]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge remote-tracking branch 'origin/cbr/export_to_geom_via_xao'
authorChristophe Bourcier <christophe.bourcier@cea.fr>
Tue, 5 Dec 2017 07:37:33 +0000 (08:37 +0100)
committerChristophe Bourcier <christophe.bourcier@cea.fr>
Tue, 5 Dec 2017 07:37:33 +0000 (08:37 +0100)
276 files changed:
src/BuildPlugin/Test/Test1920.py
src/CollectionPlugin/Test/TestGroup1799.py
src/CollectionPlugin/Test/TestGroupMove2.py
src/Config/CMakeLists.txt
src/Config/ConfigAPI.i
src/Config/Config_AttributeMessage.cpp
src/Config/Config_AttributeMessage.h
src/Config/Config_FeatureMessage.h
src/Config/Config_FeatureReader.cpp
src/Config/Config_Keywords.h
src/Config/Config_ModuleReader.cpp
src/Config/Config_PluginMessage.cpp [new file with mode: 0644]
src/Config/Config_PluginMessage.h [new file with mode: 0644]
src/Config/Config_Prop.h
src/Config/Config_XMLReader.cpp
src/Config/Config_XMLReader.h
src/Config/Config_swig.h
src/ExchangePlugin/CMakeLists.txt
src/ExchangePlugin/ExchangePlugin_Tools.cpp
src/ExchangePlugin/Test/Test2290.py [new file with mode: 0644]
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Fillet.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_Fillet.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp
src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Boolean.h
src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp
src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Fillet.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp
src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.h
src/FeaturesPlugin/FeaturesPlugin_Union.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/FeaturesPlugin_msg_en.ts
src/FeaturesPlugin/Test/Test1922.py
src/FeaturesPlugin/Test/Test1942.py
src/FeaturesPlugin/Test/Test2023.py
src/FeaturesPlugin/Test/Test2038.py
src/FeaturesPlugin/Test/Test2046.py
src/FeaturesPlugin/Test/Test2194.py
src/FeaturesPlugin/Test/Test2197_2.py
src/FeaturesPlugin/Test/Test2197_3.py
src/FeaturesPlugin/Test/Test2197_4.py
src/FeaturesPlugin/Test/Test2240.py
src/FeaturesPlugin/Test/Test2246.py
src/FeaturesPlugin/Test/Test2248.py
src/FeaturesPlugin/Test/Test2255.py
src/FeaturesPlugin/Test/Test2289.py [new file with mode: 0644]
src/FeaturesPlugin/Test/Test2304.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestBooleanFillWithPlane.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestExtrusion.py
src/FeaturesPlugin/Test/TestFillet.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestPipe.py
src/FeaturesPlugin/Test/TestRecover1798.py
src/FeaturesPlugin/Test/TestRemoveSubShapes.py
src/FeaturesPlugin/Test/TestRemoveSubShapes2.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestUnionFaces.py [new file with mode: 0644]
src/FeaturesPlugin/boolean_widget.xml
src/FeaturesPlugin/extrusioncut_widget.xml
src/FeaturesPlugin/extrusionfuse_widget.xml
src/FeaturesPlugin/fillet_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/icons/fillet.png [new file with mode: 0644]
src/FeaturesPlugin/icons/fillet_fixed_radius.png [new file with mode: 0644]
src/FeaturesPlugin/icons/fillet_var_radius.png [new file with mode: 0644]
src/FeaturesPlugin/icons/keep_subshapes_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/icons/remove_subshapes_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/FeaturesPlugin/remove_subshapes_widget.xml
src/FeaturesPlugin/revolutioncut_widget.xml
src/FeaturesPlugin/revolutionfuse_widget.xml
src/FeaturesPlugin/union_widget.xml
src/GDMLAPI/CMakeLists.txt
src/GDMLAPI/GDMLAPI.i
src/GDMLAPI/GDMLAPI_Ellipsoid.cpp [new file with mode: 0644]
src/GDMLAPI/GDMLAPI_Ellipsoid.h [new file with mode: 0644]
src/GDMLAPI/GDMLAPI_swig.h
src/GeomAPI/GeomAPI_AISObject.cpp
src/GeomAPI/GeomAPI_AISObject.h
src/GeomAPI/GeomAPI_DataMapOfShapeMapOfShapes.cpp
src/GeomAPI/GeomAPI_DataMapOfShapeMapOfShapes.h
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAPI/GeomAPI_Trsf.cpp
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Fillet.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp
src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_UnifySameDomain.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_UnifySameDomain.h [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Splitter.cxx
src/Model/Model_BodyBuilder.cpp
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultCompSolid.cpp
src/Model/Model_ResultPart.cpp
src/Model/Model_SelectionNaming.cpp
src/Model/Model_Session.cpp
src/Model/Model_Session.h
src/Model/Model_Update.cpp
src/Model/Model_Update.h
src/Model/Model_Validator.cpp
src/Model/Model_Validator.h
src/ModelAPI/CMakeLists.txt
src/ModelAPI/ModelAPI.i
src/ModelAPI/ModelAPI_Data.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Folder.cpp [new file with mode: 0644]
src/ModelAPI/ModelAPI_Folder.h [new file with mode: 0644]
src/ModelAPI/ModelAPI_Result.cpp
src/ModelAPI/ModelAPI_Result.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/ModelAPI/ModelAPI_Validator.h
src/ModelAPI/ModelAPI_swig.h
src/ModelAPI/Test/Test1064.py
src/ModelAPI/Test/Test1512.py
src/ModelAPI/Test/Test1757.py
src/ModelAPI/Test/Test2170.py
src/ModelAPI/Test/Test2228.py
src/ModelAPI/Test/Test2241.py
src/ModelAPI/Test/TestCustomName_BooleanCut.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_CommonCompSolid.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_CutCompSolid.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_CutGroup.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_DefaultName.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_ExtrudeFace.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_ExtrusionCut.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_ExtrusionCutFace.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_MultiTranslation.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_Partition.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_Placement.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_Recover.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_Rename.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_RotateGroup.py [new file with mode: 0644]
src/ModelAPI/Test/TestCustomName_Translation.py [new file with mode: 0644]
src/ModelAPI/Test/TestFolder_Create.py [new file with mode: 0644]
src/ModelAPI/Test/TestFolder_Remove.py [new file with mode: 0644]
src/ModelAPI/Test/TestFolder_Sketch.py [new file with mode: 0644]
src/ModelAPI/Test/TestFolder_Stability.py [new file with mode: 0644]
src/ModelAPI/Test/TestFolder_Update.py [new file with mode: 0644]
src/ModelHighAPI/CMakeLists.txt
src/ModelHighAPI/ModelHighAPI.i
src/ModelHighAPI/ModelHighAPI_Dumper.cpp
src/ModelHighAPI/ModelHighAPI_Dumper.h
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp
src/ModelHighAPI/ModelHighAPI_FeatureStore.h
src/ModelHighAPI/ModelHighAPI_Folder.cpp [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI_Folder.h [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI_Interface.cpp
src/ModelHighAPI/ModelHighAPI_Interface.h
src/ModelHighAPI/ModelHighAPI_Selection.cpp
src/ModelHighAPI/ModelHighAPI_Selection.h
src/ModelHighAPI/ModelHighAPI_Tools.cpp
src/ModelHighAPI/ModelHighAPI_swig.h
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_ActionType.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_IconFactory.cpp
src/ModuleBase/ModuleBase_ModelWidget.cpp
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_ToolBox.cpp
src/ModuleBase/ModuleBase_Tools.cpp
src/ModuleBase/ModuleBase_Tools.h
src/ModuleBase/ModuleBase_ViewerFilters.cpp
src/ModuleBase/ModuleBase_WidgetChoice.cpp
src/ModuleBase/ModuleBase_WidgetChoice.h
src/ModuleBase/ModuleBase_WidgetDoubleValue.h
src/ModuleBase/ModuleBase_WidgetEditor.h
src/ModuleBase/ModuleBase_WidgetExprEditor.h
src/ModuleBase/ModuleBase_WidgetFileSelector.cpp
src/ModuleBase/ModuleBase_WidgetFileSelector.h
src/ModuleBase/ModuleBase_WidgetIntValue.h
src/ModuleBase/ModuleBase_WidgetLineEdit.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.h
src/PartSet/PartSet_CenterPrs.cpp
src/PartSet/PartSet_CenterPrs.h
src/PartSet/PartSet_ExternalObjectsMgr.cpp
src/PartSet/PartSet_Filters.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_PreviewSketchPlane.cpp
src/PartSet/PartSet_PreviewSketchPlane.h
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/PartSet/PartSet_WidgetSketchCreator.cpp
src/PartSet/PartSet_WidgetSketchLabel.cpp
src/PythonAPI/examples/Platine.py
src/PythonAPI/model/dump/DumpAssistant.py
src/PythonAPI/model/features/__init__.py
src/PythonAPI/model/gdml/__init__.py
src/PythonAPI/model/services/__init__.py
src/PythonAPI/model/tests/tests.py
src/SketchAPI/SketchAPI_Constraint.cpp
src/SketchAPI/SketchAPI_Mirror.cpp
src/SketchAPI/SketchAPI_Rotation.cpp
src/SketchAPI/SketchAPI_Translation.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Projection.cpp
src/SketchPlugin/SketchPlugin_Split.cpp
src/SketchPlugin/SketchPlugin_Split.h
src/SketchPlugin/SketchPlugin_Trim.cpp
src/SketchPlugin/SketchPlugin_Trim.h
src/SketchPlugin/Test/Test2287.py [new file with mode: 0644]
src/SketchPlugin/Test/TestEdgesOrder.py [new file with mode: 0644]
src/SketchPlugin/Test/TestProjectionIntoResult.py
src/SketchPlugin/Test/TestProjectionUpdate.py [new file with mode: 0644]
src/SketcherPrs/SketcherPrs_Angle.cpp
src/SketcherPrs/SketcherPrs_Coincident.cpp
src/SketcherPrs/SketcherPrs_LengthDimension.cpp
src/SketcherPrs/SketcherPrs_PositionMgr.cpp
src/SketcherPrs/SketcherPrs_Radius.cpp
src/XAO/CMakeLists.txt
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_ContextMenuMgr.h
src/XGUI/XGUI_CustomPrs.cpp
src/XGUI/XGUI_CustomPrs.h
src/XGUI/XGUI_DataModel.cpp
src/XGUI/XGUI_DataModel.h
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h
src/XGUI/XGUI_PropertyDialog.cpp [new file with mode: 0644]
src/XGUI/XGUI_PropertyDialog.h [new file with mode: 0644]
src/XGUI/XGUI_SelectionMgr.cpp
src/XGUI/XGUI_SelectionMgr.h
src/XGUI/XGUI_TransparencyWidget.cpp [new file with mode: 0644]
src/XGUI/XGUI_TransparencyWidget.h [new file with mode: 0644]
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h
src/XGUI/XGUI_pictures.qrc
src/XGUI/pictures/create_folder.png [new file with mode: 0644]
src/XGUI/pictures/features_folder.png [new file with mode: 0644]
src/XGUI/pictures/insert_folder_after.png [new file with mode: 0644]
src/XGUI/pictures/insert_folder_before.png [new file with mode: 0644]
src/XGUI/pictures/move_out_after.png [new file with mode: 0644]
src/XGUI/pictures/move_out_before.png [new file with mode: 0644]
src/XGUI/pictures/transparency.png [new file with mode: 0644]
test.API/SHAPER/Primitives/TestBox.py
test.API/SHAPER/Transformations/TestTranslation_1.py
test.API/SHAPER/Transformations/TestTranslation_2.py
test.API/SHAPER/Transformations/TestTranslation_3.py
test.models/CSWA.py
test.models/angle30.py
test.models/bearing_puller.py
test.models/bobine_film_reel.py
test.models/bracket32.py
test.models/bushing.py
test.models/case24.py
test.models/clothespin.py
test.models/ecran.py
test.models/flange.py
test.models/gear.py
test.models/idler_plate.py
test.models/piece_02.py
test.models/piece_09.py
test.models/piece_12.py

index 96f8eb6dcbb80fe919a7336f71c594deef7630e2..18323fefdf77d5535daee768ffe96f5491d44009 100644 (file)
@@ -44,7 +44,7 @@ model.do()
 Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_3r-SketchLine_4r-SketchLine_5r")])
 Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_5f")])
 Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")], model.selection("EDGE", "PartSet/OY"), 100)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Translation_1_1/Translated_Edge_1"), model.selection("EDGE", "Translation_1_1/Translated_Edge_2"), model.selection("EDGE", "Translation_1_1/Translated_Edge_3"), model.selection("EDGE", "Translation_1_1/Translated_Edge_4"), model.selection("EDGE", "Translation_1_2/Translated_Edge_1"), model.selection("EDGE", "Translation_1_2/Translated_Edge_2"), model.selection("EDGE", "Translation_1_2/Translated_Edge_3"), model.selection("EDGE", "Translation_1_2/Translated_Edge_4")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Translated_Edge_1"), model.selection("EDGE", "Face_1_1/Translated_Edge_2"), model.selection("EDGE", "Face_1_1/Translated_Edge_3"), model.selection("EDGE", "Face_1_1/Translated_Edge_4"), model.selection("EDGE", "Face_2_1/Translated_Edge_1"), model.selection("EDGE", "Face_2_1/Translated_Edge_2"), model.selection("EDGE", "Face_2_1/Translated_Edge_3"), model.selection("EDGE", "Face_2_1/Translated_Edge_4")])
 aGroupFeature = Group_1.feature()
 aSelectionList = aGroupFeature.selectionList("group_list")
 model.end()
index 8a767c0e71af344d0b444ca9e8bb0825b40dea20..5d67a8fd40f9ce419f42c2767968094802a515f6 100644 (file)
@@ -116,11 +116,11 @@ SketchConstraintEqual_5 = Sketch_1.setEqual(SketchLine_7.result(), SketchLine_2.
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r-SketchLine_5f-SketchLine_6f-SketchLine_9r-SketchLine_10r"), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchCircle_1_2r-SketchLine_7f-SketchLine_9f-SketchLine_12r"), model.selection("FACE", "Sketch_1/Face-SketchLine_4f-SketchCircle_1_2r-SketchLine_8f-SketchLine_11r-SketchLine_12f"), model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchLine_3f-SketchCircle_1_2r-SketchLine_10f-SketchLine_11f")], model.selection(), 150, 0)
 Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/To_Face_1"), model.selection("FACE", "Extrusion_1_1/To_Face_4"), model.selection("FACE", "Extrusion_1_1/To_Face_3"), model.selection("FACE", "Extrusion_1_1/To_Face_2")])
-Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), 150, True)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_15"), 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_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)
+Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Partition_1_1_7/Modified_Face_2_4"), 110, True)
+Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "Partition_1_1_5/Modified_Face_3_4"), 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()
 
index 0f06d1dfdf8676f54d427fed562080ee26e4f388..298ba49dc35d742983889cc02721a6a54f4dcac3 100644 (file)
@@ -31,7 +31,7 @@ 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 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Box_1_1"))
 Remove_SubShapes_1.setSubShapesToKeep([model.selection("SOLID", "Partition_1_1_2")])
 model.do()
 # move group
index d1a1781ab6de12b2112495fbf6dac7cbcf7ac683..e120e21b8a9fb69a62d309835331b1408dc0f4aa 100644 (file)
@@ -29,6 +29,7 @@ INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events
 SET(PROJECT_HEADERS
   Config_def.h
   Config_FeatureMessage.h
+  Config_PluginMessage.h
   Config_XMLReader.h
   Config_ModuleReader.h
   Config_FeatureReader.h
@@ -48,6 +49,7 @@ SET(PROJECT_HEADERS
 
 SET(PROJECT_SOURCES
   Config_FeatureMessage.cpp
+  Config_PluginMessage.cpp
   Config_XMLReader.cpp
   Config_ModuleReader.cpp
   Config_FeatureReader.cpp
index deb262c363616f6a5fead39904eef1a410207b89..2bf42f1a044bdbab5330e527da8cfb1d5dde10c8 100644 (file)
@@ -32,3 +32,5 @@
 %include "std_string.i"
 
 %include "Config_ModuleReader.h"
+%include "Config_PropManager.h"
+%include "Config_Prop.h"
index b8d4de423075c7755ddcee4fad8806969afb7e87..32051337cd23c0e703978d8cd3146387bb639565 100644 (file)
@@ -84,3 +84,13 @@ void Config_AttributeMessage::setCases(const std::list<std::pair<std::string,
 {
   myCases = theCases;
 }
+
+bool Config_AttributeMessage::isMainArgument() const
+{
+  return myIsMainArgument;
+}
+
+void Config_AttributeMessage::setMainArgument(bool isMainArg)
+{
+  myIsMainArgument = isMainArg;
+}
index ad5279ed92b52c34b82977df6630a5bc09359c42..cb4ef232c79b2740c8768b8a49ccf716e3a57484 100644 (file)
@@ -41,6 +41,7 @@ class Config_AttributeMessage : public Events_Message
   std::string myFeatureId; ///< Attribute's feature's unique id
   bool myIsObligatory; ///< Required to be set by user, else it's feature is invalid.
   bool myIsConcealment; ///< If true, conceals features used as input
+  bool myIsMainArgument; ///< Mark attribute as a main argument of the feature
   ///< a list of pairs, if the attribute is placed inside paged containers: (case, switch)
   std::list<std::pair<std::string, std::string> > myCases;
 
@@ -66,6 +67,8 @@ public:
   CONFIG_EXPORT bool isObligatory() const;
   /// Returns true if attribute should conceal input features
   CONFIG_EXPORT bool isConcealment() const;
+  /// Returns true if attribute is a main argument of the feature
+  CONFIG_EXPORT bool isMainArgument() const;
   /// Returns container of ids of pair of a case and switches
   CONFIG_EXPORT const std::list<std::pair<std::string, std::string> >& getCases() const;
   /// Sets ids of pair of a case and switches
@@ -79,6 +82,8 @@ public:
   CONFIG_EXPORT void setConcealment(bool isConcealment);
   /// Set attribute's obligatory state
   CONFIG_EXPORT void setObligatory(bool isObligatory);
+  /// Set a state that the attribute is a main argument of the feature
+  CONFIG_EXPORT void setMainArgument(bool isMainArg);
 };
 
 #endif // ATTRIBUTE_MESSAGE_H
index 86d30868414a40e9f875bfb97d44d3cccff5d018..a4c6105511b5301f98fc00626e1c5c3fb1a3cfe7 100644 (file)
@@ -18,8 +18,8 @@
 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
 //
 
-#ifndef CONFIG_MESSAGE_H
-#define CONFIG_MESSAGE_H
+#ifndef CONFIG_FEATUREMESSAGE_H
+#define CONFIG_FEATUREMESSAGE_H
 
 #include <Config_def.h>
 #include <Events_Message.h>
index 71261ba95849971d0085bd12d102cdb38b42d0db..6115d715f7f76d90593e8bc51bebbc8492b78e3d 100644 (file)
@@ -84,7 +84,10 @@ void Config_FeatureReader::processNode(xmlNodePtr theNode)
       if (!anAttributeID.empty()) {
         aMessage->setAttributeId(anAttributeID);
         aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true));
-        aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false));
+        bool isConcealment = getBooleanAttribute(theNode, ATTR_CONCEALMENT, false);
+        aMessage->setConcealment(isConcealment);
+        bool isMainArg = isConcealment && getBooleanAttribute(theNode, ATTR_MAIN_ARG, false);
+        aMessage->setMainArgument(isMainArg);
 
         std::list<std::pair<std::string, std::string> > aCases;
         xmlNodePtr aCaseNode =
index 81a8d8dea00fbb40980983a7a9919cead4c0234f..da19a07e643d1a85b87774a1ef0ed5316bbbb175 100644 (file)
@@ -92,6 +92,7 @@ const static char* ATTR_CONCEALMENT = "concealment";
 const static char* ATTR_USE_RESET = "use_reset";
 const static char* ATTR_GREED = "greed";
 const static char* ATTR_MODIFIED_IN_EDIT = "modified_in_edit";
+const static char* ATTR_MAIN_ARG = "main_argument";
 
 // WDG_INFO properties
 const static char* INFO_WDG_TEXT = FEATURE_TEXT;
@@ -123,6 +124,7 @@ const static char* PLUGIN_CONFIG = "configuration";
 const static char* PLUGIN_LIBRARY = "library";
 const static char* PLUGIN_SCRIPT = "script";
 const static char* PLUGIN_DEPENDENCY = "dependency";
+const static char* PLUGIN_USES = "uses";
 
 /*
  * Hardcoded xml entities of dataModel.xml
index 168983a5eb2d7a28c7c1f0bb2848f69a41c6c6d9..452fc4ca3a9291602ec9c71f7b4488de442c1332 100644 (file)
@@ -24,6 +24,7 @@
 #include <Config_Common.h>
 #include <Config_ModuleReader.h>
 #include <Config_FeatureReader.h>
+#include <Config_PluginMessage.h>
 #include <Events_InfoMessage.h>
 
 #include <libxml/parser.h>
@@ -102,6 +103,13 @@ void Config_ModuleReader::processNode(xmlNodePtr theNode)
     std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY);
     std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT);
     std::string aPluginName = addPlugin(aPluginLibrary, aPluginScript, aPluginConf);
+    std::string aUsesPlugin = getProperty(theNode, PLUGIN_USES);
+    if (!aUsesPlugin.empty()) { // send information about the plugin dependencies
+      std::shared_ptr<Config_PluginMessage> aMess(new Config_PluginMessage(
+        Events_Loop::loop()->eventByName(Config_PluginMessage::EVENT_ID()), aPluginName));
+      aMess->setUses(aUsesPlugin);
+      Events_Loop::loop()->send(aMess);
+    }
 
     std::list<std::string> aFeatures = importPlugin(aPluginName, aPluginConf);
     std::list<std::string>::iterator it = aFeatures.begin();
@@ -167,6 +175,12 @@ std::string Config_ModuleReader::addPlugin(const std::string& aPluginLibrary,
 
 void Config_ModuleReader::loadPlugin(const std::string& thePluginName)
 {
+  // informs model that plugin loading is started
+  static const Events_ID kEVENT_ID =
+    Events_Loop::loop()->eventByName(Config_PluginMessage::EVENT_ID());
+  std::shared_ptr<Config_PluginMessage> aMess(new Config_PluginMessage(kEVENT_ID, thePluginName));
+  Events_Loop::loop()->send(aMess);
+
   PluginType aType = Config_ModuleReader::Binary;
   if(myPluginTypes.find(thePluginName) != myPluginTypes.end()) {
     aType = myPluginTypes.at(thePluginName);
diff --git a/src/Config/Config_PluginMessage.cpp b/src/Config/Config_PluginMessage.cpp
new file mode 100644 (file)
index 0000000..eaee691
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "Config_PluginMessage.h"
+
+Config_PluginMessage::Config_PluginMessage(const Events_ID theId,
+  const std::string& thePluginId, const void* theParent)
+    : Events_Message(theId, theParent)
+{
+  myPluginId = thePluginId;
+}
+
+Config_PluginMessage::~Config_PluginMessage()
+{
+
+}
+
+const std::string& Config_PluginMessage::pluginId() const
+{
+  return myPluginId;
+}
+
+const std::string& Config_PluginMessage::uses() const
+{
+  return myUses;
+}
+
+void Config_PluginMessage::setUses(const std::string& theUses)
+{
+  myUses = theUses;
+}
diff --git a/src/Config/Config_PluginMessage.h b/src/Config/Config_PluginMessage.h
new file mode 100644 (file)
index 0000000..8778c3d
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef CONFIG_PLUGINMESSAGE_H
+#define CONFIG_PLUGINMESSAGE_H
+
+#include <Config_def.h>
+#include <Events_Message.h>
+
+#include <string>
+
+/*!
+ * \class Config_PluginMessage
+ * \ingroup Config
+ * \brief Information that plugin is started to load.
+ *
+ * Contains the plugin name. Event is posted just before load of the plugin
+ * before registerPlugin call.
+ */
+class Config_PluginMessage : public Events_Message
+{
+  std::string myPluginId;  ///< Plugin unique id
+  std::string myUses;  ///< Which plugins are used by this one Id
+
+ public:
+  /// Event ID that plugin will be loaded
+  inline static const char* EVENT_ID()
+  {
+    static const char * MY_EVENT_ID("BeforePluginLoad");
+    return MY_EVENT_ID;
+  }
+
+  /// Constructs Config_PluginMessage
+  CONFIG_EXPORT Config_PluginMessage(const Events_ID theId,
+    const std::string& thePluginId, const void* theParent = 0);
+  /// Deletes Config_PluginMessage
+  CONFIG_EXPORT virtual ~Config_PluginMessage();
+
+  /// Plugin Id
+  CONFIG_EXPORT const std::string& pluginId() const;
+  /// Which plugins are used by this one Id
+  CONFIG_EXPORT const std::string& uses() const;
+  /// Sets which plugins are used by this one Id
+  CONFIG_EXPORT void setUses(const std::string& theUses);
+};
+
+#endif // CONFIG_MESSAGE_H
index d6ce44e41dbbcd6e7980c10b81c73080780b5ef0..bdaecb59b7bc84d856cd149407fa9c402f4fe6bd 100644 (file)
@@ -26,7 +26,7 @@
 #include <string>
 #include <list>
 
-const static char* SKETCH_TAB_NAME = "Sketch";
+static const char* SKETCH_TAB_NAME = "Sketch";
 
 /*!
  * \class Config_Prop
index 6b29a5851b9d3c50d3bc1f249e461be338806b72..f7af50c8f21e7a9ead3ecf0652948525c84bbe84 100644 (file)
@@ -30,6 +30,7 @@
 #include <libxml/tree.h>
 
 #include <fstream>
+#include <sstream>
 
 #ifdef WIN32
 #pragma warning(disable : 4996) // for getenv
 #endif
 
 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
-    : myXmlDoc(NULL)
+    : myXmlDoc(NULL), myRootFileName(theXmlFileName)
 {
-  std::string prefix = "";
-  Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path");
-  if (aProp)
-    prefix = aProp->value();
-  /*
-   * Get path to *.xml files (typically ./bin/../plugins/)
-
-   * the problem: application may be launched using python executable,
-   * to use environment variable (at least for the current moment)
-   */
-  if (prefix.empty())
-    prefix = pluginConfigFile();
-
-  myDocumentPath = prefix + FSEP + theXmlFileName;
-  std::ifstream aTestFile(myDocumentPath);
-  if (!aTestFile)
-    Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(myDocumentPath).send();
-  aTestFile.close();
+  myDocumentPath = findConfigFile(theXmlFileName);
+  if (myDocumentPath.empty()) {
+    Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(theXmlFileName).send();
+  }
 }
 
 Config_XMLReader::~Config_XMLReader()
@@ -73,6 +60,22 @@ Config_XMLReader::~Config_XMLReader()
   xmlFreeDoc(myXmlDoc);
 }
 
+std::string Config_XMLReader::resourcesConfigFile()
+{
+  std::string aValue;
+  char* anEnv = getenv("SHAPER_ROOT_DIR");
+  if (anEnv) {
+    aValue = std::string(anEnv) +
+      FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
+  } else {
+    anEnv = getenv("OPENPARTS_ROOT_DIR");
+    if (anEnv) {
+      aValue = std::string(anEnv) + FSEP + "resources";
+    }
+  }
+  return aValue;
+}
+
 std::string Config_XMLReader::pluginConfigFile()
 {
   std::string aValue;
@@ -89,13 +92,84 @@ std::string Config_XMLReader::pluginConfigFile()
   return aValue;
 }
 
+std::string Config_XMLReader::findConfigFile(const std::string theFileName, const int theFindIndex)
+{
+  int aResultIndex = 0;
+  for(int aSolution = 0; aSolution < 12; aSolution++) {
+    std::string aFileName;
+    if (aSolution == 0) {
+      Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path");
+      if (!aProp)
+        continue;
+      aFileName = aProp->value();
+    } else {
+      std::ostringstream anEnvName;
+      if (aSolution == 1)
+        anEnvName<<"SHAPER_ROOT_DIR";
+      else if (aSolution == 2)
+        anEnvName<<"OPENPARTS_ROOT_DIR";
+      else
+        anEnvName<<"OPENPARTS_PLUGINS_DIR";
+
+      char* anEnv = getenv(anEnvName.str().c_str());
+      if (!anEnv)
+        continue;
+      if (aSolution > 2) { // there may be several paths separated by ";" symbol
+        std::string anEnvPart = anEnv;
+        size_t aPosStart = 0, aPosEnd;
+        for(int aSubNum = 0; aSubNum < aSolution - 3; aSubNum++) {
+          aPosStart++;
+          aPosStart = anEnvPart.find(';', aPosStart);
+          if (aPosStart == std::string::npos)
+            break;
+        }
+        if (aPosStart == std::string::npos)
+          break;
+        if (aPosStart != 0)
+          aPosStart++;
+        aPosEnd = anEnvPart.find(';', aPosStart);
+        aFileName = anEnvPart.substr(aPosStart,
+          aPosEnd == std::string::npos ? aPosEnd : aPosEnd - aPosStart) + FSEP;
+      } else {
+        aFileName = std::string(anEnv) + FSEP;
+      }
+      if (aSolution == 1)
+        aFileName += std::string("share") + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
+      else if (aSolution == 2)
+        aFileName += "plugins";
+    }
+
+    aFileName += FSEP + theFileName;
+    std::ifstream aTestFile(aFileName);
+    if (aTestFile) {
+      if (aResultIndex == theFindIndex)
+        return aFileName;
+      aResultIndex++;
+      if (aSolution == 1) // don't allow SHAPER and OpenParts paths treated simultaneously
+        aSolution++;
+    }
+  }
+  return ""; // no files found
+}
+
 void Config_XMLReader::readAll()
 {
-  // to load external modules dependencies (like GEOm for Connector Feature
+  // to load external modules dependencies (like GEOM for Connector Feature)
   Config_ModuleReader::loadScript("salome.shaper.initConfig", false);
 
-  xmlNodePtr aRoot = findRoot();
-  readRecursively(aRoot);
+  for(int aSolution = 0; true; aSolution++) {
+    std::string aFoundFile = findConfigFile(myRootFileName, aSolution);
+    if (aFoundFile.empty()) {
+      break; // no more solutions
+    }
+
+    if (myXmlDoc != NULL) { // clear the previous XML document - now the new one will be opened
+      xmlFreeDoc(myXmlDoc);
+      myXmlDoc = NULL;
+    }
+    xmlNodePtr aRoot = findRoot(aFoundFile);
+    readRecursively(aRoot);
+  }
 }
 
 void Config_XMLReader::processNode(xmlNodePtr theNode)
@@ -120,14 +194,15 @@ bool Config_XMLReader::processChildren(xmlNodePtr aNode)
   return true;
 }
 
-xmlNodePtr Config_XMLReader::findRoot()
+xmlNodePtr Config_XMLReader::findRoot(const std::string theDocumentPath)
 {
+  std::string aDocPath = theDocumentPath.empty() ? myDocumentPath : theDocumentPath;
   if (myXmlDoc == NULL) {
-    myXmlDoc = xmlParseFile(myDocumentPath.c_str());
+    myXmlDoc = xmlParseFile(aDocPath.c_str());
   }
   if (myXmlDoc == NULL) {
 #ifdef _DEBUG
-    std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
+    std::cout << "Config_XMLReader::import: " << "Document " << aDocPath
     << " is not parsed successfully." << std::endl;
 #endif
     return NULL;
index 53b07024f1b9dac0ed5864c83061276863665a29..ab067cd4bce224b276b14408f716e805dc38041d 100644 (file)
@@ -54,6 +54,11 @@ class Config_XMLReader
    */
   CONFIG_EXPORT Config_XMLReader(const std::string& theXmlFile);
   CONFIG_EXPORT virtual ~Config_XMLReader();
+  /*!
+   * Returns a path to resource files (created from ROOT_DIR environment variable)
+   * \return string value
+   */
+  CONFIG_EXPORT static std::string resourcesConfigFile();
   /*!
    * Returns a path to the plugins.xml file (created from ROOT_DIR environment variable)
    * \return string value
@@ -66,13 +71,18 @@ class Config_XMLReader
    */
   CONFIG_EXPORT void readAll();
   /*!
-   * Returns xmlNodePtr to the root of reader's document
-   * or NULL if not found
+   * Returns xmlNodePtr to the root of reader's document or NULL if not found.
+   * If the path to the document to read is empty, uses myDocumentPath.
    */
-  CONFIG_EXPORT xmlNodePtr findRoot();
+  CONFIG_EXPORT xmlNodePtr findRoot(const std::string theDocumentPath = "");
 
   CONFIG_EXPORT const char* encoding() const;
 
+  /// Checks all possible paths to configuration file given
+  /// Uses theFindIndex if several solutions can be found (this is the number of solution to find)
+  CONFIG_EXPORT static std::string
+    findConfigFile(const std::string theFileName, const int theFindIndex = 0);
+
  protected:
   /*!
    * \brief Allows to customize reader's behavior for a node. Virtual.
@@ -117,6 +127,7 @@ class Config_XMLReader
  protected:
   std::string myDocumentPath; ///< Path to the xml document
   xmlDocPtr myXmlDoc; ///< Root of the xml document
+  std::string myRootFileName; ///< name of the root file
   /// A map to store all parent's attributes.
   /// The key has from "Node_Name:Node_Attribute"
   std::map<std::string, std::string> myCachedAttributes;
index c6cf51d51eed73b6472fbc51dc0fde41edb2ff04..cda0700d8d2d2c2d3e455e4312b1de6fdc737fa1 100644 (file)
@@ -22,5 +22,7 @@
 #define SRC_CONFIG_SWIG_H_
 
   #include "Config_ModuleReader.h"
+  #include "Config_Prop.h"
+  #include "Config_PropManager.h"
 
 #endif /* SRC_CONFIG_SWIG_H_ */
index 3c56a9476d31f0992209f0a0fe9f27b35e4129e9..6d95ce732e0c8ef6c937f3842b08e8f2515fa744 100644 (file)
@@ -79,7 +79,9 @@ INSTALL(FILES ${XML_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
 INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Exchange)
 INSTALL(FILES ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
 
-ADD_UNIT_TESTS(TestImport.py TestExport.py)
+ADD_UNIT_TESTS(TestImport.py
+               TestExport.py
+               Test2290.py)
 
 SET(DATA_FILES
   solid.brep
index f10f316dc51db804a0d1ec6748ad475e0599c0b4..1d2000236e6a885bdd2f9ddb0122c9651b0538e0 100644 (file)
@@ -34,8 +34,6 @@ std::list<std::string> ExchangePlugin_Tools::split(const std::string& theString,
 
 std::string ExchangePlugin_Tools::selectionType2xaoDimension(const std::string& theType)
 {
-  // if the selection is done in the GUI, the type is lower case
-  // if the selection is done in python, the type is in upper case
   if (theType == "Vertices" || theType == "vertex" || theType == "VERTEX")
     return "vertex";
   else if (theType == "Edges" || theType == "edge" || theType == "EDGE")
diff --git a/src/ExchangePlugin/Test/Test2290.py b/src/ExchangePlugin/Test/Test2290.py
new file mode 100644 (file)
index 0000000..5671cea
--- /dev/null
@@ -0,0 +1,39 @@
+## 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()
+Box_1 = model.addBox(Part_1_doc, 5, 10, 10)
+Box_2 = model.addBox(Part_1_doc, 10, 50, 8)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Box_1_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Partition_1_1_3/Modified_Face_2_3"), model.selection("FACE", "Partition_1_1_1/Modified_Face_2_3")])
+model.do()
+# test export to XAO
+anExportFeature = Part_1_doc.addFeature("Export")
+anExportFeature.string("xao_file_path").setValue("Data/export2290.xao")
+anExportFeature.string("file_format").setValue("XAO")
+anExportFeature.string("ExportType").setValue("XAO")
+anExportFeature.string("xao_author").setValue("me")
+anExportFeature.string("xao_geometry_name").setValue("mygeom")
+model.end()
index 791859eedd8d904a1846a1f271742ca1c1e91647..1c549224202d4f881ecb6d847c8bad37a59ac8b4 100644 (file)
@@ -25,6 +25,7 @@ SET(PROJECT_HEADERS
   FeaturesAPI_Boolean.h
   FeaturesAPI_Extrusion.h
   FeaturesAPI_ExtrusionBoolean.h
+  FeaturesAPI_Fillet.h
   FeaturesAPI_Intersection.h
   FeaturesAPI_MultiRotation.h
   FeaturesAPI_MultiTranslation.h
@@ -46,6 +47,7 @@ SET(PROJECT_SOURCES
   FeaturesAPI_Boolean.cpp
   FeaturesAPI_Extrusion.cpp
   FeaturesAPI_ExtrusionBoolean.cpp
+  FeaturesAPI_Fillet.cpp
   FeaturesAPI_Intersection.cpp
   FeaturesAPI_MultiRotation.cpp
   FeaturesAPI_MultiTranslation.cpp
index e77373949f43a83a4012c468cb321f6b38173e7e..62afc3e4889829499a60f6e0870b7319d3ffee73 100644 (file)
@@ -44,6 +44,7 @@
 %shared_ptr(FeaturesAPI_ExtrusionBoolean)
 %shared_ptr(FeaturesAPI_ExtrusionCut)
 %shared_ptr(FeaturesAPI_ExtrusionFuse)
+%shared_ptr(FeaturesAPI_Fillet)
 %shared_ptr(FeaturesAPI_Intersection)
 %shared_ptr(FeaturesAPI_MultiRotation)
 %shared_ptr(FeaturesAPI_MultiTranslation)
@@ -66,6 +67,7 @@
 %include "FeaturesAPI_Boolean.h"
 %include "FeaturesAPI_Extrusion.h"
 %include "FeaturesAPI_ExtrusionBoolean.h"
+%include "FeaturesAPI_Fillet.h"
 %include "FeaturesAPI_Intersection.h"
 %include "FeaturesAPI_MultiRotation.h"
 %include "FeaturesAPI_MultiTranslation.h"
diff --git a/src/FeaturesAPI/FeaturesAPI_Fillet.cpp b/src/FeaturesAPI/FeaturesAPI_Fillet.cpp
new file mode 100644 (file)
index 0000000..17878f0
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright (C) 2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "FeaturesAPI_Fillet.h"
+
+#include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+////#include <ModelHighAPI_Reference.h>
+#include <ModelHighAPI_Tools.h>
+
+FeaturesAPI_Fillet::FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+  : ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+FeaturesAPI_Fillet::FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                       const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                       const ModelHighAPI_Double& theRadius)
+  : ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS(), mycreationMethod);
+    fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(theRadius, myradius);
+  }
+}
+
+FeaturesAPI_Fillet::FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                       const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                       const ModelHighAPI_Double& theRadius1,
+                                       const ModelHighAPI_Double& theRadius2)
+  : ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS(), mycreationMethod);
+    fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(theRadius1, mystartRadius);
+    fillAttribute(theRadius2, myendRadius);
+  }
+}
+
+FeaturesAPI_Fillet::~FeaturesAPI_Fillet()
+{
+}
+
+//==================================================================================================
+void FeaturesAPI_Fillet::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+  mybaseObjects->clear();
+  fillAttribute(theBaseObjects, mybaseObjects);
+
+  execIfBaseNotEmpty();
+}
+
+void FeaturesAPI_Fillet::setRadius(const ModelHighAPI_Double& theRadius)
+{
+  fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS(), mycreationMethod);
+  fillAttribute(theRadius, myradius);
+
+  execIfBaseNotEmpty();
+}
+
+void FeaturesAPI_Fillet::setRadius(const ModelHighAPI_Double& theRadius1,
+                                   const ModelHighAPI_Double& theRadius2)
+{
+  fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS(), mycreationMethod);
+  fillAttribute(theRadius1, mystartRadius);
+  fillAttribute(theRadius2, myendRadius);
+
+  execIfBaseNotEmpty();
+}
+
+void FeaturesAPI_Fillet::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects =
+    aBase->selectionList(FeaturesPlugin_Fillet::OBJECT_LIST_ID());
+
+  theDumper << aBase << " = model.addFillet(" << aDocName << ", " << anAttrObjects;
+
+  std::string aCreationMethod = aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value();
+
+  if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS()) {
+    AttributeDoublePtr anAttrRadius = aBase->real(FeaturesPlugin_Fillet::RADIUS_ID());
+    theDumper << ", " << anAttrRadius;
+  } else if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS()) {
+    AttributeDoublePtr anAttrRadius1 = aBase->real(FeaturesPlugin_Fillet::START_RADIUS_ID());
+    AttributeDoublePtr anAttrRadius2 = aBase->real(FeaturesPlugin_Fillet::END_RADIUS_ID());
+    theDumper << ", " << anAttrRadius1 << ", " << anAttrRadius2;
+  }
+
+  theDumper << ")" << std::endl;
+}
+
+void FeaturesAPI_Fillet::execIfBaseNotEmpty()
+{
+  if (mybaseObjects->size() > 0)
+    execute();
+}
+
+
+//==================================================================================================
+
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                    const ModelHighAPI_Double& theRadius)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Fillet::ID());
+  return FilletPtr(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius));
+}
+
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                    const ModelHighAPI_Double& theRadius1,
+                    const ModelHighAPI_Double& theRadius2)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Fillet::ID());
+  return FilletPtr(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius1, theRadius2));
+}
diff --git a/src/FeaturesAPI/FeaturesAPI_Fillet.h b/src/FeaturesAPI/FeaturesAPI_Fillet.h
new file mode 100644 (file)
index 0000000..e622408
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright (C) 2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef FeaturesAPI_Fillet_H_
+#define FeaturesAPI_Fillet_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_Fillet.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Double;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_Fillet
+/// \ingroup CPPHighAPI
+/// \brief Interface for Fillet feature.
+class FeaturesAPI_Fillet: public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                              const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                              const ModelHighAPI_Double& theRadius);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                              const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                              const ModelHighAPI_Double& theRadius1,
+                              const ModelHighAPI_Double& theRadius2);
+
+  /// Destructor.
+  FEATURESAPI_EXPORT
+  virtual ~FeaturesAPI_Fillet();
+
+  INTERFACE_5(FeaturesPlugin_Fillet::ID(),
+              creationMethod, FeaturesPlugin_Fillet::CREATION_METHOD(),
+                              ModelAPI_AttributeString,
+                              /** Creation method */,
+              baseObjects, FeaturesPlugin_Fillet::OBJECT_LIST_ID(),
+                           ModelAPI_AttributeSelectionList,
+                           /** Base objects */,
+              radius, FeaturesPlugin_Fillet::RADIUS_ID(),
+                      ModelAPI_AttributeDouble,
+                      /** Value of the fixed radius fillet */,
+              startRadius, FeaturesPlugin_Fillet::START_RADIUS_ID(),
+                           ModelAPI_AttributeDouble,
+                           /** Start radius of the varying radius fillet */,
+              endRadius, FeaturesPlugin_Fillet::END_RADIUS_ID(),
+                         ModelAPI_AttributeDouble,
+                         /** End radius of the varying radius fillet */)
+
+  /// Modify base objects of the fillet.
+  FEATURESAPI_EXPORT
+  void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Modify fillet to have fixed radius
+  FEATURESAPI_EXPORT
+  void setRadius(const ModelHighAPI_Double& theRadius);
+
+  /// Modify fillet to have varying radius
+  FEATURESAPI_EXPORT
+  void setRadius(const ModelHighAPI_Double& theRadius1, const ModelHighAPI_Double& theRadius2);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+  void execIfBaseNotEmpty();
+};
+
+/// Pointer on Fillet object.
+typedef std::shared_ptr<FeaturesAPI_Fillet> FilletPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Fillet feature.
+FEATURESAPI_EXPORT
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                    const ModelHighAPI_Double& theRadius);
+
+/// \ingroup CPPHighAPI
+/// \brief Create Fillet feature.
+FEATURESAPI_EXPORT
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                    const ModelHighAPI_Double& theRadius1,
+                    const ModelHighAPI_Double& theRadius2);
+
+#endif // FeaturesAPI_Fillet_H_
index 24447bc00ecb24490d2467f47f47c9eec66e0e84..4d5b40ba324680961b78db3b49932c8ad78c2b51 100644 (file)
@@ -62,7 +62,20 @@ void FeaturesAPI_RemoveSubShapes::setBase(const ModelHighAPI_Selection& theBase)
 void FeaturesAPI_RemoveSubShapes::setSubShapesToKeep(
   const std::list<ModelHighAPI_Selection>& theSubShapes)
 {
-  fillAttribute(theSubShapes, mysubshapes);
+  fillAttribute(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES(),
+                mycreationMethod);
+  fillAttribute(theSubShapes, mysubshapesToKeep);
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_RemoveSubShapes::setSubShapesToRemove(
+  const std::list<ModelHighAPI_Selection>& theSubShapes)
+{
+  fillAttribute(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_REMOVE_SUBSHAPES(),
+                mycreationMethod);
+  fillAttribute(theSubShapes, mysubshapesToRemove);
 
   execute();
 }
@@ -75,12 +88,27 @@ void FeaturesAPI_RemoveSubShapes::dump(ModelHighAPI_Dumper& theDumper) const
 
   AttributeSelectionPtr anAttrBaseShape =
     aBase->selection(FeaturesPlugin_RemoveSubShapes::BASE_SHAPE_ID());
-  AttributeSelectionListPtr anAttrSubShapes =
-    aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_ID());
 
-  theDumper << aBase << " = model.addRemoveSubShapes(" << aDocName <<
-    ", " << anAttrBaseShape << ")" << std::endl;
-  theDumper << aBase << ".setSubShapesToKeep(" << anAttrSubShapes << ")" << std::endl;
+  std::string aCreationMethod =
+    aBase->string(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD())->value();
+
+  AttributeSelectionListPtr anAttrSubShapes;
+
+  if (aCreationMethod == FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES()) {
+    anAttrSubShapes =
+      aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_KEEP_ID());
+  }
+  else {
+    anAttrSubShapes =
+      aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_REMOVE_ID());
+  }
+
+  theDumper << aBase << " = model.addRemoveSubShapes(" << aDocName << ", " << anAttrBaseShape << ")"
+            << std::endl;
+  theDumper << aBase
+    << (aCreationMethod == FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES() ?
+       ".setSubShapesToKeep(" : ".setSubShapesToRemove(")
+    << anAttrSubShapes << ")" << std::endl;
 }
 
 //==================================================================================================
index cabae5368de9a50b60411a8a2f9dbeab7d324ce9..15a1d04955edbe434da7db64f179da41b877de64 100644 (file)
@@ -50,11 +50,15 @@ public:
   FEATURESAPI_EXPORT
   virtual ~FeaturesAPI_RemoveSubShapes();
 
-  INTERFACE_2(FeaturesPlugin_RemoveSubShapes::ID(),
+  INTERFACE_4(FeaturesPlugin_RemoveSubShapes::ID(),
               base, FeaturesPlugin_RemoveSubShapes::BASE_SHAPE_ID(),
               ModelAPI_AttributeSelection, /** Base */,
-              subshapes, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_ID(),
-              ModelAPI_AttributeSelectionList, /** Subshapes */)
+              creationMethod, FeaturesPlugin_RemoveSubShapes::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
+              subshapesToKeep, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_KEEP_ID(),
+              ModelAPI_AttributeSelectionList, /** Subshapes to keep*/,
+              subshapesToRemove, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_REMOVE_ID(),
+              ModelAPI_AttributeSelectionList, /** Subshapes to remove*/)
 
   /// Modify objects attribute of the feature.
   FEATURESAPI_EXPORT
@@ -64,6 +68,10 @@ public:
   FEATURESAPI_EXPORT
   void setSubShapesToKeep(const std::list<ModelHighAPI_Selection>& theSubShapes);
 
+  /// Modify tools attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setSubShapesToRemove(const std::list<ModelHighAPI_Selection>& theSubShapes);
+
   /// Dump wrapped feature
   FEATURESAPI_EXPORT
   virtual void dump(ModelHighAPI_Dumper& theDumper) const;
index 9a6637c03bffd8aa6229af5ea5d4c5fd5523fccf..8b6ce0005d468d1366028a17764a6ba9a7fea3cd 100644 (file)
@@ -27,6 +27,7 @@
   #include "FeaturesAPI_Boolean.h"
   #include "FeaturesAPI_Extrusion.h"
   #include "FeaturesAPI_ExtrusionBoolean.h"
+  #include "FeaturesAPI_Fillet.h"
   #include "FeaturesAPI_Intersection.h"
   #include "FeaturesAPI_MultiRotation.h"
   #include "FeaturesAPI_MultiTranslation.h"
index 53b6ad50eb1e8e3c229e3e54efc54835d4695d69..3b9197381959b52fa0603906b16fe5bea4311c5a 100644 (file)
@@ -51,6 +51,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_Scale.h
     FeaturesPlugin_MultiTranslation.h
     FeaturesPlugin_MultiRotation.h
+    FeaturesPlugin_Fillet.h
 )
 
 SET(PROJECT_SOURCES
@@ -82,6 +83,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Scale.cpp
     FeaturesPlugin_MultiTranslation.cpp
     FeaturesPlugin_MultiRotation.cpp
+    FeaturesPlugin_Fillet.cpp
 )
 
 SET(XML_RESOURCES
@@ -106,6 +108,7 @@ SET(XML_RESOURCES
   scale_widget.xml
   multitranslation_widget.xml
   multirotation_widget.xml
+  fillet_widget.xml
 )
 
 SET(TEXT_RESOURCES
@@ -156,11 +159,14 @@ ADD_UNIT_TESTS(TestExtrusion.py
                TestBooleanCompSolids.py
                TestBooleanSmash.py
                TestBooleanFill.py
+               TestBooleanFillWithPlane.py
                TestMultiBoolean.py
                TestSerialBoolean.py
                TestIntersection.py
                TestUnion.py
+               TestUnionFaces.py
                TestRemoveSubShapes.py
+               TestRemoveSubShapes2.py
                TestPipe.py
                TestRecover.py
                TestRecover1798.py
@@ -185,4 +191,6 @@ ADD_UNIT_TESTS(TestExtrusion.py
                Test2248.py
                Test2251.py
                Test2255.py
+               Test2289.py
+               Test2304.py
 )
index b51d76b60079f828e22d108873850259b1bce324..d10b03f1c365ed906aefd7150e61682d5bea1328 100644 (file)
 #include <ModelAPI_Tools.h>
 
 #include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_MakeShapeCustom.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_Partition.h>
 #include <GeomAlgoAPI_PaveFiller.h>
 #include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_Face.h>
 #include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_ShapeIterator.h>
 
@@ -87,7 +89,7 @@ void FeaturesPlugin_Boolean::execute()
     return;
   OperationType aType = (FeaturesPlugin_Boolean::OperationType)aTypeAttr->value();
 
-  ListOfShape anObjects, aTools, anEdgesAndFaces;
+  ListOfShape anObjects, aTools, anEdgesAndFaces, aPlanes;
   std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
 
   // Getting objects.
@@ -116,10 +118,14 @@ void FeaturesPlugin_Boolean::execute()
         aCompSolidsObjects[aContextShape].push_back(anObject);
       }
     } else {
-      if(anObject->shapeType() == GeomAPI_Shape::EDGE ||
-         anObject->shapeType() == GeomAPI_Shape::FACE) {
+      if(aType != BOOL_FILL
+        && (anObject->shapeType() == GeomAPI_Shape::EDGE
+          || anObject->shapeType() == GeomAPI_Shape::FACE))
+      {
         anEdgesAndFaces.push_back(anObject);
-      } else {
+      }
+      else
+      {
         anObjects.push_back(anObject);
       }
     }
@@ -129,12 +135,16 @@ void FeaturesPlugin_Boolean::execute()
   AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
   for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
     AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
-    std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
+    GeomShapePtr aTool = aToolAttr->value();
     if(!aTool.get()) {
-      return;
+      // It could be a construction plane.
+      ResultPtr aContext = aToolAttr->context();
+      aPlanes.push_back(aToolAttr->context()->shape());
     }
-    if(aTool->shapeType() == GeomAPI_Shape::EDGE ||
-       aTool->shapeType() == GeomAPI_Shape::FACE) {
+    else if(aType != BOOL_FILL
+      && (aTool->shapeType() == GeomAPI_Shape::EDGE
+        || aTool->shapeType() == GeomAPI_Shape::FACE))
+    {
       anEdgesAndFaces.push_back(aTool);
     } else {
       aTools.push_back(aTool);
@@ -147,7 +157,8 @@ void FeaturesPlugin_Boolean::execute()
     case BOOL_CUT:
     case BOOL_COMMON:
     case BOOL_FILL: {
-      if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
+      if((anObjects.empty() && aCompSolidsObjects.empty())
+          || (aTools.empty() && aPlanes.empty())) {
         std::string aFeatureError = "Error: Not enough objects for boolean operation.";
         setError(aFeatureError);
         return;
@@ -159,25 +170,46 @@ void FeaturesPlugin_Boolean::execute()
         std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
         ListOfShape aListWithObject;
         aListWithObject.push_back(anObject);
-        GeomAlgoAPI_MakeShape aBoolAlgo;
+        GeomAlgoAPI_MakeShapeList aMakeShapeList;
+        std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
         GeomShapePtr aResShape;
 
         switch(aType) {
           case BOOL_CUT: {
-            aBoolAlgo =
-              GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_CUT);
-            aResShape = aBoolAlgo.shape();
+            aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject,
+                                                    aTools,
+                                                    GeomAlgoAPI_Boolean::BOOL_CUT));
+            aResShape = aBoolAlgo->shape();
             break;
           }
           case BOOL_COMMON: {
-            aBoolAlgo =
-              GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_COMMON);
-            aResShape = aBoolAlgo.shape();
+            aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject,
+                                                    aTools,
+                                                    GeomAlgoAPI_Boolean::BOOL_COMMON));
+            aResShape = aBoolAlgo->shape();
             break;
           }
           case BOOL_FILL: {
-            aBoolAlgo = GeomAlgoAPI_Partition(aListWithObject, aTools);
-            aResShape = aBoolAlgo.shape();
+              std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
+                GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0);
+
+            // Resize planes.
+            ListOfShape aToolsWithPlanes = aTools;
+            for(ListOfShape::const_iterator anIt = aPlanes.cbegin();
+                                            anIt != aPlanes.cend();
+                                            ++anIt)
+            {
+              GeomShapePtr aPlane = *anIt;
+              GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
+              std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
+                new GeomAlgoAPI_MakeShapeCustom);
+              aMkShCustom->addModified(aPlane, aTool);
+              aMakeShapeList.appendAlgo(aMkShCustom);
+              aToolsWithPlanes.push_back(aTool);
+            }
+
+            aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes));
+            aResShape = aBoolAlgo->shape();
             if(aResShape->shapeType() == GeomAPI_Shape::COMPOUND) {
               int aSubResultsNb = 0;
               GeomAPI_ShapeIterator anIt(aResShape);
@@ -196,7 +228,7 @@ void FeaturesPlugin_Boolean::execute()
         }
 
         // Checking that the algorithm worked properly.
-        if(!aBoolAlgo.isDone()) {
+        if(!aBoolAlgo->isDone()) {
           static const std::string aFeatureError = "Error: Boolean algorithm failed.";
           setError(aFeatureError);
           return;
@@ -206,17 +238,27 @@ void FeaturesPlugin_Boolean::execute()
           setError(aShapeError);
           return;
         }
-        if(!aBoolAlgo.isValid()) {
+        if(!aBoolAlgo->isValid()) {
           std::string aFeatureError = "Error: Resulting shape is not valid.";
           setError(aFeatureError);
           return;
         }
 
-        if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27) {
+        aMakeShapeList.appendAlgo(aBoolAlgo);
+
+        if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27
+          || (aType != BOOL_CUT && aType != BOOL_COMMON))
+        {
           std::shared_ptr<ModelAPI_ResultBody> aResultBody =
             document()->createBody(data(), aResultIndex);
-          loadNamingDS(aResultBody, anObject, aTools, aResShape,
-                       aBoolAlgo, *aBoolAlgo.mapOfSubShapes().get());
+
+          ListOfShape aUsedTools = aTools;
+          if (aType == BOOL_FILL) {
+            aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end());
+          }
+
+          loadNamingDS(aResultBody, anObject, aUsedTools, aResShape,
+                       aMakeShapeList, *(aBoolAlgo->mapOfSubShapes()), aType == BOOL_FILL);
           setResult(aResultBody, aResultIndex);
           aResultIndex++;
         }
@@ -245,6 +287,7 @@ void FeaturesPlugin_Boolean::execute()
           }
         }
 
+        GeomAlgoAPI_MakeShapeList aMakeShapeList;
         std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
 
         switch(aType) {
@@ -261,7 +304,25 @@ void FeaturesPlugin_Boolean::execute()
             break;
           }
           case BOOL_FILL: {
-            aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aTools));
+            std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
+              GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0);
+
+            // Resize planes.
+            ListOfShape aToolsWithPlanes = aTools;
+            for(ListOfShape::const_iterator anIt = aPlanes.cbegin();
+                                            anIt != aPlanes.cend();
+                                            ++anIt)
+            {
+              GeomShapePtr aPlane = *anIt;
+              GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
+              std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
+                new GeomAlgoAPI_MakeShapeCustom);
+              aMkShCustom->addModified(aPlane, aTool);
+              aMakeShapeList.appendAlgo(aMkShCustom);
+              aToolsWithPlanes.push_back(aTool);
+            }
+
+            aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aToolsWithPlanes));
             break;
           }
         }
@@ -283,7 +344,6 @@ void FeaturesPlugin_Boolean::execute()
           return;
         }
 
-        GeomAlgoAPI_MakeShapeList aMakeShapeList;
         aMakeShapeList.appendAlgo(aBoolAlgo);
         GeomAPI_DataMapOfShapeShape aMapOfShapes;
         aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
@@ -306,10 +366,24 @@ void FeaturesPlugin_Boolean::execute()
           aResultShape = aFillerAlgo->shape();
         }
 
-        if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27) {
+        if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27
+          || (aType != BOOL_CUT && aType != BOOL_COMMON))
+        {
           std::shared_ptr<ModelAPI_ResultBody> aResultBody =
             document()->createBody(data(), aResultIndex);
-          loadNamingDS(aResultBody, aCompSolid, aTools, aResultShape, aMakeShapeList, aMapOfShapes);
+
+          ListOfShape aUsedTools = aTools;
+          if (aType == BOOL_FILL) {
+            aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end());
+          }
+
+          loadNamingDS(aResultBody,
+                       aCompSolid,
+                       aUsedTools,
+                       aResultShape,
+                       aMakeShapeList,
+                       aMapOfShapes,
+                       aType == BOOL_FILL);
           setResult(aResultBody, aResultIndex);
           aResultIndex++;
         }
@@ -626,7 +700,8 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> t
                                           const ListOfShape& theTools,
                                           const std::shared_ptr<GeomAPI_Shape> theResultShape,
                                           GeomAlgoAPI_MakeShape& theMakeShape,
-                                          GeomAPI_DataMapOfShapeShape& theMapOfShapes)
+                                          GeomAPI_DataMapOfShapeShape& theMapOfShapes,
+                                          const bool theIsStoreAsGenerated)
 {
   //load result
   if(theBaseShape->isEqual(theResultShape)) {
@@ -645,7 +720,7 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> t
     const std::string aModFName = "Modified_Face";
 
     theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
-      aModifyTag, aModName, theMapOfShapes, false, false, true);
+      aModifyTag, aModName, theMapOfShapes, false, theIsStoreAsGenerated, true);
     theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
                                      GeomAPI_Shape::FACE, aDeletedTag);
 
@@ -666,7 +741,7 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> t
       }
       theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter,
         aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE,
-        aTag, aName, theMapOfShapes, false, false, true);
+        aTag, aName, theMapOfShapes, false, theIsStoreAsGenerated, true);
       theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
     }
   }
index 726b33846bc0e402630a422f65e8d146d16cdede..d49820686883058d1991b778f8ab14a0f6c6ec4c 100644 (file)
@@ -95,7 +95,8 @@ private:
                     const ListOfShape& theTools,
                     const std::shared_ptr<GeomAPI_Shape> theResultShape,
                     GeomAlgoAPI_MakeShape& theMakeShape,
-                    GeomAPI_DataMapOfShapeShape& theMapOfShapes);
+                    GeomAPI_DataMapOfShapeShape& theMapOfShapes,
+                    const bool theIsStoreAsGenerated = false);
 };
 
 #endif
index adde95a0b22668d6cf0d1cf82976265096529ca3..a3018be53df4c5a9a3d8ed67cf708ad68f538408 100644 (file)
@@ -506,6 +506,11 @@ void FeaturesPlugin_CompositeSketch::storeShapes(ResultBodyPtr theResultBody,
       std::string aName = theName + aShapeTypeStr;
       storeSubShape(theResultBody, aShape, aShapeTypeToExplore,
                     theMapOfSubShapes, aName, aShapeIndex, theTag);
+      if (theBaseShapeType == GeomAPI_Shape::WIRE) { // issue 2289: special names also for vertices
+        aName = theName + "Vertex";
+        storeSubShape(theResultBody, aShape, GeomAPI_Shape::VERTEX,
+                      theMapOfSubShapes, aName, aShapeIndex, theTag);
+      }
     }
   }
 }
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp b/src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp
new file mode 100644 (file)
index 0000000..0df54c1
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright (C) 2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "FeaturesPlugin_Fillet.h"
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomAlgoAPI_Fillet.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+
+#include <GeomAPI_DataMapOfShapeMapOfShapes.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+
+// Obtain all sub-shapes from the shape and append them to the list
+static void collectSubs(const GeomShapePtr& theShape,
+                              ListOfShape& theSubs,
+                        const GeomAPI_Shape::ShapeType theShapeType)
+{
+  GeomAPI_ShapeExplorer anExp(theShape, theShapeType);
+  for (; anExp.more(); anExp.next()) {
+    GeomShapePtr aShape = anExp.current();
+    // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices
+    aShape->setOrientation(GeomAPI_Shape::FORWARD);
+    theSubs.push_back(aShape);
+  }
+}
+
+// Extract edges from the list
+static ListOfShape selectEdges(const ListOfShape& theShapes)
+{
+  ListOfShape anEdges;
+  for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
+    if ((*anIt)->isEdge())
+      anEdges.push_back(*anIt);
+  return anEdges;
+}
+
+// If theShape is a compound of single shape, return it
+static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape)
+{
+  GeomShapePtr aShape = theShape;
+  if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+    int aSubResultsNb = 0;
+    GeomAPI_ShapeIterator anIt(aShape);
+    for(; anIt.more(); anIt.next())
+      ++aSubResultsNb;
+
+    if(aSubResultsNb == 1) {
+      anIt.init(aShape);
+      aShape = anIt.current();
+    }
+  }
+  return aShape;
+}
+
+
+FeaturesPlugin_Fillet::FeaturesPlugin_Fillet()
+{
+}
+
+void FeaturesPlugin_Fillet::initAttributes()
+{
+  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+  data()->addAttribute(START_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(END_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
+
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_RADIUS_ID());
+}
+
+
+void FeaturesPlugin_Fillet::execute()
+{
+  AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
+  if (!aCreationMethod)
+    return;
+
+  GeomAPI_DataMapOfShapeMapOfShapes aSolidsAndSubs;
+
+  // getting objects and sort them accroding to parent solids
+  AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
+  for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
+    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+    GeomShapePtr anObject = anObjectAttr->value();
+    if (!anObject)
+      return;
+
+    ResultPtr aContext = anObjectAttr->context();
+    ResultCompSolidPtr aCtxOwner = ModelAPI_Tools::compSolidOwner(aContext);
+    GeomShapePtr aParent = aCtxOwner ? aCtxOwner->shape() : aContext->shape();
+    if (!aParent)
+      return;
+
+    ListOfShape anEdgesAndVertices;
+    collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE);
+    collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX);
+    for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
+         aEIt != anEdgesAndVertices.end(); ++aEIt)
+      aSolidsAndSubs.add(aParent, *aEIt);
+  }
+
+  bool isFixedRadius = true;
+  double aRadius1 = 0.0, aRadius2 = 0.0;
+  if (aCreationMethod->value() == CREATION_METHOD_SINGLE_RADIUS())
+    aRadius1 = real(RADIUS_ID())->value();
+  else {
+    aRadius1 = real(START_RADIUS_ID())->value();
+    aRadius2 = real(END_RADIUS_ID())->value();
+    isFixedRadius = false;
+  }
+
+  // Perform fillet operation
+  GeomAlgoAPI_MakeShapeList aMakeShapeList;
+  std::shared_ptr<GeomAlgoAPI_Fillet> aFilletBuilder;
+  int aResultIndex = 0;
+
+  GeomAPI_DataMapOfShapeMapOfShapes::iterator anIt = aSolidsAndSubs.begin();
+  for (; anIt != aSolidsAndSubs.end(); ++anIt) {
+    GeomShapePtr aSolid = anIt.first();
+    ListOfShape aFilletEdgesAndVertices = anIt.second();
+
+    ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices);
+    if (isFixedRadius)
+      aFilletBuilder.reset(new GeomAlgoAPI_Fillet(aSolid, aFilletEdges, aRadius1));
+    else
+      aFilletBuilder.reset(new GeomAlgoAPI_Fillet(aSolid, aFilletEdges, aRadius1, aRadius2));
+    if (isFailed(aFilletBuilder))
+      return;
+
+    GeomShapePtr aResult = unwrapCompound(aFilletBuilder->shape());
+    std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+        document()->createBody(data(), aResultIndex);
+
+    loadNamingDS(aResultBody, aSolid, aFilletEdgesAndVertices, aResult, aFilletBuilder);
+    setResult(aResultBody, aResultIndex);
+    aResultIndex++;
+  }
+  removeResults(aResultIndex);
+}
+
+bool FeaturesPlugin_Fillet::isFailed(
+    const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm)
+{
+  if (!theAlgorithm->isDone()) {
+    static const std::string aFeatureError = "Error: fillet algorithm failed.";
+    setError(aFeatureError);
+    return true;
+  }
+  if (theAlgorithm->shape()->isNull()) {
+    static const std::string aShapeError = "Error: Resulting shape of fillet is Null.";
+    setError(aShapeError);
+    return true;
+  }
+  if (!theAlgorithm->isValid()) {
+    std::string aFeatureError = "Error: Resulting shape of fillet is not valid.";
+    setError(aFeatureError);
+    return true;
+  }
+  return false;
+}
+
+void FeaturesPlugin_Fillet::loadNamingDS(
+    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+    const ListOfShape& theFilletShapes,
+    const std::shared_ptr<GeomAPI_Shape> theResultShape,
+    const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
+{
+  //load result
+  if(theBaseShape->isEqual(theResultShape)) {
+    theResultBody->store(theResultShape, false);
+    return;
+  }
+
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfShapes = theMakeShape->mapOfSubShapes();
+
+  const int aDeletedTag = 1;
+  const int aModifyTag = 2;
+  const int aGeneratedTag = 3;
+  /// sub solids will be placed at labels 4, 5, etc. if result is compound of solids
+  const int aSubsolidsTag = 4;
+
+  theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
+  theResultBody->storeGenerated(theBaseShape, theResultShape);
+
+  const std::string aModFaceName = "Modified_Face";
+  const std::string aFilletFaceName = "Fillet_Face";
+
+  // Store modified faces
+  theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), theBaseShape,
+      GeomAPI_Shape::FACE, aModifyTag, aModFaceName, *aMapOfShapes);
+
+  // Store new faces generated from edges and vertices
+  theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape,
+      GeomAPI_Shape::EDGE, aGeneratedTag, aFilletFaceName, *aMapOfShapes);
+  theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape,
+      GeomAPI_Shape::VERTEX, aGeneratedTag, aFilletFaceName, *aMapOfShapes);
+
+  // Deleted shapes
+  theResultBody->loadDeletedShapes(theMakeShape.get(), theBaseShape,
+                                   GeomAPI_Shape::EDGE, aDeletedTag);
+  theResultBody->loadDeletedShapes(theMakeShape.get(), theBaseShape,
+                                   GeomAPI_Shape::FACE, aDeletedTag);
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Fillet.h b/src/FeaturesPlugin/FeaturesPlugin_Fillet.h
new file mode 100644 (file)
index 0000000..d0aa712
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef FeaturesPlugin_Fillet_H_
+#define FeaturesPlugin_Fillet_H_
+
+#include "FeaturesPlugin.h"
+
+#include <GeomAPI_Shape.h>
+
+#include <ModelAPI_Feature.h>
+
+class GeomAlgoAPI_MakeShape;
+class GeomAPI_DataMapOfShapeMapOfShapes;
+
+/// \class FeaturesPlugin_Fillet
+/// \ingroup Plugins
+/// \brief Feature for applying the Fillet operations on Solids.
+///        Supports fixed radius fillet and varying 2-radius fillet.
+class FeaturesPlugin_Fillet : public ModelAPI_Feature
+{
+public:
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Fillet");
+    return MY_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Fillet::ID();
+    return MY_KIND;
+  }
+
+  inline static const std::string& CREATION_METHOD()
+  {
+    static std::string MY_CREATION_METHOD("creation_method");
+    return MY_CREATION_METHOD;
+  }
+
+  inline static const std::string CREATION_METHOD_SINGLE_RADIUS()
+  {
+    static std::string MY_SINGLE_RADIUS("fixed_radius");
+    return MY_SINGLE_RADIUS;
+  }
+
+  inline static const std::string CREATION_METHOD_VARYING_RADIUS()
+  {
+    static std::string MY_VARYING_RADIUS("variable_radius");
+    return MY_VARYING_RADIUS;
+  }
+
+  /// Attribute name of main objects.
+  inline static const std::string& OBJECT_LIST_ID()
+  {
+    static const std::string MY_OBJECT_LIST_ID("main_objects");
+    return MY_OBJECT_LIST_ID;
+  }
+
+  /// Attribute name of start radius.
+  inline static const std::string& START_RADIUS_ID()
+  {
+    static const std::string MY_START_RADIUS_ID("radius1");
+    return MY_START_RADIUS_ID;
+  }
+
+  /// Attribute name of end radius.
+  inline static const std::string& END_RADIUS_ID()
+  {
+    static const std::string MY_END_RADIUS_ID("radius2");
+    return MY_END_RADIUS_ID;
+  }
+
+  /// Attribute name of a radius for fillet with fixed radius.
+  inline static const std::string& RADIUS_ID()
+  {
+    return START_RADIUS_ID();
+  }
+
+  /// Creates a new part document if needed.
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_Fillet();
+
+private:
+  /// Check algorithm is finished correctly and store error otherwise
+  bool isFailed(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
+
+  /// Load Naming data structure of the feature to the document
+  void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                    const ListOfShape& theFilletShapes,
+                    const std::shared_ptr<GeomAPI_Shape> theResultShape,
+                    const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
+};
+
+#endif
index 954a0fb3c6786f30618271f2d7055b038dd8eea9..b9760dc07027ad7c55a7d4a85171ae343ad62659 100644 (file)
@@ -24,6 +24,7 @@
 #include <FeaturesPlugin_Extrusion.h>
 #include <FeaturesPlugin_ExtrusionCut.h>
 #include <FeaturesPlugin_ExtrusionFuse.h>
+#include <FeaturesPlugin_Fillet.h>
 #include <FeaturesPlugin_Intersection.h>
 #include <FeaturesPlugin_MultiRotation.h>
 #include <FeaturesPlugin_MultiTranslation.h>
@@ -84,6 +85,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorUnionArguments);
   aFactory->registerValidator("FeaturesPlugin_ValidatorConcealedResult",
                               new FeaturesPlugin_ValidatorConcealedResult);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorFilletSelection",
+                              new FeaturesPlugin_ValidatorFilletSelection);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
@@ -131,6 +134,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_MultiTranslation);
   } else if (theFeatureID == FeaturesPlugin_MultiRotation::ID()) {
     return FeaturePtr(new FeaturesPlugin_MultiRotation);
+  } else if (theFeatureID == FeaturesPlugin_Fillet::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Fillet);
   }
 
   // feature of such kind is not found
index 53d02ab83e183e643c45c03357965aea72d51dc1..2f54129831f54599ecfee4f72b51c36924e03050 100644 (file)
@@ -21,6 +21,7 @@
 #include "FeaturesPlugin_RemoveSubShapes.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_ResultConstruction.h>
@@ -38,6 +39,7 @@
 
 //==================================================================================================
 FeaturesPlugin_RemoveSubShapes::FeaturesPlugin_RemoveSubShapes()
+: myChangedInCode(false)
 {
 }
 
@@ -46,59 +48,141 @@ void FeaturesPlugin_RemoveSubShapes::initAttributes()
 {
   data()->addAttribute(BASE_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
 
-  data()->addAttribute(SUBSHAPES_ID(), ModelAPI_AttributeSelectionList::typeId());
+  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+  data()->addAttribute(SUBSHAPES_TO_KEEP_ID(), ModelAPI_AttributeSelectionList::typeId());
+
+  data()->addAttribute(SUBSHAPES_TO_REMOVE_ID(), ModelAPI_AttributeSelectionList::typeId());
 }
 
 void FeaturesPlugin_RemoveSubShapes::attributeChanged(const std::string& theID)
 {
   ModelAPI_Feature::attributeChanged(theID);
 
-  if(theID == BASE_SHAPE_ID()) {
-    AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
-    AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID());
-    if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
-      return;
-    }
+  if (myChangedInCode) return;
 
-    aSubShapesAttrList->clear();
+  AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
+  AttributeSelectionListPtr aSubShapesToKeepAttrList = selectionList(SUBSHAPES_TO_KEEP_ID());
+  AttributeSelectionListPtr aSubShapesToRemoveAttrList = selectionList(SUBSHAPES_TO_REMOVE_ID());
+  if (!aShapeAttrSelection.get()
+      || !aSubShapesToKeepAttrList.get()
+      || !aSubShapesToRemoveAttrList.get())
+  {
+    return;
+  }
 
-    ResultPtr aContext = aShapeAttrSelection->context();
-    ResultCompSolidPtr aResultCompSolid =
-      std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
-    if(!aResultCompSolid.get()) {
-      return;
-    }
+  ResultPtr aContext = aShapeAttrSelection->context();
+  ResultCompSolidPtr aResultCompSolid =
+    std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
+  if(!aResultCompSolid.get()) {
+    aSubShapesToKeepAttrList->clear();
+    aSubShapesToRemoveAttrList->clear();
+    return;
+  }
+  const int aNumOfSubs = aResultCompSolid->numberOfSubs();
 
-    GeomShapePtr aBaseShape = aShapeAttrSelection->value();
-    if(!aBaseShape.get()) {
-      aBaseShape = aContext->shape();
-    }
-    if(!aBaseShape.get()) {
-      return;
-    }
-    GeomAPI_Shape::ShapeType aShapeType = aBaseShape->shapeType();
-    if(aShapeType != GeomAPI_Shape::WIRE
-        && aShapeType != GeomAPI_Shape::SHELL
-        && aShapeType != GeomAPI_Shape::COMPSOLID
-        && aShapeType != GeomAPI_Shape::COMPOUND) {
+  GeomShapePtr aBaseShape = aShapeAttrSelection->value();
+  if(!aBaseShape.get()) {
+    aBaseShape = aContext->shape();
+  }
+
+  myChangedInCode = true;
+
+  if(theID == BASE_SHAPE_ID()) {
+    aSubShapesToKeepAttrList->clear();
+    aSubShapesToRemoveAttrList->clear();
+
+    if (!aBaseShape.get()) {
       return;
     }
+
     for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
       GeomShapePtr aSubShape = anIt.current();
-      const int aNumOfSubs = aResultCompSolid->numberOfSubs();
       if(aNumOfSubs == 0) {
-        aSubShapesAttrList->append(aContext, aSubShape);
+        aSubShapesToKeepAttrList->append(aContext, aSubShape);
       } else {
         for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) {
           ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex);
           if(aSubResult->shape()->isEqual(aSubShape)) {
-            aSubShapesAttrList->append(aSubResult, aSubShape);
+            aSubShapesToKeepAttrList->append(aSubResult, aSubShape);
             break;
           }
         }
       }
     }
   }
+  else if (theID == SUBSHAPES_TO_KEEP_ID())
+  {
+    aSubShapesToRemoveAttrList->clear();
+
+    if (!aBaseShape.get()) {
+      return;
+    }
+
+    int anIndex;
+    const int aSubsToKeepNb = aSubShapesToKeepAttrList->size();
+    for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+      GeomShapePtr aSubShape = anIt.current();
+      for(anIndex = 0; anIndex < aSubsToKeepNb; ++anIndex) {
+        AttributeSelectionPtr anAttrSelectionInList = aSubShapesToKeepAttrList->value(anIndex);
+        GeomShapePtr aSubShapeToKeep = anAttrSelectionInList->value();
+        if (aSubShapeToKeep.get() && aSubShapeToKeep->isEqual(aSubShape)) {
+          break;
+        }
+      }
+
+      if (anIndex == aSubsToKeepNb) {
+        if(aNumOfSubs == 0) {
+          aSubShapesToRemoveAttrList->append(aContext, aSubShape);
+        } else {
+          for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) {
+            ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex);
+            if(aSubResult->shape()->isEqual(aSubShape)) {
+              aSubShapesToRemoveAttrList->append(aSubResult, aSubShape);
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (theID == SUBSHAPES_TO_REMOVE_ID())
+  {
+    aSubShapesToKeepAttrList->clear();
+
+    if (!aBaseShape.get()) {
+      return;
+    }
+
+    int anIndex;
+    const int aSubsToRemoveNb = aSubShapesToRemoveAttrList->size();
+    for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+      GeomShapePtr aSubShape = anIt.current();
+      for(anIndex = 0; anIndex < aSubsToRemoveNb; ++anIndex) {
+        AttributeSelectionPtr anAttrSelectionInList = aSubShapesToRemoveAttrList->value(anIndex);
+        GeomShapePtr aSubShapeToRemove = anAttrSelectionInList->value();
+        if (aSubShapeToRemove.get() && aSubShapeToRemove->isEqual(aSubShape)) {
+          break;
+        }
+      }
+
+      if (anIndex == aSubsToRemoveNb) {
+        if(aNumOfSubs == 0) {
+          aSubShapesToKeepAttrList->append(aContext, aSubShape);
+        } else {
+          for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) {
+            ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex);
+            if(aSubResult->shape()->isEqual(aSubShape)) {
+              aSubShapesToKeepAttrList->append(aSubResult, aSubShape);
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  myChangedInCode = false;
 }
 
 //==================================================================================================
@@ -106,7 +190,7 @@ void FeaturesPlugin_RemoveSubShapes::execute()
 {
   // Get base shape and sub-shapes list.
   AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
-  AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID());
+  AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_TO_KEEP_ID());
   if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
     return;
   }
index 39cb6fabeafc166a9e99e5084807c03f276b99c3..4bbe6a01c2abf0b3017c5a4be2a92f7038137f6b 100644 (file)
@@ -48,13 +48,42 @@ public:
     return MY_BASE_SHAPE_ID;
   }
 
-  /// Attribute name of sub-shapes.
-  inline static const std::string& SUBSHAPES_ID()
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
   {
-    static const std::string MY_SUBSHAPES_ID("subshapes");
+    static const std::string MY_CREATION_METHOD_ID("creation_method");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_BY_KEEP_SUBSHAPES()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_keep_subshapes");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_BY_REMOVE_SUBSHAPES()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_remove_subshapes");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name of sub-shapes to keep.
+  inline static const std::string& SUBSHAPES_TO_KEEP_ID()
+  {
+    static const std::string MY_SUBSHAPES_ID("subshapes_to_keep");
     return MY_SUBSHAPES_ID;
   }
 
+  /// Attribute name of sub-shapes to remove.
+  inline static const std::string& SUBSHAPES_TO_REMOVE_ID()
+  {
+    static const std::string MY_SUBSHAPES_ID("subshapes_to_remove");
+    return MY_SUBSHAPES_ID;
+  }
+
+
   /// \return the kind of a feature.
   FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -71,6 +100,9 @@ public:
 
   /// Creates a new part document if needed.
   FEATURESPLUGIN_EXPORT virtual void execute();
+
+private:
+  bool myChangedInCode;
 };
 
 #endif
index 2b3188ddcbd4d5f4fcc439063fa034cc734974a5..66bef610ccf6784882a93a7291050995f306fa57 100644 (file)
 #include <GeomAlgoAPI_Boolean.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_PaveFiller.h>
+#include <GeomAlgoAPI_UnifySameDomain.h>
 
 #include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
 
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultCompSolid.h>
@@ -87,7 +89,7 @@ void FeaturesPlugin_Union::execute()
     anObjects.insert(anObjects.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end());
 
     // Collect solids from compsolid which will not be modified in boolean operation.
-    for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
+    for(GeomAPI_ShapeIterator anExp(aCompSolid); anExp.more(); anExp.next()) {
       std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
       ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
       for(; anIt != aUsedInOperationSolids.end(); anIt++) {
@@ -107,31 +109,36 @@ void FeaturesPlugin_Union::execute()
   }
 
   // Fuse objects.
+  std::shared_ptr<GeomAlgoAPI_MakeShape> anAlgo;
   ListOfShape aTools;
-  aTools.splice(aTools.begin(), anObjects, anObjects.begin());
-  std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
-                                                            aTools,
-                                                            GeomAlgoAPI_Boolean::BOOL_FUSE));
+  if (anObjects.front()->shapeType() == GeomAPI_Shape::SOLID) {
+    aTools.splice(aTools.begin(), anObjects, anObjects.begin());
+    anAlgo.reset(new GeomAlgoAPI_Boolean(anObjects,
+                 aTools,
+                 GeomAlgoAPI_Boolean::BOOL_FUSE));
+  } else {
+    anAlgo.reset(new GeomAlgoAPI_UnifySameDomain(anObjects));
+  }
 
   // Checking that the algorithm worked properly.
   GeomAlgoAPI_MakeShapeList aMakeShapeList;
   GeomAPI_DataMapOfShapeShape aMapOfShapes;
-  if(!aFuseAlgo->isDone()) {
+  if(!anAlgo->isDone()) {
     setError("Error: Boolean algorithm failed.");
     return;
   }
-  if(aFuseAlgo->shape()->isNull()) {
+  if(anAlgo->shape()->isNull()) {
     setError("Error: Resulting shape is Null.");
     return;
   }
-  if(!aFuseAlgo->isValid()) {
+  if(!anAlgo->isValid()) {
     setError("Error: Resulting shape is not valid.");
     return;
   }
 
-  GeomShapePtr aShape = aFuseAlgo->shape();
-  aMakeShapeList.appendAlgo(aFuseAlgo);
-  aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
+  GeomShapePtr aShape = anAlgo->shape();
+  aMakeShapeList.appendAlgo(anAlgo);
+  aMapOfShapes.merge(anAlgo->mapOfSubShapes());
 
   // Store original shapes for naming.
   anObjects.splice(anObjects.begin(), aTools);
@@ -161,18 +168,21 @@ void FeaturesPlugin_Union::execute()
   }
 
   // Store result and naming.
-  const int aModifyTag = 1;
-  const int aDeletedTag = 2;
-  /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
-  const int aSubsolidsTag = 3;
+  const int aModifyEdgeTag = 1;
+  const int aModifyFaceTag = 2;
+  const int aDeletedTag = 3;
+  /// sub solids will be placed at labels 4, 5 etc. if result is compound of solids
+  const int aSubsolidsTag = 4;
   const std::string aModName = "Modified";
 
   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
   aResultBody->storeModified(anObjects.front(), aShape, aSubsolidsTag);
 
   for(ListOfShape::const_iterator anIter = anObjects.begin(); anIter != anObjects.end(); ++anIter) {
+    aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::EDGE,
+                                             aModifyEdgeTag, aModName, aMapOfShapes);
     aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE,
-                                             aModifyTag, aModName, aMapOfShapes);
+                                             aModifyFaceTag, aModName, aMapOfShapes);
     aResultBody->loadDeletedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
   }
 
index acc2b8becfa8d36a29a2f60c8d31a902f08b70c5..4c53bcbb2bf6b58047f571810267a58d4d249803 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "FeaturesPlugin_Validators.h"
 
+#include "FeaturesPlugin_Boolean.h"
 #include "FeaturesPlugin_Union.h"
 
 #include <Events_InfoMessage.h>
@@ -608,8 +609,11 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt
     ResultConstructionPtr aResultConstruction =
       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
     if(aResultConstruction.get()) {
-      theError = "Error: Result construction not allowed for selection.";
-      return false;
+      if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
+          || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
+        theError = "Error: Result construction not allowed for selection.";
+        return false;
+      }
     }
     std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
     GeomShapePtr aContextShape = aContext->shape();
@@ -625,24 +629,75 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt
       return false;
     }
 
-    int aShapeType = aShape->shapeType();
-    if(anOperationType == 1) {
-      // Fuse operation. Allow to select edges, faces and solids.
-      if(aShapeType != GeomAPI_Shape::EDGE &&
-         aShapeType != GeomAPI_Shape::FACE &&
-         aShapeType != GeomAPI_Shape::SOLID &&
-         aShapeType != GeomAPI_Shape::COMPSOLID &&
-         aShapeType != GeomAPI_Shape::COMPOUND) {
-        theError = "Error: Selected shape has the wrong type.";
-        return false;
-      }
+    GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
+    std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
+    if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
+      anAllowedTypes.insert(GeomAPI_Shape::EDGE);
+      anAllowedTypes.insert(GeomAPI_Shape::FACE);
+      anAllowedTypes.insert(GeomAPI_Shape::SOLID);
+      anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
+      anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
+    } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL) {
+      anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
+      anAllowedTypes.insert(GeomAPI_Shape::EDGE);
+      anAllowedTypes.insert(GeomAPI_Shape::WIRE);
+      anAllowedTypes.insert(GeomAPI_Shape::FACE);
+      anAllowedTypes.insert(GeomAPI_Shape::SHELL);
+      anAllowedTypes.insert(GeomAPI_Shape::SOLID);
+      anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
+      anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
     } else {
-      if(aShapeType != GeomAPI_Shape::SOLID &&
-         aShapeType != GeomAPI_Shape::COMPSOLID &&
-         aShapeType != GeomAPI_Shape::COMPOUND) {
-        theError = "Error: Selected shape has the wrong type.";
-        return false;
-      }
+      anAllowedTypes.insert(GeomAPI_Shape::SOLID);
+      anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
+      anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
+    }
+
+    if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
+      || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
+      theError = "Error: Selected shape has the wrong type.";
+      return false;
+    }
+
+  }
+
+  return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
+                                                      const std::list<std::string>& theArguments,
+                                                      Events_InfoMessage& theError) const
+{
+  AttributeSelectionListPtr anAttrSelectionList =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if(!anAttrSelectionList.get()) {
+    theError =
+      "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
+    return false;
+  }
+
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  // Check all selected entities are sub-shapes of single solid
+  GeomShapePtr aBaseSolid;
+  for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+    if(!anAttrSelection.get()) {
+      theError = "Error: Empty attribute selection.";
+      return false;
+    }
+    ResultPtr aContext = anAttrSelection->context();
+    if(!aContext.get()) {
+      theError = "Error: Empty selection context.";
+      return false;
+    }
+
+    ResultCompSolidPtr aContextOwner = ModelAPI_Tools::compSolidOwner(aContext);
+    GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
+    if (!aBaseSolid)
+      aBaseSolid = anOwner;
+    else if (!aBaseSolid->isEqual(anOwner)) {
+      theError = "Error: Sub-shapes of different solids have been selected.";
+      return false;
     }
   }
 
@@ -759,7 +814,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
   Events_InfoMessage& theError) const
 {
   static const std::string aBaseShapeID = "base_shape";
-  static const std::string aSubShapesID = "subshapes";
+  static const std::string aSubShapesID = "subshapes_to_keep";
 
   if(theFeature->getKind() != "Remove_SubShapes") {
     theError = "Error: Feature \"%1\" does not supported by this validator.";
@@ -789,6 +844,11 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
   }
   GeomShapePtr aResultShape = aBaseShape->emptyCopied();
 
+  if (aSubShapesAttrList->size() == 0) {
+    theError = "Error: Resulting shape is not valid.";
+    return false;
+  }
+
   // Copy sub-shapes from list to new shape.
   for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
     AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
@@ -828,11 +888,28 @@ bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttr
   for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
     bool isSameFound = false;
     AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
+    ResultPtr aContext = anAttrSelectionInList->context();
+
+    ResultConstructionPtr aConstruction =
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+    if(aConstruction.get()) {
+      theError = "Error: Result construction not allowed for selection.";
+      return false;
+    }
+
+    GeomShapePtr aShape = anAttrSelectionInList->value();
+    GeomShapePtr aContextShape = aContext->shape();
+    if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
+      theError = "Error: Local selection not allowed.";
+      return false;
+    }
+
     ResultCompSolidPtr aResult =
-      std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
+      std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
     if(!aResult.get()) {
       continue;
     }
+
     if(aResult->numberOfSubs() > 0) {
       theError = "Error: Whole compsolids not allowed for selection.";
       return false;
@@ -865,17 +942,27 @@ bool FeaturesPlugin_ValidatorUnionArguments::isValid(
   }
 
   // Get all shapes.
+  GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
   ListOfShape aBaseShapesList;
   for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
     AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
     GeomShapePtr aShape = anAttrSelectionInList->value();
+    if (!aShape.get()) {
+      continue;
+    }
     aBaseShapesList.push_back(aShape);
+    aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
+                                                         GeomAPI_Shape::COMPSOLID;
   }
 
-  // Make componud and find connected.
+  // Make compound and find connected.
   GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
   ListOfShape aCombined, aFree;
-  GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
+  GeomAlgoAPI_ShapeTools::combineShapes(
+    aCompound,
+    aType,
+    aCombined,
+    aFree);
 
   if(aFree.size() > 0 || aCombined.size() > 1) {
     theError = "Error: Not all shapes have shared topology.";
index d8c0a091e1a1e6ae1c09c17d7ce2cad7ba754b25..62edcb2bf7fdf7fa8128a2f809a02cd117c6fea8 100644 (file)
@@ -152,6 +152,22 @@ public:
                        Events_InfoMessage& theError) const;
 };
 
+/// \class FeaturesPlugin_ValidatorFilletSelection
+/// \ingroup Validators
+/// \brief Validates selection for fillet operation.
+class FeaturesPlugin_ValidatorFilletSelection: public ModelAPI_AttributeValidator
+{
+public:
+  /// \return True if the attribute is valid. It checks whether the selection
+  /// is acceptable for boolean operation.
+  /// \param[in] theAttribute an attribute to check.
+  /// \param[in] theArguments a filter parameters.
+  /// \param[out] theError error message.
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments,
+                       Events_InfoMessage& theError) const;
+};
+
 /// \class FeaturesPlugin_ValidatorPartitionSelection
 /// \ingroup Validators
 /// \brief Validates selection for partition.
index 1e7fab54dc35286a1b64cbf28a722be222dabc24..5a46be2543c0b999757c6df18206e92966c247f5 100644 (file)
   <context>
     <name>Union:GeomValidators_MinObjectsSelected</name>
     <message>
-      <source>Error: Attribute \"%1\" should contain at least %2 items.</source>
-      <translation></translation>
+      <source>Error: Attribute "%1" should contain at least %2 items.</source>
+      <translation>"Base objects" should contain at least 2 items.</translation>
     </message>
   </context>
 </TS>
index a9224658b368932c2b511a233b3e0ce5ab92831a..4364f9ebf65708eb19890cbd3e4d2a7da3d10cd9 100644 (file)
@@ -97,38 +97,38 @@ SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchPoint_12.coordinat
 model.do()
 Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_6s-SketchLine_5e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_7"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_5s-SketchLine_4e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_11"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_2e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_10"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_8"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_9"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_2s-SketchLine_1e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_4s-SketchLine_3e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_13"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_6e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_14"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_2"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_6"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_1"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_4"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_5")])
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("VERTEX", "Vertex_1_1"), model.selection("VERTEX", "Vertex_1_2"), model.selection("VERTEX", "Vertex_1_3"), model.selection("VERTEX", "Vertex_1_4"), model.selection("VERTEX", "Vertex_1_5"), model.selection("VERTEX", "Vertex_1_6"), model.selection("VERTEX", "Vertex_1_7"), model.selection("VERTEX", "Vertex_1_8"), model.selection("VERTEX", "Vertex_1_9"), model.selection("VERTEX", "Vertex_1_10"), model.selection("VERTEX", "Vertex_1_11"), model.selection("VERTEX", "Vertex_1_12"), model.selection("VERTEX", "Vertex_1_13"), model.selection("VERTEX", "Vertex_1_14"), model.selection("VERTEX", "Vertex_1_15"), model.selection("VERTEX", "Vertex_1_16"), model.selection("VERTEX", "Vertex_1_17"), model.selection("VERTEX", "Vertex_1_18")], model.selection("EDGE", "PartSet/OZ"), 100, 0)
-Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Extrusion_1_12/To_Vertex_1"), model.selection("VERTEX", "Extrusion_1_13/To_Vertex_1"), model.selection("VERTEX", "Extrusion_1_3/To_Vertex_1"))
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Vertex_1_12/To_Vertex_1"), model.selection("VERTEX", "Vertex_1_13/To_Vertex_1"), model.selection("VERTEX", "Vertex_1_3/To_Vertex_1"))
 Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
 SketchLine_7 = Sketch_2.addLine(-717.0963364993213, -45.06817090071282, -717.0963364993213, -180.9380775505473)
-SketchPoint_13 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_12/To_Vertex_1"))
+SketchPoint_13 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_12/To_Vertex_1"))
 SketchPoint_13.setName("SketchPoint_15")
 SketchPoint_13.result().setName("SketchPoint_15")
 SketchConstraintCoincidence_19 = Sketch_2.setCoincident(SketchLine_7.startPoint(), SketchPoint_13.result())
-SketchPoint_14 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/To_Vertex_1"))
+SketchPoint_14 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_1/To_Vertex_1"))
 SketchPoint_14.setName("SketchPoint_16")
 SketchPoint_14.result().setName("SketchPoint_16")
 SketchConstraintCoincidence_20 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchPoint_14.result())
 SketchLine_8 = Sketch_2.addLine(-717.0963364993213, -180.9380775505473, -102.0809741405142, -180.9380775505473)
 SketchConstraintCoincidence_21 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
-SketchPoint_15 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_3/To_Vertex_1"))
+SketchPoint_15 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_3/To_Vertex_1"))
 SketchPoint_15.setName("SketchPoint_17")
 SketchPoint_15.result().setName("SketchPoint_17")
 SketchConstraintCoincidence_22 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchPoint_15.result())
 SketchLine_9 = Sketch_2.addLine(-102.0809741405142, -180.9380775505473, -102.0809741405142, 193.0685819822336)
 SketchConstraintCoincidence_23 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
-SketchPoint_16 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_10/To_Vertex_1"))
+SketchPoint_16 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_10/To_Vertex_1"))
 SketchPoint_16.setName("SketchPoint_18")
 SketchPoint_16.result().setName("SketchPoint_18")
 SketchConstraintCoincidence_24 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchPoint_16.result())
 SketchLine_10 = Sketch_2.addLine(-102.0809741405142, 193.0685819822336, -254.8675173043772, 193.0685819822336)
 SketchConstraintCoincidence_25 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
-SketchPoint_17 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_5/To_Vertex_1"))
+SketchPoint_17 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_5/To_Vertex_1"))
 SketchPoint_17.setName("SketchPoint_19")
 SketchPoint_17.result().setName("SketchPoint_19")
 SketchConstraintCoincidence_26 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchPoint_17.result())
 SketchLine_11 = Sketch_2.addLine(-254.8675173043772, 193.0685819822336, -254.8675173043772, -45.06817090071281)
 SketchConstraintCoincidence_27 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
-SketchPoint_18 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_9/To_Vertex_1"))
+SketchPoint_18 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_9/To_Vertex_1"))
 SketchPoint_18.setName("SketchPoint_20")
 SketchPoint_18.result().setName("SketchPoint_20")
 SketchConstraintCoincidence_28 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchPoint_18.result())
@@ -138,16 +138,16 @@ SketchConstraintCoincidence_30 = Sketch_2.setCoincident(SketchLine_7.startPoint(
 SketchConstraintCoincidence_31 = Sketch_2.setCoincident(SketchPoint_13.coordinates(), SketchLine_12.endPoint())
 SketchLine_13 = Sketch_2.addLine(-599.2405881202537, -45.06817090071282, -584.124830393487, -180.9380775505472)
 SketchConstraintCoincidence_32 = Sketch_2.setCoincident(SketchLine_13.startPoint(), SketchLine_12.result())
-SketchPoint_19 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_13/To_Vertex_1"))
+SketchPoint_19 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_13/To_Vertex_1"))
 SketchPoint_19.setName("SketchPoint_21")
 SketchPoint_19.result().setName("SketchPoint_21")
 SketchConstraintCoincidence_33 = Sketch_2.setCoincident(SketchLine_13.endPoint(), SketchPoint_19.result())
 SketchLine_14 = Sketch_2.addLine(-356.1736770691994, -45.06817090071282, -342.6051560379917, -180.9380775505472)
-SketchPoint_20 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_15/To_Vertex_1"))
+SketchPoint_20 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_15/To_Vertex_1"))
 SketchPoint_20.setName("SketchPoint_22")
 SketchPoint_20.result().setName("SketchPoint_22")
 SketchConstraintCoincidence_34 = Sketch_2.setCoincident(SketchLine_14.startPoint(), SketchPoint_20.result())
-SketchPoint_21 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_11/To_Vertex_1"))
+SketchPoint_21 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_11/To_Vertex_1"))
 SketchPoint_21.setName("SketchPoint_23")
 SketchPoint_21.result().setName("SketchPoint_23")
 SketchConstraintCoincidence_35 = Sketch_2.setCoincident(SketchLine_14.endPoint(), SketchPoint_21.result())
@@ -161,7 +161,7 @@ Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-Sketc
 Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_8f-SketchLine_12f-SketchLine_13f-SketchLine_14r")])
 Face_3 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_8f-SketchLine_9f-SketchLine_12f-SketchLine_14f-SketchLine_15r")])
 Face_4 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_9f-SketchLine_10f-SketchLine_11f-SketchLine_15f")])
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("EDGE", "Extrusion_1_1"), model.selection("EDGE", "Extrusion_1_2"), model.selection("EDGE", "Extrusion_1_3"), model.selection("EDGE", "Extrusion_1_4"), model.selection("EDGE", "Extrusion_1_5"), model.selection("EDGE", "Extrusion_1_6"), model.selection("EDGE", "Extrusion_1_7"), model.selection("EDGE", "Extrusion_1_8"), model.selection("EDGE", "Extrusion_1_9"), model.selection("EDGE", "Extrusion_1_10"), model.selection("EDGE", "Extrusion_1_11"), model.selection("EDGE", "Extrusion_1_12"), model.selection("EDGE", "Extrusion_1_13"), model.selection("EDGE", "Extrusion_1_14"), model.selection("EDGE", "Extrusion_1_15"), model.selection("EDGE", "Extrusion_1_16"), model.selection("EDGE", "Extrusion_1_17"), model.selection("EDGE", "Extrusion_1_18"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_4_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("EDGE", "Vertex_1_1"), model.selection("EDGE", "Vertex_1_2"), model.selection("EDGE", "Vertex_1_3"), model.selection("EDGE", "Vertex_1_4"), model.selection("EDGE", "Vertex_1_5"), model.selection("EDGE", "Vertex_1_6"), model.selection("EDGE", "Vertex_1_7"), model.selection("EDGE", "Vertex_1_8"), model.selection("EDGE", "Vertex_1_9"), model.selection("EDGE", "Vertex_1_10"), model.selection("EDGE", "Vertex_1_11"), model.selection("EDGE", "Vertex_1_12"), model.selection("EDGE", "Vertex_1_13"), model.selection("EDGE", "Vertex_1_14"), model.selection("EDGE", "Vertex_1_15"), model.selection("EDGE", "Vertex_1_16"), model.selection("EDGE", "Vertex_1_17"), model.selection("EDGE", "Vertex_1_18"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_4_1")])
 model.end()
 PartitionFeature = Partition_1.feature()
 assert(len(PartitionFeature.results()) == 1)
index 93272c18752581d0a4de093c5d518a8128ddfdc8..fedf186b2b0db66711ae62105d7c61b3e9e334ba 100644 (file)
@@ -181,7 +181,7 @@ Recover_1 = model.addRecover(Part_1_doc, Partition_1, [Revolution_1.result()])
 Plane_5 = model.addPlane(Part_1_doc, model.selection("EDGE", "PartSet/Axis_4"), model.selection("VERTEX", "PartSet/Point_2"), True)
 Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_2_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2")])
 Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Recover_1_1")], [model.selection("FACE", "Face_1_1")])
-Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_2_1"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_2"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_6_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_4_1"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_3"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_1_1"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_4"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_3_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_7_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_5_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Recover_1_1/Modified_Vertex_2_1"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_2"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_6_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_4_1"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_3"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_1_1"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_4"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_3_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_7_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_5_1")])
 Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Intersection_1_1_7"), model.selection("EDGE", "Intersection_1_1_6"), model.selection("EDGE", "Intersection_1_1_3"), model.selection("EDGE", "Intersection_1_1_11"), model.selection("EDGE", "Intersection_1_1_5"), model.selection("EDGE", "Intersection_1_1_1"), model.selection("EDGE", "Intersection_1_1_4"), model.selection("EDGE", "Intersection_1_1_2"), model.selection("EDGE", "Intersection_1_1_10"), model.selection("EDGE", "Intersection_1_1_9"), model.selection("EDGE", "Intersection_1_1_8")])
 model.end()
 
index d025a0785c569201a8cd6a0b02a8351136881594..8ac55527ffb0473eb98c92e906e3242153f15dd9 100644 (file)
@@ -55,7 +55,7 @@ SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
 model.do()
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_8f")], model.selection(), 10, 110)
 Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
-Rotation_1 = model.addRotation(Part_1_doc, [model.selection("COMPOUND", "Intersection_1_1")], model.selection("EDGE", "PartSet/OZ"), 45)
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("COMPOUND", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OZ"), 45)
 model.end()
 
 assert(model.checkPythonDump())
index 8a98df7e97ba911ace53474ea0d8a316dee7599d..6d1aca8b6fa4c1c39e427e7381763b7e333151e0 100644 (file)
@@ -40,9 +40,9 @@ model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_5r")], model.selection(), 100, 0)
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f")], model.selection(), 100, 0)
 Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
-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")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1")])
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OZ"), 50)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Translated_Face_24"), model.selection("FACE", "Extrusion_1_1/Translated_Face_13"), model.selection("FACE", "Extrusion_1_1/Translated_Face_16"), model.selection("FACE", "Extrusion_1_1/Translated_Face_12"), model.selection("FACE", "Extrusion_1_1/Translated_Face_9"), model.selection("FACE", "Extrusion_1_1/Translated_Face_10"), model.selection("FACE", "Extrusion_1_1/Translated_Face_11"), model.selection("FACE", "Extrusion_1_1/Translated_Face_25"), model.selection("FACE", "Extrusion_1_1/Translated_Face_20"), model.selection("FACE", "Extrusion_1_1/Translated_Face_19"), model.selection("FACE", "Extrusion_1_1/Translated_Face_18"), model.selection("FACE", "Extrusion_1_1/Translated_Face_27"), model.selection("FACE", "Extrusion_1_1/Translated_Face_17"), model.selection("FACE", "Extrusion_1_1/Translated_Face_31"), model.selection("FACE", "Extrusion_1_1/Translated_Face_32"), model.selection("FACE", "Extrusion_1_1/Translated_Face_30"), model.selection("FACE", "Extrusion_1_1/Translated_Face_28"), model.selection("FACE", "Extrusion_1_1/Translated_Face_29"), model.selection("FACE", "Extrusion_1_1/Translated_Face_8"), model.selection("FACE", "Extrusion_1_1/Translated_Face_22"), model.selection("FACE", "Extrusion_1_1/Translated_Face_7"), model.selection("FACE", "Extrusion_1_1/Translated_Face_6"), model.selection("FACE", "Extrusion_1_1/Translated_Face_5"), model.selection("FACE", "Extrusion_1_1/Translated_Face_3"), model.selection("FACE", "Extrusion_1_1/Translated_Face_1"), model.selection("FACE", "Extrusion_1_1/Translated_Face_2"), model.selection("FACE", "Extrusion_1_1/Translated_Face_21"), model.selection("FACE", "Extrusion_1_1/Translated_Face_4"), model.selection("FACE", "Extrusion_1_1/Translated_Face_25"), model.selection("FACE", "Extrusion_1_1/Translated_Face_27"), model.selection("FACE", "Extrusion_1_1/Translated_Face_21"), model.selection("FACE", "Extrusion_1_1/Translated_Face_22"), model.selection("FACE", "Extrusion_1_1/Translated_Face_26"), model.selection("FACE", "Extrusion_1_1/Translated_Face_23"), model.selection("FACE", "Extrusion_1_1/Translated_Face_30"), model.selection("FACE", "Extrusion_1_1/Translated_Face_23"), model.selection("FACE", "Extrusion_1_1/Translated_Face_14"), model.selection("FACE", "Extrusion_1_1/Translated_Face_15")])
 #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()
index 72c1b77f1298b988b0dac10bd0ad60e4e2d47378..ef5cdc48eb916dd4fc36c8a606610c55944d3fd3 100644 (file)
@@ -33,7 +33,7 @@ Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
 Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_3")])
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 100, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Wire_1_1/Generated_Face_3"), model.selection("FACE", "Wire_1_1/Generated_Face_2"), model.selection("FACE", "Wire_1_1/Generated_Face_1")])
 model.do()
 model.end()
 
index 0fd8972afe8e1e90847cd185387af26e1728219f..855ae61e1abf747502e96142b3db086f1f85b7ea 100644 (file)
@@ -34,7 +34,7 @@ SketchCircle_3 = Sketch_2.addCircle(-41.97827733564338, 89.35676702647821, 6.102
 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")])
+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()
 
index c32cd440b1ae8ed65e5f405a3d8a6f348eb7dc46..54e1020c31fa4780b9978153f57762b38512ff70 100644 (file)
@@ -29,9 +29,9 @@ 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")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Base_Edge_1")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Lateral_Edge_1")])
+Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Face_1_1/Lateral_Edge_1&Face_1_1/Base_Edge_1")])
 model.end()
 
 # check that resulting group selection is valid
index e07e3e154ee3f87c02f12aff1b7b1411e29b7a7a..6ce089431641e386e80f32c1eaaecae588be27e1 100644 (file)
@@ -36,7 +36,7 @@ SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(),
 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")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_3"), 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
index 9ebe471a7456f689f499c2a5612d1e081190825c..d68bbf00c05ec1336ae72d513fbaf97c13d6e57f 100644 (file)
@@ -52,7 +52,7 @@ SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.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")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Generated_Face_5&Revolution_1_1/Generated_Face_4"), model.selection("EDGE", "Revolution_1_1/Generated_Face_4&Revolution_1_1/Generated_Face_3"), 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_4"), model.selection("EDGE", "Revolution_1_1/Generated_Face_3")])
 model.end()
 
 # check that resulting group selection is valid
index 5317ea29b425ba88ba9c1d704b8619285afc9b17..bab4cc8ba57f36153a915d809d509ffe1375a3a5 100644 (file)
@@ -106,7 +106,7 @@ 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"))
+SketchPoint_1 = Sketch_3.addPoint(model.selection("VERTEX", "Partition_1_1_1/Modified_Edge_15_15&Partition_1_1_1/Modified_Edge_15_16"))
 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)
@@ -129,17 +129,21 @@ Face_5 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-Sketc
 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"))
+Translation_1.result().setName("Translation_1_1")
 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"))
+Translation_2.result().setName("Translation_2_1")
 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"))
+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", "Translation_2_1/Translated_Edge_1_4&Translation_2_1/Translated_Edge_1_1"))
+Translation_3.result().setName("Translation_3_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"))
+Translation_4.result().setName("Translation_4_1")
 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")])
+Partition_2 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "Face_1_1"), model.selection("COMPOUND", "Face_5_1"), model.selection("COMPOUND", "Translation_1_1"), model.selection("COMPOUND", "Translation_2_1"), model.selection("COMPOUND", "Translation_3_1"), model.selection("COMPOUND", "Translation_4_1")])
 model.end()
 
 # check that partition constructed correctly
index c178e45ab6e5a74c8f21cb6c301ca77285661698..be0c82b1dae52502a740d1952bff408aa2d5d6c0 100644 (file)
@@ -39,7 +39,7 @@ SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.startPoint(),
 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")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Revolution_1_1/Translated_Vertex_1"), model.selection("VERTEX", "Revolution_1_1/Translated_Vertex_2")])
 model.end()
 
 # check that resulting group selection is valid, names exist and different
index 89f15dd57e38564aa82aab891e05d74fbf80111b..20e48f5b9a5f339618c0318eef7cf59d027fd460 100644 (file)
@@ -48,7 +48,7 @@ SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_3.result(), SketchArc
 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")])
+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_7&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_7"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&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
index 92193a3a5dc60c0862c855a8e02c4426fa96859c..6312d5989862ab61ad062469593e83d70e2adfaf 100644 (file)
@@ -46,7 +46,7 @@ Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-Sketc
 Wire_2 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
 Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Wire_1_1")])
 Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Wire_2_1")])
-Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")], model.selection(), 50, 0)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Wire_1_1"), model.selection("FACE", "Wire_2_1")], model.selection(), 50, 0)
 Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
 SketchLine_5 = Sketch_2.addLine(49.62901186301215, 25.3130971701971, 39.15939470736273, 25.3130971701971)
 SketchLine_6 = Sketch_2.addLine(39.15939470736273, 25.3130971701971, 39.15939470736273, 38.96586914453801)
@@ -61,7 +61,7 @@ SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_6.result())
 SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_7.result())
 SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
 model.do()
-ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")], model.selection(), 50, 50, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")], model.selection(), 50, 50, [model.selection("SOLID", "Wire_1_1"), model.selection("SOLID", "Wire_2_1")])
 model.do()
 model.end()
 
diff --git a/src/FeaturesPlugin/Test/Test2289.py b/src/FeaturesPlugin/Test/Test2289.py
new file mode 100644 (file)
index 0000000..7597676
--- /dev/null
@@ -0,0 +1,56 @@
+## 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(55.30809111108014, 52.50335568234566, -47.4076783683968, 52.50335568234566)
+SketchLine_2 = Sketch_1.addLine(-47.4076783683968, 52.50335568234566, -77.7205049049542, 0)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-77.7205049049542, 0, -47.4076783683968, -52.50335568234565)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(-47.4076783683968, -52.50335568234565, 55.30809111108014, -52.50335568234565)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(55.30809111108014, -52.50335568234565, 55.30809111108014, 52.50335568234566)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_5.result())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_6 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.result(), SketchLine_3.startPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngleBackward(SketchLine_2.result(), SketchLine_3.result(), 120)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_2.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_4.result())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 10, 0)
+model.do()
+
+model.testHaveNamingVertices(Extrusion_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/Test/Test2304.py b/src/FeaturesPlugin/Test/Test2304.py
new file mode 100644 (file)
index 0000000..cd9c8d6
--- /dev/null
@@ -0,0 +1,69 @@
+## 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(64.44596912521442, 49.72041166380789, -52.66552315608919, 49.72041166380789)
+SketchLine_2 = Sketch_1.addLine(-52.66552315608919, 49.72041166380789, -52.66552315608919, -67.3910806174957)
+SketchLine_3 = Sketch_1.addLine(-52.66552315608919, -67.3910806174957, 64.44596912521442, -67.3910806174957)
+SketchLine_4 = Sketch_1.addLine(64.44596912521442, -67.3910806174957, 64.44596912521442, 49.72041166380789)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(34.99485420240136, 11.60720411663807, -11.7804459691252, 11.60720411663807)
+SketchLine_6 = Sketch_1.addLine(-11.7804459691252, 11.60720411663807, -11.7804459691252, -33.78216123499142)
+SketchLine_7 = Sketch_1.addLine(-11.7804459691252, -33.78216123499142, 34.99485420240136, -33.78216123499142)
+SketchLine_8 = Sketch_1.addLine(34.99485420240136, -33.78216123499142, 34.99485420240136, 11.60720411663807)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_8.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_8f")], model.selection(), 100, 100)
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("FACE", "Face_1_1")])
+model.do()
+model.end()
+
+from GeomAPI import  GeomAPI_Shape
+
+model.testNbResults(Partition_1, 1)
+model.testNbSubResults(Partition_1, [2])
+model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [13])
+model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [56])
+model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [112])
+model.testResultsVolumes(Partition_1, [424620.237783511402085423469543457])
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/Test/TestBooleanFillWithPlane.py b/src/FeaturesPlugin/Test/TestBooleanFillWithPlane.py
new file mode 100644 (file)
index 0000000..dbc2670
--- /dev/null
@@ -0,0 +1,69 @@
+## 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(50.45430931454487, 141.3050678403047, -211.8625790259634, 141.3050678403047)
+SketchLine_2 = Sketch_1.addLine(-211.8625790259634, 141.3050678403047, -211.8625790259634, -163.3288837233227)
+SketchLine_3 = Sketch_1.addLine(-211.8625790259634, -163.3288837233227, 50.45430931454487, -163.3288837233227)
+SketchLine_4 = Sketch_1.addLine(50.45430931454487, -163.3288837233227, 50.45430931454487, 141.3050678403047)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(246.5736143115653, 48.78197815871301, -51.09047583637312, 48.78197815871301)
+SketchLine_6 = Sketch_1.addLine(-51.09047583637312, 48.78197815871301, -51.09047583637312, -104.8260668928192)
+SketchLine_7 = Sketch_1.addLine(-51.09047583637312, -104.8260668928192, 246.5736143115653, -104.8260668928192)
+SketchLine_8 = Sketch_1.addLine(246.5736143115653, -104.8260668928192, 246.5736143115653, 48.78197815871301)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_8.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 100, 0)
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1_2")], [model.selection("FACE", "PartSet/YOZ")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Boolean_1_1_4/Modified_3"), model.selection("FACE", "Boolean_1_1_4/Modified_Face_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_9"), model.selection("FACE", "Boolean_1_1_4/Modified_2"), model.selection("FACE", "Boolean_1_1_4/Modified_4"), model.selection("FACE", "Boolean_1_1_4/Modified_1"), model.selection("FACE", "Boolean_1_1_4/Modified_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_6"), model.selection("FACE", "Boolean_1_1_3/Modified_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_7"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_9"), model.selection("FACE", "Boolean_1_1_1/Modified_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_5"), model.selection("FACE", "Boolean_1_1_4/Modified_4"), model.selection("FACE", "Boolean_1_1_1/Modified_2"), model.selection("FACE", "Boolean_1_1_3/Modified_4"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_12"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_11"), model.selection("FACE", "Boolean_1_1_3/Modified_3"), model.selection("FACE", "Boolean_1_1_3/Modified_2"), model.selection("FACE", "Boolean_1_1_3/Modified_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_4"), model.selection("FACE", "Boolean_1_1_3/Modified_4"), model.selection("FACE", "Boolean_1_1_4/Modified_Face_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_4"), model.selection("FACE", "_Extrusion_1_1/To_Face_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_2"), model.selection("FACE", "_Extrusion_1_1/From_Face_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_1")])
+model.do()
+model.end()
+
+from GeomAPI import  GeomAPI_Shape
+
+model.testNbResults(Boolean_1, 1)
+model.testNbSubResults(Boolean_1, [4])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.SOLID, [4])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.FACE, [30])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.EDGE, [132])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.VERTEX, [264])
+model.testResultsVolumes(Boolean_1, [11003613.329450136050581932067871094])
+
+assert(model.checkPythonDump())
index 4d3daea4479f0bff6399c6796b338396d77185b6..5e44cac127913e038df1dc283cb72ffa9e22fb89 100644 (file)
@@ -250,9 +250,9 @@ anExtrusionFt.selectionList("base").append(
 anExtrusionFt.string("CreationMethod").setValue("ByPlanesAndOffsets")
 anExtrusionFt.real("to_size").setValue(0) #TODO: remove
 anExtrusionFt.real("from_size").setValue(0) #TODO: remove
-anExtrusionFt.selection("to_object").selectSubShape("face", "Extrusion_3_1/Generated_Face_2")
+anExtrusionFt.selection("to_object").selectSubShape("face", "Extrusion_3_1/Generated_Face_3")
 anExtrusionFt.real("to_offset").setValue(0)
-anExtrusionFt.selection("from_object").selectSubShape("face", "Extrusion_3_1/Generated_Face_1")
+anExtrusionFt.selection("from_object").selectSubShape("face", "Extrusion_3_1/Generated_Face_4")
 anExtrusionFt.real("from_offset").setValue(0)
 anExtrusionFt.execute()
 aSession.finishOperation()
diff --git a/src/FeaturesPlugin/Test/TestFillet.py b/src/FeaturesPlugin/Test/TestFillet.py
new file mode 100644 (file)
index 0000000..49831b3
--- /dev/null
@@ -0,0 +1,134 @@
+## Copyright (C) 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>
+##
+
+"""
+      TestFillet.py
+      Unit test of FeaturesPlugin_Fillet class
+"""
+
+from ModelAPI import *
+
+__updated__ = "2017-11-30"
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+# Create a part for extrusion
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+aPart = aSession.activeDocument()
+
+# Create a box and a cylinder for filleting
+aSession.startOperation()
+aBox = aPart.addFeature("Box")
+aBox.string("CreationMethod").setValue("BoxByDimensions")
+aBox.real("dx").setValue(10)
+aBox.real("dy").setValue(10)
+aBox.real("dz").setValue(10)
+aSession.finishOperation()
+
+# a point to anchor a cylinder
+aSession.startOperation()
+aPoint = aPart.addFeature("Point")
+aPoint.string("creation_method").setValue("by_xyz")
+aPoint.real("x").setValue(20)
+aPoint.real("y").setValue(5)
+aPoint.real("z").setValue(0)
+aSession.finishOperation()
+
+aSession.startOperation()
+aCylinder = aPart.addFeature("Cylinder")
+aCylinder.string("CreationMethod").setValue("Cylinder")
+aCylinder.selection("base_point").selectSubShape("vertex", "Point_1")
+aCylinder.selection("axis").selectSubShape("edge", "PartSet/OZ")
+aCylinder.real("radius").setValue(5)
+aCylinder.real("height").setValue(10)
+aSession.finishOperation()
+
+#=========================================================================
+# Test 1. Create fillet with fixed radius
+#=========================================================================
+aSession.startOperation()
+aFillet1 = aPart.addFeature("Fillet")
+aFillet1.string("creation_method").setValue("fixed_radius")
+anObjects = aFillet1.selectionList("main_objects")
+anObjects.append("Box_1_1/Left&Box_1_1/Top", "edge")
+aFillet1.real("radius1").setValue(3)
+aSession.finishOperation()
+assert(aFillet1.error() == ""), "FAILED: Fillet reports error \"{}\"".format(aFillet1.error())
+
+#=========================================================================
+# Test 2. Change fillet type
+#=========================================================================
+aSession.startOperation()
+aFillet1.string("creation_method").setValue("variable_radius")
+aFillet1.real("radius1").setValue(5)
+aFillet1.real("radius2").setValue(1)
+aSession.finishOperation()
+assert(aFillet1.error() == ""), "FAILED: Fillet reports error \"{}\"".format(aFillet1.error())
+
+#=========================================================================
+# Test 3. Check fillet reports error if selected entities from different solids
+#=========================================================================
+aSession.startOperation()
+aFillet2 = aPart.addFeature("Fillet")
+aFillet2.string("creation_method").setValue("fixed_radius")
+anObjects = aFillet2.selectionList("main_objects")
+anObjects.append("Cylinder_1_1/Face_2", "face")
+anObjects.append("_Box_1_1/Right", "face")
+aFillet2.real("radius1").setValue(2)
+aSession.finishOperation()
+assert(aFillet2.error() != ""), "FAILED: Fillet does not report error"
+
+#=========================================================================
+# Test 4. Fix the error
+#=========================================================================
+aSession.startOperation()
+anObjects.removeLast()
+aSession.finishOperation()
+assert(aFillet2.error() == ""), "FAILED: Fillet reports error \"{}\"".format(aFillet1.error())
+
+#=========================================================================
+# Test 5. Check fillet reports error on smoothly connected edges
+#=========================================================================
+aSession.startOperation()
+aFillet3 = aPart.addFeature("Fillet")
+aFillet3.string("creation_method").setValue("fixed_radius")
+aFillet3.selectionList("main_objects").append("Cylinder_1_1/Modified_Face_1", "face")
+aFillet3.real("radius1").setValue(3)
+aSession.finishOperation()
+assert(aFillet3.lastResult() is None), "FAILED: Fillet should not produce a result"
+
+#=========================================================================
+# Test 6. Remove last fillet feature
+#=========================================================================
+aSession.startOperation()
+aPart.removeFeature(aFillet3)
+aSession.finishOperation()
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+from salome.shaper import model
+assert(model.checkPythonDump())
index bc9f7cf52e458984ff4c451424dd663db89f2d75..f805375d5fbb98c6f7f407f199d466943f90f5f4 100644 (file)
@@ -121,11 +121,20 @@ aSession.finishOperation()
 assert (len(aPipeFeature.results()) > 0)
 # aSession.undo()
 
+# Recover original face
+aSession.startOperation()
+aRecover = aPart.addFeature("Recover")
+aBaseObject = aRecover.reference("base_feature")
+aBaseObject.setValue(aPipeFeature)
+aRecoveredObjects = aRecover.reflist("recovered")
+aRecoveredObjects.append(aFaceResult1)
+aSession.finishOperation()
+
 # Create pipe with bi-normal
 aSession.startOperation()
 aPipeFeature = aPart.addFeature("Pipe")
 aBaseObjectsList = aPipeFeature.selectionList("base_objects")
-aBaseObjectsList.append(aFaceResult1, None)
+aBaseObjectsList.append(aRecover.firstResult(), None)
 aPathObjectSelection = aPipeFeature.selection("path_object")
 aPathObjectSelection.setValue(aWireResult, None)
 aPipeFeature.string("creation_method").setValue("binormal")
@@ -138,6 +147,15 @@ aSession.finishOperation()
 assert (len(aPipeFeature.results()) > 0)
 # aSession.undo()
 
+# Recover original face
+aSession.startOperation()
+aRecover2 = aPart.addFeature("Recover")
+aBaseObject = aRecover2.reference("base_feature")
+aBaseObject.setValue(aPipeFeature)
+aRecoveredObjects = aRecover2.reflist("recovered")
+aRecoveredObjects.append(aRecover.firstResult())
+aSession.finishOperation()
+
 # Create pipe with locations
 # Create a sketch with circle for pipe profile
 aSession.startOperation()
@@ -173,7 +191,7 @@ aFaceResult2 = aFaceFeature.firstResult()
 aSession.startOperation()
 aPipeFeature = aPart.addFeature("Pipe")
 aBaseObjectsList = aPipeFeature.selectionList("base_objects")
-aBaseObjectsList.append(aFaceResult1, None)
+aBaseObjectsList.append(aRecover2.firstResult(), None)
 aBaseObjectsList.append(aFaceResult2, None)
 aPathObjectSelection = aPipeFeature.selection("path_object")
 aPathObjectSelection.setValue(aWireResult, None)
index ae497c06392e9f3f04a0426eb4d24d303581f7a2..1adcbd13e30df69ed0f45b9d1042d05d31598811 100644 (file)
@@ -206,7 +206,7 @@ SketchConstraintRadius_4 = Sketch_2.setRadius(SketchArc_1.results()[1], 10)
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_24f-SketchLine_28f-SketchLine_26f-SketchLine_27f-SketchArc_1_2f-SketchArc_2_2f-SketchArc_3_2f-SketchArc_4_2f")], model.selection(), model.selection("FACE", "Revolution_1_1/To_Face_1"), -30, model.selection(), 0)
 Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "Extrusion_1_1/From_Face_1&Extrusion_1_1/Generated_Face_8"), "inclinaison")
-Rotation_2 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Rotation_1_1")], model.selection("EDGE", "PartSet/OZ"), "angle1")
+Rotation_2 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OZ"), "angle1")
 Recover_1 = model.addRecover(Part_1_doc, Rotation_2, [Rotation_1.result()])
 Rotation_3 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_1_1")], model.selection("EDGE", "PartSet/OZ"), "angle2")
 Rotation_3.setName("Rotation_4")
@@ -219,7 +219,7 @@ Recover_3 = model.addRecover(Part_1_doc, Rotation_2, [Rotation_1.result()])
 Rotation_5 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_3_1")], model.selection("EDGE", "PartSet/OZ"), "-angle1")
 Rotation_5.setName("Rotation_6")
 Rotation_5.result().setName("Rotation_6_1")
-Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], [model.selection("SOLID", "Rotation_4_1"), model.selection("SOLID", "Rotation_2_1"), model.selection("SOLID", "Rotation_6_1"), model.selection("SOLID", "Rotation_5_1")])
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], [model.selection("SOLID", "Rotation_4_1"), model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Rotation_6_1"), model.selection("SOLID", "Rotation_5_1")])
 model.end()
 
 assert(Boolean_1.result().shapeType() == 'SOLID')
index a94dcee60183a4777fe746df64206e78de3513ff..9a10cfab5d2b3a8fdf17d678fb9761f628e893a1 100644 (file)
@@ -87,7 +87,8 @@ anExtrusionResult = modelAPI_ResultCompSolid(modelAPI_ResultBody(anExtrusionFeat
 aSession.startOperation()
 aRemoveSubShapesFeature = aPart.addFeature("Remove_SubShapes")
 aRemoveSubShapesFeature.selection("base_shape").setValue(anExtrusionResult, None)
-aRemoveSubShapesFeature.selectionList("subshapes").removeLast();
+aRemoveSubShapesFeature.string("creation_method").setValue("by_keep_subshapes")
+aRemoveSubShapesFeature.selectionList("subshapes_to_keep").removeLast();
 aSession.finishOperation()
 assert (len(aRemoveSubShapesFeature.results()) > 0)
 anUnionResult = modelAPI_ResultCompSolid(modelAPI_ResultBody(aRemoveSubShapesFeature.firstResult()))
diff --git a/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py b/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py
new file mode 100644 (file)
index 0000000..f630056
--- /dev/null
@@ -0,0 +1,47 @@
+## 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"))
+SketchCircle_1 = Sketch_1.addCircle(-38.80617495711836, 0.1732418524871273, 42.63017006028262)
+SketchCircle_2 = Sketch_1.addCircle(-117.8044596912521, -0.1732418524871385, 54.50817511994374)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Extrusion_1_1"))
+Remove_SubShapes_1.setSubShapesToRemove([model.selection("SOLID", "Extrusion_1_1_3")])
+model.do()
+model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Remove_SubShapes_1, 1)
+model.testNbSubResults(Remove_SubShapes_1, [2])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.FACE, [10])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.EDGE, [36])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.VERTEX, [72])
+model.testResultsVolumes(Remove_SubShapes_1, [136619.795923917088657617568969727])
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/Test/TestUnionFaces.py b/src/FeaturesPlugin/Test/TestUnionFaces.py
new file mode 100644 (file)
index 0000000..3bbd55f
--- /dev/null
@@ -0,0 +1,45 @@
+## 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"))
+SketchCircle_1 = Sketch_1.addCircle(-5.197255574614073, 0.1732418524871273, 67.586529314451)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "PartSet/YOZ"), model.selection("FACE", "PartSet/XOZ")])
+Union_1 = model.addUnion(Part_1_doc, [model.selection("FACE", "Partition_1_1_3"), model.selection("FACE", "Partition_1_1_4")])
+model.do()
+model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Union_1, 1)
+model.testNbSubResults(Union_1, [3])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.FACE, [3])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.EDGE, [10])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.VERTEX, [20])
+
+assert(model.checkPythonDump())
index a5c4e919502f7e567b52fe6a6fe68be3c39914e9..015c1d0e5ecf409bcd4ed3915749fcdbdb73aca3 100644 (file)
@@ -34,7 +34,7 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     label="Main objects"
     icon=""
     tooltip="Select objects"
-    type_choice="solids compsolids edges faces"
+    type_choice="vertices edges wires faces shells solids compsolids"
     use_choice="false"
     concealment="true">
     <validator id="PartSet_DifferentObjects"/>
@@ -44,7 +44,7 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     label="Tool objects"
     icon=""
     tooltip="Select tools"
-    type_choice="solids compsolids edges faces"
+    type_choice="vertices edges wires faces shells solids compsolids"
     use_choice="false"
     concealment="true" >
     <validator id="PartSet_DifferentObjects"/>
index 95f86e25a4e8ef46dd0e8a93e6f2837cb647a871..b176ddc1812e8050c855c02a8569abd097c22aca 100755 (executable)
@@ -109,7 +109,8 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     tooltip="Objects to Cut"
     type_choice="Objects"
     use_choice="false"
-    concealment="true">
+    concealment="true"
+    main_argument="true">
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </multi_selector>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,sketch_selection,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
index 7cde0f50d7d0e858a827ef0da977963f88187b80..e65b6b4af990bcdcb52914206dae5522a2fd9ade 100644 (file)
@@ -109,7 +109,8 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     tooltip="Objects to Fuse"
     type_choice="Objects"
     use_choice="false"
-    concealment="true">
+    concealment="true"
+    main_argument="true">
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </multi_selector>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,sketch_selection,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
diff --git a/src/FeaturesPlugin/fillet_widget.xml b/src/FeaturesPlugin/fillet_widget.xml
new file mode 100644 (file)
index 0000000..1ccb5bc
--- /dev/null
@@ -0,0 +1,76 @@
+<!--
+Copyright (C) 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>
+-->
+
+<source>
+  <toolbox id="creation_method">
+    <box id="fixed_radius"
+         title="Fixed radius"
+         tooltip="Fillet with fixed radius"
+         icon="icons/Features/fillet_fixed_radius.png">
+      <multi_selector id="main_objects"
+                      label="Faces or/and edges"
+                      icon=""
+                      tooltip="Select objects"
+                      type_choice="edges faces"
+                      use_choice="false"
+                      concealment="true">
+        <validator id="PartSet_DifferentObjects"/>
+        <validator id="FeaturesPlugin_ValidatorFilletSelection"/>
+      </multi_selector>
+      <doublevalue id="radius1"
+                   label="Radius"
+                   tooltip="Fillet radius."
+                   min="0"
+                   default="2">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+    </box>
+    <box id="variable_radius"
+         title="Varying radius"
+         tooltip="Fillet with varying radius"
+         icon="icons/Features/fillet_var_radius.png">
+      <multi_selector id="main_objects"
+                      label="Faces or/and edges"
+                      icon=""
+                      tooltip="Select objects"
+                      type_choice="edges faces"
+                      use_choice="false"
+                      concealment="true">
+        <validator id="PartSet_DifferentObjects"/>
+        <validator id="FeaturesPlugin_ValidatorFilletSelection"/>
+      </multi_selector>
+      <doublevalue id="radius1"
+                   label="Start radius"
+                   tooltip="Fillet radius at start point."
+                   min="0"
+                   default="2">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+      <doublevalue id="radius2"
+                   label="End radius"
+                   tooltip="Fillet radius at end point."
+                   min="0"
+                   default="2">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+    </box>
+  </toolbox>
+</source>
diff --git a/src/FeaturesPlugin/icons/fillet.png b/src/FeaturesPlugin/icons/fillet.png
new file mode 100644 (file)
index 0000000..3b5a982
Binary files /dev/null and b/src/FeaturesPlugin/icons/fillet.png differ
diff --git a/src/FeaturesPlugin/icons/fillet_fixed_radius.png b/src/FeaturesPlugin/icons/fillet_fixed_radius.png
new file mode 100644 (file)
index 0000000..0897bde
Binary files /dev/null and b/src/FeaturesPlugin/icons/fillet_fixed_radius.png differ
diff --git a/src/FeaturesPlugin/icons/fillet_var_radius.png b/src/FeaturesPlugin/icons/fillet_var_radius.png
new file mode 100644 (file)
index 0000000..56e4a78
Binary files /dev/null and b/src/FeaturesPlugin/icons/fillet_var_radius.png differ
diff --git a/src/FeaturesPlugin/icons/keep_subshapes_32x32.png b/src/FeaturesPlugin/icons/keep_subshapes_32x32.png
new file mode 100644 (file)
index 0000000..45319eb
Binary files /dev/null and b/src/FeaturesPlugin/icons/keep_subshapes_32x32.png differ
diff --git a/src/FeaturesPlugin/icons/remove_subshapes_32x32.png b/src/FeaturesPlugin/icons/remove_subshapes_32x32.png
new file mode 100644 (file)
index 0000000..094f6d4
Binary files /dev/null and b/src/FeaturesPlugin/icons/remove_subshapes_32x32.png differ
index 298723427364fc02046e55c5d8f173c59e17625d..171d8acb84c66f086b1300720bf00454cc277821 100644 (file)
@@ -80,6 +80,11 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
         <source path="recover_widget.xml"/>
       </feature>
     </group>
+    <group id="Fillet">
+      <feature id="Fillet" title="Fillet" tooltip="Perform fillet on face or edge" icon="icons/Features/fillet.png" auto_preview="true">
+        <source path="fillet_widget.xml"/>
+      </feature>
+    </group>
   </workbench>
   <workbench id="Part">
     <group id="Movement">
index 353881c4554a970d05053b9dfe1498f76634b6f5..92cb0aab07e22f78261d5b8a9d6da33ec3ca9a2a 100644 (file)
@@ -29,12 +29,29 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     <validator id="GeomValidators_ShapeType" parameters="wire,shell,compsolid,compound"/>
     <validator id="GeomValidators_BodyShapes" parameters="toplevel"/>
   </shape_selector>
-  <multi_selector id="subshapes"
-                  label="Sub-Shapes to keep:"
-                  tooltip="Select shapes to keep."
-                  type_choice="vertices edges wires faces shells solids compsolids compounds"
-                  clear_in_neutral_point="false">
-    <validator id="FeaturesPlugin_ValidatorRemoveSubShapesSelection"/>
-  </multi_selector>
+  <toolbox id="creation_method">
+    <box id="by_remove_subshapes"
+     title="By removing sub-shapes"
+     icon="icons/Features/remove_subshapes_32x32.png">
+      <multi_selector id="subshapes_to_remove"
+                label="Sub-Shapes to remove:"
+                tooltip="Select shapes to remove."
+                type_choice="vertices edges wires faces shells solids compsolids compounds"
+                clear_in_neutral_point="false">
+        <validator id="FeaturesPlugin_ValidatorRemoveSubShapesSelection"/>
+      </multi_selector>
+    </box>
+    <box id="by_keep_subshapes"
+     title="By keeping sub-shapes"
+     icon="icons/Features/keep_subshapes_32x32.png">
+      <multi_selector id="subshapes_to_keep"
+                label="Sub-Shapes to keep:"
+                tooltip="Select shapes to keep."
+                type_choice="vertices edges wires faces shells solids compsolids compounds"
+                clear_in_neutral_point="false">
+        <validator id="FeaturesPlugin_ValidatorRemoveSubShapesSelection"/>
+      </multi_selector>
+    </box>
+  </toolbox>
   <validator id="FeaturesPlugin_ValidatorRemoveSubShapesResult"/>
 </source>
index 3b69da1580585832afe16f4d2e5ff2764008cc1d..12f2f247f45e509048e9dd951573275a38668bfa 100644 (file)
@@ -109,7 +109,8 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     tooltip="Objects to Cut"
     type_choice="Objects"
     use_choice="false"
-    concealment="true">
+    concealment="true"
+    main_argument="true">
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </multi_selector>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,ByAngles,sketch_selection,to_angle,from_angle,to_object,to_offset,from_object,from_offset"/>
index 26a02d72eae6f655a20970854e51ad498bd08340..6d1bb83945ef55b9e1a08688f8ea6173cb2ae147 100644 (file)
@@ -109,7 +109,8 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     tooltip="Objects to Fuse"
     type_choice="Objects"
     use_choice="false"
-    concealment="true">
+    concealment="true"
+    main_argument="true">
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </multi_selector>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,ByAngles,sketch_selection,to_angle,from_angle,to_object,to_offset,from_object,from_offset"/>
index 1de6e9a6ea243d82ed5026a01d94c50fdd2c5050..2d14a54bd2515186a1ed85813ce7a01d0f8b7bdd 100644 (file)
@@ -23,7 +23,7 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
   <multi_selector id="base_objects"
     label="Base objects:"
     tooltip="Select solids for union."
-    type_choice="solids compsolids"
+    type_choice="faces solids compsolids"
     use_choice="false"
     concealment="true">
     <validator id="FeaturesPlugin_ValidatorUnionSelection"/>
index 205d9ddf5fc2cb5800c7d9d41805b0186ab6783b..6654525fa428de3ea445f9bb6f510c47111336d9 100644 (file)
@@ -23,10 +23,12 @@ INCLUDE(Common)
 SET(PROJECT_HEADERS
   GDMLAPI.h
   GDMLAPI_ConeSegment.h
+  GDMLAPI_Ellipsoid.h
 )
 
 SET(PROJECT_SOURCES
   GDMLAPI_ConeSegment.cpp
+  GDMLAPI_Ellipsoid.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 82eb12a37a5b8a8c1f8c3c7fd67181b7330987d5..25516108d34d1ddb4ce0bfb962d969306884fca2 100644 (file)
@@ -45,7 +45,8 @@
 
 // shared pointers
 %shared_ptr(GDMLAPI_ConeSegment)
+%shared_ptr(GDMLAPI_Ellipsoid)
 
 // all supported interfaces
 %include "GDMLAPI_ConeSegment.h"
-
+%include "GDMLAPI_Ellipsoid.h"
diff --git a/src/GDMLAPI/GDMLAPI_Ellipsoid.cpp b/src/GDMLAPI/GDMLAPI_Ellipsoid.cpp
new file mode 100644 (file)
index 0000000..385b5de
--- /dev/null
@@ -0,0 +1,144 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GDMLAPI_Ellipsoid.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+GDMLAPI_Ellipsoid::GDMLAPI_Ellipsoid(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+  : ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+GDMLAPI_Ellipsoid::GDMLAPI_Ellipsoid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const ModelHighAPI_Double& theAX,
+                                     const ModelHighAPI_Double& theBY,
+                                     const ModelHighAPI_Double& theCZ)
+  : ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    setSizes(theAX, theBY, theCZ);
+    fillAttribute("", useZCut1());
+    fillAttribute("", useZCut1());
+  }
+}
+
+GDMLAPI_Ellipsoid::GDMLAPI_Ellipsoid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const ModelHighAPI_Double& theAX,
+                                     const ModelHighAPI_Double& theBY,
+                                     const ModelHighAPI_Double& theCZ,
+                                     const ModelHighAPI_Double& theZCut1,
+                                     const ModelHighAPI_Double& theZCut2)
+  : ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    setSizes(theAX, theBY, theCZ);
+    setZCut1(theZCut1);
+    setZCut2(theZCut2);
+  }
+}
+
+GDMLAPI_Ellipsoid::~GDMLAPI_Ellipsoid()
+{
+}
+
+void GDMLAPI_Ellipsoid::setSizes(const ModelHighAPI_Double& theAX,
+                                 const ModelHighAPI_Double& theBY,
+                                 const ModelHighAPI_Double& theCZ)
+{
+  fillAttribute(theAX, ax());
+  fillAttribute(theBY, by());
+  fillAttribute(theCZ, cz());
+
+  execute();
+}
+
+void GDMLAPI_Ellipsoid::setZCut1(const ModelHighAPI_Double& theZCut1)
+{
+  fillAttribute("true", useZCut1());
+  fillAttribute(theZCut1, zCut1());
+
+  execute();
+}
+
+void GDMLAPI_Ellipsoid::setZCut2(const ModelHighAPI_Double& theZCut2)
+{
+  fillAttribute("true", useZCut2());
+  fillAttribute(theZCut2, zCut2());
+
+  execute();
+}
+
+
+//==================================================================================================
+void GDMLAPI_Ellipsoid::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeDoublePtr anAttrAX = aBase->real(GDMLPlugin_Ellipsoid::AX_ID());
+  AttributeDoublePtr anAttrBY = aBase->real(GDMLPlugin_Ellipsoid::BY_ID());
+  AttributeDoublePtr anAttrCZ = aBase->real(GDMLPlugin_Ellipsoid::CZ_ID());
+
+  theDumper << aBase << " = model.addEllipsoid(" << aDocName << ", "
+            << anAttrAX << ", " << anAttrBY << ", " << anAttrCZ;
+
+  AttributeStringPtr anAttrUseZCut1 = aBase->string(GDMLPlugin_Ellipsoid::USE_ZCUT1_ID());
+  AttributeDoublePtr anAttrZCut1 = aBase->real(GDMLPlugin_Ellipsoid::ZCUT1_ID());
+  AttributeStringPtr anAttrUseZCut2 = aBase->string(GDMLPlugin_Ellipsoid::USE_ZCUT2_ID());
+  AttributeDoublePtr anAttrZCut2 = aBase->real(GDMLPlugin_Ellipsoid::ZCUT2_ID());
+
+  bool isZCut1 = !anAttrUseZCut1->value().empty();
+  bool isZCut2 = !anAttrUseZCut2->value().empty();
+  if (isZCut1 && isZCut2)
+    theDumper << ", " << anAttrZCut1 << ", " << anAttrZCut2 << ")" << std::endl;
+  else {
+    theDumper << ")" << std::endl;
+
+    if (isZCut1 && !isZCut2)
+      theDumper << theDumper.name(aBase) << ".setZCut1(" << anAttrZCut1 << ")" << std::endl;
+    else if (!isZCut1 && isZCut2)
+      theDumper << theDumper.name(aBase) << ".setZCut2(" << anAttrZCut2 << ")" << std::endl;
+  }
+}
+
+
+//==================================================================================================
+EllipsoidPtr addEllipsoid(const std::shared_ptr<ModelAPI_Document>& thePart,
+                          const ModelHighAPI_Double& theAX,
+                          const ModelHighAPI_Double& theBY,
+                          const ModelHighAPI_Double& theCZ)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(GDMLAPI_Ellipsoid::ID());
+  return EllipsoidPtr(new GDMLAPI_Ellipsoid(aFeature, theAX, theBY, theCZ));
+}
+
+EllipsoidPtr addEllipsoid(const std::shared_ptr<ModelAPI_Document>& thePart,
+                          const ModelHighAPI_Double& theAX,
+                          const ModelHighAPI_Double& theBY,
+                          const ModelHighAPI_Double& theCZ,
+                          const ModelHighAPI_Double& theZCut1,
+                          const ModelHighAPI_Double& theZCut2)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(GDMLAPI_Ellipsoid::ID());
+  return EllipsoidPtr(new GDMLAPI_Ellipsoid(aFeature, theAX, theBY, theCZ, theZCut1, theZCut2));
+}
diff --git a/src/GDMLAPI/GDMLAPI_Ellipsoid.h b/src/GDMLAPI/GDMLAPI_Ellipsoid.h
new file mode 100644 (file)
index 0000000..dcc93ff
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GDMLAPI_Ellipsoid_H_
+#define GDMLAPI_Ellipsoid_H_
+
+#include "GDMLAPI.h"
+
+#include <GDMLPlugin_Ellipsoid.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Double;
+
+/// \class GDMLAPI_Ellipsoid
+/// \ingroup CPPHighAPI
+/// \brief Interface for primitive Ellipsoid feature.
+class GDMLAPI_Ellipsoid: public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values.
+  GDMLAPI_EXPORT
+  explicit GDMLAPI_Ellipsoid(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  GDMLAPI_EXPORT
+  explicit GDMLAPI_Ellipsoid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const ModelHighAPI_Double& theAX,
+                             const ModelHighAPI_Double& theBY,
+                             const ModelHighAPI_Double& theCZ);
+
+  /// Constructor with values.
+  GDMLAPI_EXPORT
+  explicit GDMLAPI_Ellipsoid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const ModelHighAPI_Double& theAX,
+                             const ModelHighAPI_Double& theBY,
+                             const ModelHighAPI_Double& theCZ,
+                             const ModelHighAPI_Double& theZCut1,
+                             const ModelHighAPI_Double& theZCut2);
+
+  /// Destructor.
+  GDMLAPI_EXPORT
+  virtual ~GDMLAPI_Ellipsoid();
+
+  INTERFACE_7(GDMLPlugin_Ellipsoid::ID(),
+              ax, GDMLPlugin_Ellipsoid::AX_ID(),
+                  ModelAPI_AttributeDouble,
+                  /** Ellipsoid size along X axis */,
+              by, GDMLPlugin_Ellipsoid::BY_ID(),
+                  ModelAPI_AttributeDouble,
+                  /** Ellipsoid size along Y axis */,
+              cz, GDMLPlugin_Ellipsoid::CZ_ID(),
+                  ModelAPI_AttributeDouble,
+                  /** Ellipsoid size along Z axis */,
+              useZCut1, GDMLPlugin_Ellipsoid::USE_ZCUT1_ID(),
+                  ModelAPI_AttributeString,
+                  /** First cut of the ellipsoid along Z axis */,
+              zCut1, GDMLPlugin_Ellipsoid::ZCUT1_ID(),
+                  ModelAPI_AttributeDouble,
+                  /** Position of the first cut */,
+              useZCut2, GDMLPlugin_Ellipsoid::USE_ZCUT2_ID(),
+                  ModelAPI_AttributeString,
+                  /** Second cut of the ellipsoid along Z axis */,
+              zCut2, GDMLPlugin_Ellipsoid::ZCUT2_ID(),
+                  ModelAPI_AttributeDouble,
+                  /** Position of the second cut */)
+
+  /// Set dimensions
+  GDMLAPI_EXPORT
+  void setSizes(const ModelHighAPI_Double& theAX,
+                const ModelHighAPI_Double& theBY,
+                const ModelHighAPI_Double& theCZ);
+
+  /// Set Z cut no.1
+  GDMLAPI_EXPORT
+  void setZCut1(const ModelHighAPI_Double& theZCut1);
+
+  /// Set Z cut no.2
+  GDMLAPI_EXPORT
+  void setZCut2(const ModelHighAPI_Double& theZCut2);
+
+  /// Dump wrapped feature
+  GDMLAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on primitive Ellipsoid object
+typedef std::shared_ptr<GDMLAPI_Ellipsoid> EllipsoidPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create GDML Ellipsoid feature.
+GDMLAPI_EXPORT
+EllipsoidPtr addEllipsoid(const std::shared_ptr<ModelAPI_Document>& thePart,
+                          const ModelHighAPI_Double& theAX,
+                          const ModelHighAPI_Double& theBY,
+                          const ModelHighAPI_Double& theCZ);
+
+/// \ingroup CPPHighAPI
+/// \brief Create GDML Ellipsoid feature.
+GDMLAPI_EXPORT
+EllipsoidPtr addEllipsoid(const std::shared_ptr<ModelAPI_Document>& thePart,
+                          const ModelHighAPI_Double& theAX,
+                          const ModelHighAPI_Double& theBY,
+                          const ModelHighAPI_Double& theCZ,
+                          const ModelHighAPI_Double& theZCut1,
+                          const ModelHighAPI_Double& theZCut2);
+#endif // GDMLAPI_Ellipsoid_H_
index 2d4d2a705242fe11e767430349b6f5a6827537c2..91571affdf5a9c3391dc62dc16d5b35581cd4aa2 100644 (file)
@@ -25,6 +25,7 @@
 
   #include "GDMLAPI.h"
   #include "GDMLAPI_ConeSegment.h"
+  #include "GDMLAPI_Ellipsoid.h"
 
 #endif // GDMLAPI_swig_H_
 
index f25ab2e7c22311da4825cbd08aebd9692c2d0cda..c323a7835704631979c04f3dd8fefb1755444a3a 100644 (file)
@@ -388,7 +388,8 @@ void GeomAPI_AISObject::getColor(int& theR, int& theG, int& theB)
   if (anAIS.IsNull())
     return;
 
-  Quantity_Color aColor = anAIS->Color();
+  Quantity_Color aColor;
+  anAIS->Color(aColor);
   theR = (int)(aColor.Red()*255.);
   theG = (int)(aColor.Green()*255.);
   theB = (int)(aColor.Blue()*255.);
@@ -428,6 +429,39 @@ double GeomAPI_AISObject::getDeflection() const
   return aDeflection;
 }
 
+bool GeomAPI_AISObject::setTransparency(const double theTransparency)
+{
+  bool isModified = false;
+  Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
+  if (!anAIS.IsNull()) {
+    Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast(anAIS);
+    if (!anAISShape.IsNull()) {
+      Standard_Real aPreviousValue = anAISShape->Transparency();
+      if (fabs(aPreviousValue - theTransparency) > Precision::Confusion()) {
+        anAISShape->SetTransparency(theTransparency);
+        //>SetOwnDeviationCoefficient(theTransparency);
+        isModified = true;
+        // redisplay is necessary here to update presentation in all modes
+        // Standard True flag. Displayer uses Standard False flag. If it will be changed in
+        // displayer, redisplay here will not be necessary. But performance should be checked.
+        anAISShape->Redisplay(Standard_True);
+      }
+    }
+  }
+  return isModified;
+}
+
+double GeomAPI_AISObject::getTransparency() const
+{
+  double aTransparency = 0;
+
+  Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
+  if (!anAIS.IsNull()) {
+    aTransparency = anAIS->Transparency();
+  }
+  return aTransparency;
+}
+
 
 bool GeomAPI_AISObject::empty() const
 {
index 5a4cd78e98bc30304d48eab3c85c828d5a4572d9..54c6840b2197707f2e1883c2b920ab93486c7c38 100644 (file)
@@ -148,6 +148,18 @@ class GeomAPI_AISObject : public GeomAPI_Interface
   GEOMAPI_EXPORT
   double getDeflection() const;
 
+  /** \brief Assigns the transparency to the shape
+   *  \param[in] theTransparency value of transparency
+   */
+  GEOMAPI_EXPORT
+  bool setTransparency(const double theTransparency);
+
+  /** \brief Returns deflection for the shape
+   *  \return double value
+   */
+  GEOMAPI_EXPORT
+  double getTransparency() const;
+
   /// \return Current width of the lines of shape
   GEOMAPI_EXPORT
   double width();
index d5132057c681ba2403233e98076ec0c0d364d2a4..a7497c0dc511501d449e667aa10c8c486263b47e 100644 (file)
@@ -24,7 +24,8 @@
 #include <NCollection_Map.hxx>
 #include <TopoDS_Shape.hxx>
 
-#define MY_MAP implPtr<NCollection_DataMap<TopoDS_Shape, NCollection_Map<TopoDS_Shape> > >()
+typedef NCollection_DataMap<TopoDS_Shape, NCollection_Map<TopoDS_Shape> > MAP;
+#define MY_MAP implPtr<MAP>()
 
 //=================================================================================================
 GeomAPI_DataMapOfShapeMapOfShapes::GeomAPI_DataMapOfShapeMapOfShapes()
@@ -113,3 +114,158 @@ int GeomAPI_DataMapOfShapeMapOfShapes::size() const
 {
   return MY_MAP->Size();
 }
+
+
+//=================================================================================================
+//   iterator implementation
+//=================================================================================================
+
+class IteratorImpl : public GeomAPI_DataMapOfShapeMapOfShapes::iterator
+{
+public:
+  IteratorImpl() {}
+
+  IteratorImpl(const MAP::Iterator& theIterator)
+    : myIterator(theIterator)
+  {}
+
+  IteratorImpl(const std::shared_ptr<IteratorImpl>& theIterator)
+  {
+    mySelf = theIterator;
+  }
+
+  bool operator==(const std::shared_ptr<IteratorImpl>& theOther) const
+  {
+    if (theOther)
+      return theOther->myIterator.IsEqual(myIterator);
+
+    // theOther is end iterator => check the current iterator is not at the end
+    return !myIterator.More();
+  }
+
+  virtual iterator& operator++()
+  {
+    myIterator.Next();
+    return *this;
+  }
+  virtual iterator operator++(int)
+  {
+    std::shared_ptr<IteratorImpl> aSelf = std::dynamic_pointer_cast<IteratorImpl>(mySelf);
+    std::shared_ptr<IteratorImpl> aCopy(new IteratorImpl(aSelf->myIterator));
+    myIterator.Next();
+    return IteratorImpl(aCopy);
+  }
+
+  virtual key_type first() const
+  {
+    if (mySelf)
+      return iterator::first();
+
+    GeomShapePtr aShape(new GeomAPI_Shape);
+    aShape->setImpl(new TopoDS_Shape(myIterator.Key()));
+    return aShape;
+  }
+
+  virtual mapped_type second() const
+  {
+    if (mySelf)
+      return iterator::second();
+
+    ListOfShape anItems;
+    const NCollection_Map<TopoDS_Shape>& aMap = myIterator.Value();
+    for(NCollection_Map<TopoDS_Shape>::Iterator anIt(aMap); anIt.More(); anIt.Next()) {
+      std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+      aShape->setImpl(new TopoDS_Shape(anIt.Value()));
+      anItems.push_back(aShape);
+    }
+    return anItems;
+  }
+
+private:
+  MAP::Iterator myIterator;
+};
+
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::iterator()
+{
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::iterator(
+    const GeomAPI_DataMapOfShapeMapOfShapes::iterator& theOther)
+  : mySelf(theOther.mySelf)
+{
+}
+
+const GeomAPI_DataMapOfShapeMapOfShapes::iterator&
+    GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator=(
+      const GeomAPI_DataMapOfShapeMapOfShapes::iterator& theOther)
+{
+  mySelf = theOther.mySelf;
+  return *this;
+}
+
+bool GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator==(const iterator& theOther) const
+{
+  std::shared_ptr<IteratorImpl> aSelf = std::dynamic_pointer_cast<IteratorImpl>(mySelf);
+  std::shared_ptr<IteratorImpl> aSelfOther =
+      std::dynamic_pointer_cast<IteratorImpl>(theOther.mySelf);
+
+  return aSelf ? aSelf->operator==(aSelfOther)
+                : (aSelfOther ? aSelfOther->operator==(aSelf) : true);
+}
+
+bool GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator!=(const iterator& theOther) const
+{
+  return !operator==(theOther);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator&
+    GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator++()
+{
+  mySelf->operator++();
+  return *this;
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator
+    GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator++(int)
+{
+  return ++(*mySelf);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::key_type
+    GeomAPI_DataMapOfShapeMapOfShapes::iterator::first() const
+{
+  return mySelf->first();
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::mapped_type
+    GeomAPI_DataMapOfShapeMapOfShapes::iterator::second() const
+{
+  return mySelf->second();
+}
+
+
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator GeomAPI_DataMapOfShapeMapOfShapes::begin()
+{
+  MAP::Iterator anIt(*MY_MAP);
+  std::shared_ptr<IteratorImpl> anIter(new IteratorImpl(anIt));
+  return IteratorImpl(anIter);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::const_iterator GeomAPI_DataMapOfShapeMapOfShapes::begin() const
+{
+  MAP::Iterator anIt(*MY_MAP);
+  std::shared_ptr<IteratorImpl> anIter(new IteratorImpl(anIt));
+  return IteratorImpl(anIter);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator GeomAPI_DataMapOfShapeMapOfShapes::end()
+{
+  return IteratorImpl(std::shared_ptr<IteratorImpl>());
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::const_iterator GeomAPI_DataMapOfShapeMapOfShapes::end() const
+{
+  return IteratorImpl(std::shared_ptr<IteratorImpl>());
+}
index 9e631c861ebacdeaa0751971773dd328133aa25f..395abae3444c6cba1c40305d8be7a2d38a3d6da8 100644 (file)
@@ -64,6 +64,40 @@ public:
 
   /// \return size of map.
   GEOMAPI_EXPORT int size() const;
+
+public:
+  class iterator
+  {
+  public:
+    typedef GeomShapePtr key_type;
+    typedef ListOfShape  mapped_type;
+    typedef std::pair<GeomShapePtr, ListOfShape> value_type;
+
+  public:
+    GEOMAPI_EXPORT iterator();
+    GEOMAPI_EXPORT iterator(const iterator&);
+    GEOMAPI_EXPORT const iterator& operator=(const iterator&);
+
+    GEOMAPI_EXPORT bool operator==(const iterator&) const;
+    GEOMAPI_EXPORT bool operator!=(const iterator&) const;
+
+    GEOMAPI_EXPORT virtual iterator& operator++();
+    GEOMAPI_EXPORT virtual iterator  operator++(int);
+
+    GEOMAPI_EXPORT virtual key_type first() const;
+    GEOMAPI_EXPORT virtual mapped_type second() const;
+
+  protected:
+    std::shared_ptr<iterator> mySelf;
+  };
+
+  typedef iterator const_iterator;
+
+  GEOMAPI_EXPORT iterator begin();
+  GEOMAPI_EXPORT const_iterator begin() const;
+
+  GEOMAPI_EXPORT iterator end();
+  GEOMAPI_EXPORT const_iterator end() const;
 };
 
 #endif
index c1df335558bd9f4f7680e158f68a43984bd27619..f66a6a1e6f8e9351cfa20cd7e1d0ed40292f488e 100644 (file)
@@ -408,7 +408,8 @@ void GeomAPI_Shape::setOrientation(const GeomAPI_Shape::Orientation theOrientati
   }
 }
 
-bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) const
+bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape,
+                               const bool theCheckOrientation) const
 {
   if(!theShape.get()) {
     return false;
@@ -420,7 +421,8 @@ bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) co
   }
 
   for(TopExp_Explorer anExp(*MY_SHAPE, aShapeToSearch.ShapeType()); anExp.More(); anExp.Next()) {
-    if(aShapeToSearch.IsEqual(anExp.Current())) {
+    if(theCheckOrientation ?
+       aShapeToSearch.IsEqual(anExp.Current()) : aShapeToSearch.IsSame(anExp.Current())) {
       return true;
     }
   }
index 4e148978cd162140c5b9316ebd6ef0e5d89c9c6a..242a85bc7fcabca5368a687a771ae9bd57e27294 100644 (file)
@@ -125,7 +125,9 @@ public:
 
   /// \return true if passed shape is a sub-shape of this shape.
   /// \param theShape shape to search.
-  GEOMAPI_EXPORT virtual bool isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+  /// \param theCheckOrientation if false, returns true even if orientation of shape differs
+  GEOMAPI_EXPORT virtual bool isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape,
+    const bool theCheckOrientation = true) const;
 
   /// Computes boundary dimensions of the shape
   /// Returns False if it is not possible
index 01a0e3f776fb11a1604e25ba045b40c07530dccf..1262d4717b34c21bb1156c2c23903017e874a236 100644 (file)
@@ -40,7 +40,7 @@ GeomAPI_Trsf::GeomAPI_Trsf()
 
 //=================================================================================================
 GeomAPI_Trsf::GeomAPI_Trsf(void* theTrsf)
-: GeomAPI_Interface(theTrsf)
+: GeomAPI_Interface((gp_Trsf*)theTrsf)
 {
 }
 
index 43727cf248cef9df30622283f38825a619ce950c..f2b4f43305e5c6c298197e99f38dd43fc05c7f7e 100644 (file)
@@ -40,6 +40,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_MakeShapeCustom.h
     GeomAlgoAPI_MakeShapeList.h
     GeomAlgoAPI_MakeSweep.h
+    GeomAlgoAPI_MakeVolume.h
     GeomAlgoAPI_DFLoader.h
     GeomAlgoAPI_Placement.h
     GeomAlgoAPI_BREPImport.h
@@ -72,6 +73,8 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Symmetry.h
     GeomAlgoAPI_Scale.h
     GeomAlgoAPI_Circ2dBuilder.h
+    GeomAlgoAPI_UnifySameDomain.h
+    GeomAlgoAPI_Fillet.h
 )
 
 SET(PROJECT_SOURCES
@@ -90,6 +93,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_MakeShapeCustom.cpp
     GeomAlgoAPI_MakeShapeList.cpp
     GeomAlgoAPI_MakeSweep.cpp
+    GeomAlgoAPI_MakeVolume.cpp
     GeomAlgoAPI_DFLoader.cpp
     GeomAlgoAPI_Placement.cpp
     GeomAlgoAPI_BREPImport.cpp
@@ -122,6 +126,8 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Symmetry.cpp
     GeomAlgoAPI_Scale.cpp
     GeomAlgoAPI_Circ2dBuilder.cpp
+    GeomAlgoAPI_UnifySameDomain.cpp
+    GeomAlgoAPI_Fillet.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -136,6 +142,7 @@ SET(PROJECT_LIBRARIES
     ${CAS_TKBRep}
     ${CAS_TKCAF}
     ${CAS_TKCAF}
+    ${CAS_TKFillet}
     ${CAS_TKLCAF}
     ${CAS_TKPrim}
     ${CAS_TKSTEP}
index 64dcb89497206d838606d3d604baafe6d84f9c79..7ef54d5d6be0032e4e8401503ef55ca36c8f6acc 100644 (file)
@@ -86,9 +86,14 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects,
 
   // Building and getting result.
   aBuilder->Perform();
+#ifdef USE_OCCT_720
+  if (aBuilder->HasErrors())
+    return;
+#else
   if(aBuilder->ErrorStatus() != 0) {
     return;
   }
+#endif
   TopoDS_Shape aResult = aBuilder->Shape();
 
   if(aResult.ShapeType() == TopAbs_COMPOUND) {
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.cpp
new file mode 100644 (file)
index 0000000..b3d510c
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_Fillet.h"
+
+#include <BRepFilletAPI_MakeFillet.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+                                       const ListOfShape&  theFilletEdges,
+                                       const double        theFilletRadius)
+{
+  build(theBaseSolid, theFilletEdges, theFilletRadius);
+}
+
+//=================================================================================================
+GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+                                       const ListOfShape&  theFilletEdges,
+                                       const double        theStartRadius,
+                                       const double        theEndRadius)
+{
+  if (theEndRadius < 0.)
+    return;
+  build(theBaseSolid, theFilletEdges, theStartRadius, theEndRadius);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Fillet::build(const GeomShapePtr& theBaseSolid,
+                               const ListOfShape&  theFilletEdges,
+                               const double        theStartRadius,
+                               const double        theEndRadius)
+{
+  if (!theBaseSolid || theFilletEdges.empty() || theStartRadius < 0.)
+    return;
+
+  // create fillet builder
+  BRepFilletAPI_MakeFillet* aFilletBuilder =
+      new BRepFilletAPI_MakeFillet(theBaseSolid->impl<TopoDS_Shape>());
+  setImpl(aFilletBuilder);
+  setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+  // assign filleting edges
+  for (ListOfShape::const_iterator anIt = theFilletEdges.begin();
+       anIt != theFilletEdges.end(); ++anIt) {
+    if ((*anIt)->isEdge())
+      aFilletBuilder->Add( (*anIt)->impl<TopoDS_Edge>() );
+  }
+
+  // assign fillet radii for each contour of filleting edges
+  bool isFixedRadius = theEndRadius < 0.;
+  int aNbContours = aFilletBuilder->NbContours();
+  for (int ind = 1; ind <= aNbContours; ++ind) {
+    if (isFixedRadius)
+      aFilletBuilder->SetRadius(theStartRadius, ind, 1);
+    else
+      aFilletBuilder->SetRadius(theStartRadius, theEndRadius, ind, 1);
+  }
+
+  // build and get result
+  aFilletBuilder->Build();
+  if (!aFilletBuilder->IsDone())
+    return;
+  const TopoDS_Shape& aResult = aFilletBuilder->Shape();
+
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  setShape(aShape);
+  setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h b/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h
new file mode 100644 (file)
index 0000000..56648cd
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_Fillet_H_
+#define GeomAlgoAPI_Fillet_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_Fillet
+/// \ingroup DataAlgo
+/// \brief Perform fillet
+class GeomAlgoAPI_Fillet : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// Run fillet operation with fixed radius.
+  /// \param theBaseSolid    a changing solid
+  /// \param theFilletEdges  list of edges the fillet is performed on
+  /// \param theFilletRadius radius of the fillet
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+                                        const ListOfShape&  theFilletEdges,
+                                        const double        theFilletRadius);
+
+  /// Run fillet operation with variable radius.
+  /// \param theBaseSolid    a changing solid
+  /// \param theFilletEdges  list of edges the fillet is performed on
+  /// \param theStartRadius  start radius of the fillet
+  /// \param theEndRadius    end radius of the fillet
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+                                        const ListOfShape&  theFilletEdges,
+                                        const double        theStartRadius,
+                                        const double        theEndRadius);
+
+private:
+  /// Perform fillet operation.
+  /// If theEndRadius is less than 0., the fixed radius fillet will be built.
+  /// \param theBaseSolid    a changing solid
+  /// \param theFilletEdges  list of edges the fillet is performed on
+  /// \param theStartRadius  start radius of the fillet
+  /// \param theEndRadius    end radius of the fillet
+  void build(const GeomShapePtr& theBaseSolid,
+             const ListOfShape&  theFilletEdges,
+             const double        theStartRadius,
+             const double        theEndRadius = -1.0);
+};
+
+#endif
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp
new file mode 100644 (file)
index 0000000..0dc7ef9
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_MakeVolume.h"
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <BOPAlgo_MakerVolume.hxx>
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeVolume::make(const ListOfShape& theFaces)
+{
+  GeomAlgoAPI_MakeVolume aMkVolAlgo(theFaces);
+  GeomShapePtr aResult;
+  if(aMkVolAlgo.isDone() && !aMkVolAlgo.shape()->isNull() && aMkVolAlgo.isValid())
+    aResult = aMkVolAlgo.shape();
+  return aResult;
+}
+
+//=================================================================================================
+GeomAlgoAPI_MakeVolume::GeomAlgoAPI_MakeVolume(const ListOfShape& theFaces)
+{
+  build(theFaces);
+}
+
+static void convertToTopoDS(const ListOfShape& theShapes, TopTools_ListOfShape& theTopoDSShapes)
+{
+  for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
+    theTopoDSShapes.Append((*anIt)->impl<TopoDS_Shape>());
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeVolume::build(const ListOfShape& theFaces)
+{
+  if (theFaces.empty()) {
+    return;
+  }
+
+  // create make volume opration
+  BOPAlgo_MakerVolume* aVolumeMaker = new BOPAlgo_MakerVolume;
+  this->setImpl(aVolumeMaker);
+  this->setBuilderType(OCCT_BOPAlgo_Builder);
+
+  // list of arguments
+  TopTools_ListOfShape anArgs;
+  convertToTopoDS(theFaces, anArgs);
+
+  // parameters of the volume maker
+  aVolumeMaker->SetArguments(anArgs);
+  aVolumeMaker->SetIntersect(true); // split edges and faces
+#ifdef USE_OCCT_720
+  aVolumeMaker->SetAvoidInternalShapes(true);
+#endif
+  aVolumeMaker->SetGlue(BOPAlgo_GlueShift);
+
+  // building and getting result
+  aVolumeMaker->Perform();
+#ifdef USE_OCCT_720
+  if (aVolumeMaker->HasErrors())
+    return;
+#else
+  if(aVolumeMaker->ErrorStatus() != 0) {
+    return;
+  }
+#endif
+  TopoDS_Shape aResult = aVolumeMaker->Shape();
+
+  if(aResult.ShapeType() == TopAbs_COMPOUND) {
+    std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+    aGeomShape->setImpl(new TopoDS_Shape(aResult));
+    aResult = GeomAlgoAPI_ShapeTools::groupSharedTopology(aGeomShape)->impl<TopoDS_Shape>();
+  }
+
+  // Setting result.
+  if(aResult.IsNull()) {
+    return;
+  }
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  this->setShape(aShape);
+  this->setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h
new file mode 100644 (file)
index 0000000..b273fb4
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_MakeVolume_H_
+#define GeomAlgoAPI_MakeVolume_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_MakeVolume
+/// \ingroup DataAlgo
+/// \brief Perform building solid (compsolid) from a list of faces.
+class GeomAlgoAPI_MakeVolume : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// \brief Perform making volume.
+  /// \param[in] theObjects list of faces.
+  /// \return a solid or a compsolid as result of operation.
+  GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Shape> make(const ListOfShape& theFaces);
+
+  /// Constructor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeVolume(const ListOfShape& theFaces);
+
+private:
+  /// Builds resulting shape.
+  void build(const ListOfShape& theFaces);
+};
+
+#endif
index cd880734a65e4c56d03250784d6417e39b525aa8..de1551c6b375204260eb9c0fba787ae0590bccf8 100644 (file)
 
 #include <GEOMAlgo_Splitter.hxx>
 
+#include <NCollection_Vector.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS_Builder.hxx>
 #include <TopTools_MapOfShape.hxx>
 
+//=================================================================================================
+bool isSubShape(const TopoDS_Shape& theShape, const TopoDS_Shape& theSubShape)
+{
+  for(TopExp_Explorer anExp(theShape, theSubShape.ShapeType()); anExp.More(); anExp.Next()) {
+    if(theSubShape.IsSame(anExp.Current())) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 //=================================================================================================
 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Partition::make(const ListOfShape& theObjects,
                                                            const ListOfShape& theTools)
@@ -78,8 +91,10 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
 
   TopTools_MapOfShape ShapesMap;
   // Getting objects.
-  for(ListOfShape::const_iterator
-       anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
+  for(ListOfShape::const_iterator anObjectsIt = theObjects.begin();
+      anObjectsIt != theObjects.end();
+      anObjectsIt++)
+  {
     const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
     // #2240: decompose compounds to get the valid result
     TopTools_ListOfShape aSimpleShapes;
@@ -102,11 +117,47 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
 
   // Building and getting result.
   anOperation->Perform();
+#ifdef USE_OCCT_720
+  if (anOperation->HasErrors())
+    return;
+#else
   if(anOperation->ErrorStatus() != 0) {
     return;
   }
+#endif
   TopoDS_Shape aResult = anOperation->Shape();
 
+  if(aResult.ShapeType() == TopAbs_COMPOUND) {
+    // Exclude faces and edges which are shared as another sub-shape.
+    NCollection_Vector<TopoDS_Shape> aFacesAndEdges;
+    TopoDS_Compound aTempCompound;
+    TopoDS_Builder aBuilder;
+    aBuilder.MakeCompound(aTempCompound);
+    for(TopoDS_Iterator anIt(aResult);
+        anIt.More();
+        anIt.Next()) {
+      const TopoDS_Shape& aSubShape = anIt.Value();
+      if (aSubShape.ShapeType() == TopAbs_FACE || aSubShape.ShapeType() == TopAbs_EDGE) {
+        aFacesAndEdges.Append(aSubShape);
+      } else {
+        aBuilder.Add(aTempCompound, aSubShape);
+      }
+    }
+
+    for (NCollection_Vector<TopoDS_Shape>::Iterator anIt(aFacesAndEdges);
+        anIt.More();
+        anIt.Next())
+    {
+      const TopoDS_Shape& aSubShape = anIt.Value();
+      if (!isSubShape(aTempCompound, aSubShape))
+      {
+        aBuilder.Add(aTempCompound, aSubShape);
+      }
+    }
+
+    aResult = aTempCompound;
+  }
+
   if(aResult.ShapeType() == TopAbs_COMPOUND) {
     std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
     aGeomShape->setImpl(new TopoDS_Shape(aResult));
index aada7a927aa49d8eb01fbf36bdf45befbe6d62cf..9b61619a30c2624525a9fee8cf5489fd9e9379b2 100644 (file)
@@ -55,20 +55,30 @@ void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape,
   }
   aPaveFiller.SetArguments(aListOfShape);
   aPaveFiller.Perform();
+#ifdef USE_OCCT_720
+  if (aPaveFiller.HasErrors())
+    return;
+#else
   Standard_Integer iErr = aPaveFiller.ErrorStatus();
   if(iErr) {
     return;
   }
+#endif
 
   BOPAlgo_Builder* aBuilder = new BOPAlgo_Builder();
   this->setImpl(aBuilder);
   this->setBuilderType(OCCT_BOPAlgo_Builder);
   aBuilder->SetArguments(aListOfShape);
   aBuilder->PerformWithFiller(aPaveFiller);
+#ifdef USE_OCCT_720
+  if (aBuilder->HasErrors())
+    return;
+#else
   iErr = aBuilder->ErrorStatus();
   if(iErr) {
     return;
   }
+#endif
 
   TopoDS_Shape aResult = aBuilder->Shape();
   if(aResult.ShapeType() == TopAbs_COMPOUND) {
index d798b50ad00687b5f6cbe53edd6701623740dca3..fd854afb74009ba5ea90e2adfdfd31eeaece85ed 100644 (file)
@@ -93,6 +93,23 @@ double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theSh
   return aGProps.Mass();
 }
 
+//==================================================================================================
+double GeomAlgoAPI_ShapeTools::area (const std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  GProp_GProps aGProps;
+  if(!theShape.get()) {
+    return 0.0;
+  }
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  if(aShape.IsNull()) {
+    return 0.0;
+  }
+  const Standard_Real anEps = 1.e-6;
+
+  BRepGProp::SurfaceProperties(aShape, aGProps, anEps);
+  return aGProps.Mass();
+}
+
 //==================================================================================================
 std::shared_ptr<GeomAPI_Pnt>
   GeomAlgoAPI_ShapeTools::centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape)
@@ -821,8 +838,13 @@ void GeomAlgoAPI_ShapeTools::splitShape(const std::shared_ptr<GeomAPI_Shape>& th
   }
 
   aBOP.Perform();
+#ifdef USE_OCCT_720
+  if (aBOP.HasErrors())
+    return;
+#else
   if (aBOP.ErrorStatus())
     return;
+#endif
 
   // Collect splits
   const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge);
@@ -866,8 +888,13 @@ void GeomAlgoAPI_ShapeTools::splitShape_p(const std::shared_ptr<GeomAPI_Shape>&
   }
 
   aBOP.Perform();
+#ifdef USE_OCCT_720
+  if (aBOP.HasErrors())
+    return;
+#else
   if (aBOP.ErrorStatus())
     return;
+#endif
 
   // Collect splits
   const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge);
index a7f051a8dfc1f22b7c0166dc770f88dbf38df036..7745c4011f5640a6053f3b7635eda575dcbf3866 100644 (file)
@@ -48,6 +48,9 @@ public:
   /// \return the total volume of the solids of the current shape or 0.0 if it can be computed.
   GEOMALGOAPI_EXPORT static double volume(const std::shared_ptr<GeomAPI_Shape> theShape);
 
+  /// \return the total area of the faces of the current shape or 0.0 if it can be computed.
+  GEOMALGOAPI_EXPORT static double area(const std::shared_ptr<GeomAPI_Shape> theShape);
+
   /// \return the centre of mass of the current face.
   /// The coordinates returned for the center of mass
   /// are expressed in the absolute Cartesian coordinate system.
index c4bf9d6f38d37039a245433249aeb4b5a9997624..a6da1e785e24b70d0a84b515c1afd0b7805fbc94 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <BOPAlgo_Builder.hxx>
 #include <BRep_Builder.hxx>
+#include <BRepTools_WireExplorer.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_TrimmedCurve.hxx>
@@ -63,7 +64,7 @@ static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape)
   return aStart;
 }
 
-static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape,
+static TopoDS_Vertex findStartVertex(const TopoDS_Wire& theWire, const TopoDS_Face& theFace,
     const std::list<std::shared_ptr<GeomAPI_Shape> >& theInitialShapes)
 {
   // Try to find edge lying on the one of original edges.
@@ -80,9 +81,9 @@ static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape,
     if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
       aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
 
-    TopExp_Explorer anExp(theShape, TopAbs_EDGE);
+    BRepTools_WireExplorer anExp(theWire, theFace);
     for (; anExp.More(); anExp.Next()) {
-      const TopoDS_Edge& aShapeEdge = TopoDS::Edge(anExp.Current());
+      const TopoDS_Edge& aShapeEdge = anExp.Current();
       double aF, aL;
       Handle(Geom_Curve) aShapeCurve = BRep_Tool::Curve(aShapeEdge, aF, aL);
       if (aShapeCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
@@ -99,7 +100,7 @@ static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape,
   }
 
   // start vertex is not found, use algorithm to search vertex with the greatest coordinates
-  return findStartVertex(theShape);
+  return findStartVertex(theWire);
 }
 
 // returns true if the first shape must be located earlier than the second
@@ -218,9 +219,13 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
       aBB.AddArgument(anEdge);
   }
   aBB.Perform();
+#ifdef USE_OCCT_720
+  if (aBB.HasErrors())
+    return;
+#else
   if (aBB.ErrorStatus())
     return;
-
+#endif
   // Collect faces
   TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace);
   sortFaces(anAreas, theFeatures); // sort faces by the edges in them
@@ -243,7 +248,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
 
       // to make faces equal on different platforms, we will find
       // a vertex lying on an edge with the lowest index in the list of initial edges
-      TopoDS_Vertex aStartVertex = findStartVertex(aWire, theFeatures);
+      TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theFeatures);
 
       TopoDS_Wire aNewWire;
       aBuilder.MakeWire(aNewWire);
@@ -251,12 +256,12 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
       bool aStartFound = false;
 
       // remove internal edges from faces and make wire start from found vertex
-      TopExp_Explorer anExp(aWire, TopAbs_EDGE);
+      BRepTools_WireExplorer anExp(aWire, aFace);
       for (; anExp.More(); anExp.Next()) {
         if (anExp.Current().Orientation() == TopAbs_INTERNAL)
           continue;
         if (!aStartFound) {
-          const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
+          const TopoDS_Edge& anEdge = anExp.Current();
           TopoDS_Vertex aV1, aV2;
           TopExp::Vertices(anEdge, aV1, aV2, Standard_True);
           if (aV1.IsSame(aStartVertex) == Standard_True)
@@ -273,7 +278,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
         aBuilder.Add(aNewWire, *aSkIt);
 
       // check the wire is empty
-      anExp.Init(aNewWire, TopAbs_EDGE);
+      anExp.Init(aNewWire);
       if (anExp.More())
         aBuilder.Add(aNewFace, aNewWire);
     }
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_UnifySameDomain.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_UnifySameDomain.cpp
new file mode 100644 (file)
index 0000000..8e8238a
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_UnifySameDomain.h"
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <ShapeUpgrade_UnifySameDomain.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Shape.hxx>
+
+//==================================================================================================
+GeomAlgoAPI_UnifySameDomain::GeomAlgoAPI_UnifySameDomain(const ListOfShape& theShapes)
+{
+  build(theShapes);
+}
+
+void GeomAlgoAPI_UnifySameDomain::build(const ListOfShape& theShapes)
+{
+  if(theShapes.empty()) {
+    return;
+  }
+
+  // Make compound.
+  GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(theShapes);
+  ListOfShape aCombined, aFree;
+  GeomAlgoAPI_ShapeTools::combineShapes(
+    aCompound,
+    GeomAPI_Shape::SHELL,
+    aCombined,
+    aFree);
+
+  if(aFree.size() > 0 || aCombined.size() > 1) {
+    return;
+  }
+
+  const TopoDS_Shape& aShell = aCombined.front()->impl<TopoDS_Shape>();
+
+  ShapeUpgrade_UnifySameDomain* aUnifyAlgo = new ShapeUpgrade_UnifySameDomain();
+  this->setImpl(aUnifyAlgo);
+
+  aUnifyAlgo->Initialize(aShell);
+  aUnifyAlgo->UnifyFacesAndEdges();
+  aUnifyAlgo->Build();
+
+  TopoDS_Shape aResult = aUnifyAlgo->Shape();
+  if (aResult.IsNull()) {
+    return;
+  }
+
+  if (aResult.ShapeType() == TopAbs_SHELL) {
+    int aNb = 0;
+    TopoDS_Iterator anIt(aResult);
+    for (; anIt.More(); anIt.Next()) {
+      ++aNb;
+    }
+
+    if (aNb == 1) {
+      anIt.Initialize(aResult);
+      aResult = anIt.Value();
+    }
+  }
+
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  this->setShape(aShape);
+  this->setDone(true);
+}
+
+//==================================================================================================
+void GeomAlgoAPI_UnifySameDomain::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                  ListOfShape& theHistory)
+{
+  if(!theShape.get()) {
+    return;
+  }
+
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  const ShapeUpgrade_UnifySameDomain& aUnifyAlgo = this->impl<ShapeUpgrade_UnifySameDomain>();
+
+  TopoDS_Shape aModifiedShape = aUnifyAlgo.Generated(aShape);
+
+  for(TopExp_Explorer anExp(aModifiedShape, aShape.ShapeType()); anExp.More(); anExp.Next()) {
+    GeomShapePtr aGeomShape(new GeomAPI_Shape());
+    aGeomShape->setImpl(new TopoDS_Shape(anExp.Current()));
+    theHistory.push_back(aGeomShape);
+  }
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_UnifySameDomain.h b/src/GeomAlgoAPI/GeomAlgoAPI_UnifySameDomain.h
new file mode 100644 (file)
index 0000000..a183666
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_UnifySameDomain_H_
+#define GeomAlgoAPI_UnifySameDomain_H_
+
+#include "GeomAlgoAPI.h"
+#include "GeomAlgoAPI_MakeShape.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_UnifySameDomain
+/// \ingroup DataAlgo
+/// \brief This tool tries to unify faces and edges of the shape which lies on the same geometry.
+class GeomAlgoAPI_UnifySameDomain: public GeomAlgoAPI_MakeShape
+{
+public:
+  /// Constructor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_UnifySameDomain(const ListOfShape& theShapes);
+
+  /// \return the list of shapes modified from the shape \a theShape.
+  /// \param[in] theShape base shape.
+  /// \param[out] theHistory modified shapes.
+  GEOMALGOAPI_EXPORT virtual void modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                           ListOfShape& theHistory);
+
+private:
+  /// Builds resulting shape.
+  void build(const ListOfShape& theShapes);
+};
+
+#endif
index f03f0594cefc786256d6081bd62331b6f8be875e..364834d40408dee94994d04ad16b54d7ba64d637 100755 (executable)
@@ -143,7 +143,9 @@ void GEOMAlgo_Splitter::Clear()
 //=======================================================================
 void GEOMAlgo_Splitter::BuildResult(const TopAbs_ShapeEnum theType)
 {
+#ifndef USE_OCCT_720
   myErrorStatus=0;
+#endif
   //
   TopAbs_ShapeEnum aType;
   BRep_Builder aBB;
index 7383893501168275c139f7ca92e9f57e9500ac7e..f582556ff68ab900b7b42f78b8c912b86c1e4244 100755 (executable)
@@ -270,6 +270,8 @@ void Model_BodyBuilder::clean()
     }
   }
   myBuilders.clear();
+  // remove the old reference (if any)
+  aLab.ForgetAttribute(TDF_Reference::GetID());
 }
 
 Model_BodyBuilder::~Model_BodyBuilder()
@@ -404,7 +406,7 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
       }
       GeomShapePtr aGeomNewShape(new GeomAPI_Shape());
       aGeomNewShape->setImpl(new TopoDS_Shape(aNewShape));
-      if(!aRoot.IsSame(aNewShape) && aResultShape->isSubShape(aGeomNewShape)) {
+      if(!aRoot.IsSame(aNewShape) && aResultShape->isSubShape(aGeomNewShape, false)) {
         if(theIsStoreAsGenerated) {
           // Here we store shapes as generated, to avoid problem when one parent shape produce
           // several child shapes. In this case naming could not determine which shape to select.
@@ -444,8 +446,8 @@ void Model_BodyBuilder::loadAndOrientGeneratedShapes (
   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
+    //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)));
index 867614ca3fb39f5668446b30e6af1b83ef37a38a..49bca1d2752823a715467acb473d742a254b4a2b 100644 (file)
@@ -134,7 +134,7 @@ void Model_Data::setName(const std::string& theName)
     ModelAPI_ObjectRenamedMessage::send(myObject, anOldName, theName, this);
   if (isModified && myObject && myObject->document()) {
     std::dynamic_pointer_cast<Model_Document>(myObject->document())->
-      changeNamingName(anOldName, theName);
+      changeNamingName(anOldName, theName, myLab);
   }
 #ifdef DEBUG_NAMES
   myObject->myName = theName;
@@ -144,7 +144,8 @@ void Model_Data::setName(const std::string& theName)
 AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
 {
   AttributePtr aResult;
-  TDF_Label anAttrLab = myLab.FindChild(int(myAttrs.size()) + 1);
+  int anAttrIndex = int(myAttrs.size()) + 1;
+  TDF_Label anAttrLab = myLab.FindChild(anAttrIndex);
   ModelAPI_Attribute* anAttr = 0;
   if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
     anAttr = new Model_AttributeDocRef(anAttrLab);
@@ -203,7 +204,7 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin
   }
   if (anAttr) {
     aResult = std::shared_ptr<ModelAPI_Attribute>(anAttr);
-    myAttrs[theID] = aResult;
+    myAttrs[theID] = std::pair<AttributePtr, int>(aResult, anAttrIndex);
     anAttr->setObject(myObject);
     anAttr->setID(theID);
   } else {
@@ -217,10 +218,9 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin
 #define GET_ATTRIBUTE_BY_ID(ATTR_TYPE, METHOD_NAME) \
   std::shared_ptr<ATTR_TYPE> Model_Data::METHOD_NAME(const std::string& theID) { \
     std::shared_ptr<ATTR_TYPE> aRes; \
-    std::map<std::string, AttributePtr >::iterator aFound = \
-      myAttrs.find(theID); \
+    AttributeMap::iterator aFound = myAttrs.find(theID); \
     if (aFound != myAttrs.end()) { \
-      aRes = std::dynamic_pointer_cast<ATTR_TYPE>(aFound->second); \
+      aRes = std::dynamic_pointer_cast<ATTR_TYPE>(aFound->second.first); \
     } \
     return aRes; \
   }
@@ -246,15 +246,14 @@ std::shared_ptr<ModelAPI_Attribute> Model_Data::attribute(const std::string& the
   std::shared_ptr<ModelAPI_Attribute> aResult;
   if (myAttrs.find(theID) == myAttrs.end())  // no such attribute
     return aResult;
-  return myAttrs[theID];
+  return myAttrs[theID].first;
 }
 
 const std::string& Model_Data::id(const std::shared_ptr<ModelAPI_Attribute>& theAttr)
 {
-  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr =
-    myAttrs.begin();
+  AttributeMap::iterator anAttr = myAttrs.begin();
   for (; anAttr != myAttrs.end(); anAttr++) {
-    if (anAttr->second == theAttr)
+    if (anAttr->second.first == theAttr)
       return anAttr->first;
   }
   // not found
@@ -278,11 +277,11 @@ bool Model_Data::isValid()
 std::list<std::shared_ptr<ModelAPI_Attribute> > Model_Data::attributes(const std::string& theType)
 {
   std::list<std::shared_ptr<ModelAPI_Attribute> > aResult;
-  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter =
-    myAttrs.begin();
+  AttributeMap::iterator anAttrsIter = myAttrs.begin();
   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
-    if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
-      aResult.push_back(anAttrsIter->second);
+    AttributePtr anAttr = anAttrsIter->second.first;
+    if (theType.empty() || anAttr->attributeType() == theType) {
+      aResult.push_back(anAttr);
     }
   }
   return aResult;
@@ -291,10 +290,10 @@ std::list<std::shared_ptr<ModelAPI_Attribute> > Model_Data::attributes(const std
 std::list<std::string> Model_Data::attributesIDs(const std::string& theType)
 {
   std::list<std::string> aResult;
-  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter =
-    myAttrs.begin();
+  AttributeMap::iterator anAttrsIter = myAttrs.begin();
   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
-    if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
+    AttributePtr anAttr = anAttrsIter->second.first;
+    if (theType.empty() || anAttr->attributeType() == theType) {
       aResult.push_back(anAttrsIter->first);
     }
   }
@@ -380,7 +379,7 @@ void Model_Data::erase()
           if (aReferenced->get() && (*aReferenced)->data()->isValid()) {
             std::shared_ptr<Model_Data> aData =
               std::dynamic_pointer_cast<Model_Data>((*aReferenced)->data());
-            aData->removeBackReference(myAttrs[anAttrIter->first]);
+            aData->removeBackReference(myAttrs[anAttrIter->first].first);
           }
         }
       }
@@ -469,9 +468,9 @@ void Model_Data::eraseBackReferences()
     aRes->setIsConcealed(false);
 }
 
-void Model_Data::removeBackReference(FeaturePtr theFeature, std::string theAttrID)
+void Model_Data::removeBackReference(ObjectPtr theObject, std::string theAttrID)
 {
-  AttributePtr anAttribute = theFeature->data()->attribute(theAttrID);
+  AttributePtr anAttribute = theObject->data()->attribute(theAttrID);
   removeBackReference(anAttribute);
 }
 
@@ -493,10 +492,7 @@ void Model_Data::removeBackReference(AttributePtr theAttr)
 void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID,
    const bool theApplyConcealment)
 {
-  // it is possible to add the same attribute twice: may be last time the owner was not Stable...
-  AttributePtr anAttribute = theFeature->data()->attribute(theAttrID);
-  if (myRefsToMe.find(anAttribute) == myRefsToMe.end())
-    myRefsToMe.insert(theFeature->data()->attribute(theAttrID));
+  addBackReference(ObjectPtr(theFeature), theAttrID);
 
   if (theApplyConcealment &&  theFeature->isStable() &&
       ModelAPI_Session::get()->validators()->isConcealed(theFeature->getKind(), theAttrID)) {
@@ -511,6 +507,14 @@ void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID,
   }
 }
 
+void Model_Data::addBackReference(ObjectPtr theObject, std::string theAttrID)
+{
+  // it is possible to add the same attribute twice: may be last time the owner was not Stable...
+  AttributePtr anAttribute = theObject->data()->attribute(theAttrID);
+  if (myRefsToMe.find(anAttribute) == myRefsToMe.end())
+    myRefsToMe.insert(anAttribute);
+}
+
 void Model_Data::updateConcealmentFlag()
 {
   std::set<AttributePtr>::iterator aRefsIter = myRefsToMe.begin();
@@ -585,21 +589,22 @@ void Model_Data::referencesToObjects(
     static_cast<Model_ValidatorsFactory*>(ModelAPI_Session::get()->validators());
   FeaturePtr aMyFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myObject);
 
-  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = myAttrs.begin();
+  AttributeMap::iterator anAttrIt = myAttrs.begin();
   std::list<ObjectPtr> aReferenced; // not inside of cycle to avoid excess memory management
-  for(; anAttr != myAttrs.end(); anAttr++) {
+  for(; anAttrIt != myAttrs.end(); anAttrIt++) {
+    AttributePtr anAttr = anAttrIt->second.first;
     // skip not-case attributes, that really may refer to anything not-used (issue 671)
-    if (aMyFeature.get() && !aValidators->isCase(aMyFeature, anAttr->second->id()))
+    if (aMyFeature.get() && !aValidators->isCase(aMyFeature, anAttr->id()))
       continue;
 
-    std::string aType = anAttr->second->attributeType();
+    std::string aType = anAttr->attributeType();
     if (aType == ModelAPI_AttributeReference::typeId()) { // reference to object
       std::shared_ptr<ModelAPI_AttributeReference> aRef = std::dynamic_pointer_cast<
-          ModelAPI_AttributeReference>(anAttr->second);
+          ModelAPI_AttributeReference>(anAttr);
       aReferenced.push_back(aRef->value());
     } else if (aType == ModelAPI_AttributeRefAttr::typeId()) { // reference to attribute or object
       std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = std::dynamic_pointer_cast<
-          ModelAPI_AttributeRefAttr>(anAttr->second);
+          ModelAPI_AttributeRefAttr>(anAttr);
       if (aRef->isObject()) {
         aReferenced.push_back(aRef->object());
       } else {
@@ -608,20 +613,20 @@ void Model_Data::referencesToObjects(
           aReferenced.push_back(anAttr->owner());
       }
     } else if (aType == ModelAPI_AttributeRefList::typeId()) { // list of references
-      aReferenced = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttr->second)->list();
+      aReferenced = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttr)->list();
     } else if (aType == ModelAPI_AttributeSelection::typeId()) { // selection attribute
       std::shared_ptr<ModelAPI_AttributeSelection> aRef = std::dynamic_pointer_cast<
-          ModelAPI_AttributeSelection>(anAttr->second);
+          ModelAPI_AttributeSelection>(anAttr);
       aReferenced.push_back(aRef->context());
     } else if (aType == ModelAPI_AttributeSelectionList::typeId()) { // list of selection attributes
       std::shared_ptr<ModelAPI_AttributeSelectionList> aRef = std::dynamic_pointer_cast<
-          ModelAPI_AttributeSelectionList>(anAttr->second);
-      for(int a = aRef->size() - 1; a >= 0; a--) {
+          ModelAPI_AttributeSelectionList>(anAttr);
+      for(int a = 0, aSize = aRef->size(); a < aSize; ++a) {
         aReferenced.push_back(aRef->value(a)->context());
       }
     } else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
       std::shared_ptr<ModelAPI_AttributeRefAttrList> aRefAttr = std::dynamic_pointer_cast<
-          ModelAPI_AttributeRefAttrList>(anAttr->second);
+          ModelAPI_AttributeRefAttrList>(anAttr);
       std::list<std::pair<ObjectPtr, AttributePtr> > aRefs = aRefAttr->list();
       std::list<std::pair<ObjectPtr, AttributePtr> >::const_iterator anIt = aRefs.begin(),
                                                                      aLast = aRefs.end();
@@ -630,25 +635,25 @@ void Model_Data::referencesToObjects(
       }
     } else if (aType == ModelAPI_AttributeInteger::typeId()) { // integer attribute
       AttributeIntegerPtr anAttribute =
-          std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(anAttr->second);
+          std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(anAttr);
       std::set<std::string> anUsedParameters = anAttribute->usedParameters();
       std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
       aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
     } else if (aType == ModelAPI_AttributeDouble::typeId()) { // double attribute
       AttributeDoublePtr anAttribute =
-          std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr->second);
+          std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
       std::set<std::string> anUsedParameters = anAttribute->usedParameters();
       std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
       aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
     } else if (aType == GeomDataAPI_Point::typeId()) { // point attribute
       AttributePointPtr anAttribute =
-        std::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->second);
+        std::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr);
       std::set<std::string> anUsedParameters = usedParameters(anAttribute);
       std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
       aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
     } else if (aType == GeomDataAPI_Point2D::typeId()) { // point attribute
       AttributePoint2DPtr anAttribute =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->second);
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr);
       std::set<std::string> anUsedParameters = usedParameters(anAttribute);
       std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
       aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
@@ -656,7 +661,8 @@ void Model_Data::referencesToObjects(
       continue; // nothing to do, not reference
 
     if (!aReferenced.empty()) {
-      theRefs.push_back(std::pair<std::string, std::list<ObjectPtr> >(anAttr->first, aReferenced));
+      theRefs.push_back(
+          std::pair<std::string, std::list<ObjectPtr> >(anAttrIt->first, aReferenced));
       aReferenced.clear();
     }
   }
@@ -752,3 +758,15 @@ std::shared_ptr<ModelAPI_Object> Model_Data::owner()
 {
   return myObject;
 }
+
+bool Model_Data::isPrecedingAttribute(const std::string& theAttribute1,
+                                      const std::string& theAttribute2) const
+{
+  AttributeMap::const_iterator aFound1 = myAttrs.find(theAttribute1);
+  AttributeMap::const_iterator aFound2 = myAttrs.find(theAttribute2);
+  if (aFound2 == myAttrs.end())
+    return true;
+  else if (aFound1 == myAttrs.end())
+    return false;
+  return aFound1->second.second < aFound2->second.second;
+}
index a5f9af4ed2c6eaf203f571db5eb1fca36ce2e28c..836c4d646c038bec34d17fed3e914ee03b55cce5 100644 (file)
@@ -36,6 +36,7 @@
 #include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
 #include <ModelAPI_Object.h>
 
 #include <TDF_Label.hxx>
@@ -58,9 +59,12 @@ class ModelAPI_Attribute;
 
 class Model_Data : public ModelAPI_Data
 {
+  typedef std::map<std::string, std::pair<std::shared_ptr<ModelAPI_Attribute>, int> > AttributeMap;
+
   TDF_Label myLab;  ///< label of the feature in the document
   /// All attributes of the object identified by the attribute ID
-  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> > myAttrs;
+  /// (the attribute is stored together with its index in the feature)
+  AttributeMap myAttrs;
   /// Array of flags of this data
   Handle(TDataStd_BooleanArray) myFlags;
 
@@ -268,7 +272,7 @@ private:
   /// Removes a back reference (with identifier which attribute references to this object)
   /// \param theFeature feature referenced to this
   /// \param theAttrID identifier of the attribute that is references from theFeature to this
-  void removeBackReference(FeaturePtr theFeature, std::string theAttrID);
+  void removeBackReference(ObjectPtr theObject, std::string theAttrID);
   /// Removes a back reference (by the attribute)
   /// \param theAttr the referenced attribute
   void removeBackReference(AttributePtr theAttr);
@@ -278,6 +282,10 @@ private:
   /// \param theApplyConcealment applies consealment flag changes
   void addBackReference(FeaturePtr theFeature, std::string theAttrID,
     const bool theApplyConcealment = true);
+  /// Adds a back reference to an object
+  /// \param theObject object referenced to this
+  /// \param theAttrID identifier of the attribute that is references from theFolder to this
+  void addBackReference(ObjectPtr theObject, std::string theAttrID);
 
   /// Makes the concealment flag up to date for this object-owner.
   MODEL_EXPORT virtual void updateConcealmentFlag();
@@ -290,17 +298,25 @@ private:
   /// Sets the displayed/hidden state of the object. If it is changed, sends the "redisplay"
   /// signal.
   MODEL_EXPORT virtual void setDisplayed(const bool theDisplay);
+
+  /// Returns \c true if theAttribute1 is going earlier than theAttribute2 in the data
+  MODEL_EXPORT virtual bool isPrecedingAttribute(const std::string& theAttribute1,
+                                                 const std::string& theAttribute2) const;
 };
 
 /// Generic method to register back reference, used in referencing attributes.
 /// Without concealment change, it will be done later, on synchronization.
 #define ADD_BACK_REF(TARGET) \
   if (TARGET.get() != NULL) { \
+    std::shared_ptr<Model_Data> aTargetData = \
+        std::dynamic_pointer_cast<Model_Data>((TARGET)->data()); \
     FeaturePtr anAttributeOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner()); \
-    if (anAttributeOwnerFeature.get()) { \
-      std::shared_ptr<Model_Data> aTargetData = std::dynamic_pointer_cast<Model_Data>( \
-        (TARGET)->data()); \
+    if (anAttributeOwnerFeature.get()) \
       aTargetData->addBackReference(anAttributeOwnerFeature, id(), false); \
+    else { \
+      FolderPtr anAttributeOwnerFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(owner()); \
+      if (anAttributeOwnerFolder.get()) \
+        aTargetData->addBackReference(ObjectPtr(anAttributeOwnerFolder), id()); \
     } \
   }
 
@@ -308,11 +324,15 @@ private:
 /// Without concealment change, it will be done later, on synchronization.
 #define REMOVE_BACK_REF(TARGET) \
   if (TARGET.get() != NULL) { \
+    std::shared_ptr<Model_Data> aTargetData = \
+        std::dynamic_pointer_cast<Model_Data>((TARGET)->data()); \
     FeaturePtr anAttOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner()); \
-    if (anAttOwnerFeature.get()) { \
-      std::shared_ptr<Model_Data> aTargetData = std::dynamic_pointer_cast<Model_Data>( \
-        (TARGET)->data()); \
+    if (anAttOwnerFeature.get()) \
       aTargetData->removeBackReference(anAttOwnerFeature, id()); \
+    else { \
+      FolderPtr anAttributeOwnerFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(owner()); \
+      if (anAttributeOwnerFolder.get()) \
+        aTargetData->removeBackReference(ObjectPtr(anAttributeOwnerFolder), id()); \
     } \
   }
 
index 03959c2ff7ea4eecc838ee652f242609828701e4..c422dcf526c085a63aef1a4116c1ec1dddf5384e 100755 (executable)
@@ -925,7 +925,7 @@ FeaturePtr Model_Document::addFeature(std::string theID, const bool theMakeCurre
       int aSubs = aComp->numberOfSubs(false);
       for(int a = 0; a < aSubs; a++) {
         FeaturePtr aSub = aComp->subFeature(a, false);
-        if (myObjs->isLater(aSub, aCurrent)) {
+        if (aSub && myObjs->isLater(aSub, aCurrent)) {
           isModified =  true;
           aCurrent = aSub;
         }
@@ -1031,9 +1031,11 @@ std::shared_ptr<Model_Document> Model_Document::subDoc(int theDocID)
     Model_Application::getApplication()->document(theDocID));
 }
 
-ObjectPtr Model_Document::object(const std::string& theGroupID, const int theIndex)
+ObjectPtr Model_Document::object(const std::string& theGroupID,
+                                 const int theIndex,
+                                 const bool theAllowFolder)
 {
-  return myObjs->object(theGroupID, theIndex);
+  return myObjs->object(theGroupID, theIndex, theAllowFolder);
 }
 
 std::shared_ptr<ModelAPI_Object> Model_Document::objectByName(
@@ -1042,16 +1044,17 @@ std::shared_ptr<ModelAPI_Object> Model_Document::objectByName(
   return myObjs->objectByName(theGroupID, theName);
 }
 
-const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject)
+const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject,
+                                const bool theAllowFolder)
 {
-  return myObjs->index(theObject);
+  return myObjs->index(theObject, theAllowFolder);
 }
 
-int Model_Document::size(const std::string& theGroupID)
+int Model_Document::size(const std::string& theGroupID, const bool theAllowFolder)
 {
   if (myObjs == 0) // may be on close
     return 0;
-  return myObjs->size(theGroupID);
+  return myObjs->size(theGroupID, theAllowFolder);
 }
 
 std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theVisible)
@@ -1255,6 +1258,51 @@ std::shared_ptr<ModelAPI_ResultParameter> Model_Document::createParameter(
   return myObjs->createParameter(theFeatureData, theIndex);
 }
 
+std::shared_ptr<ModelAPI_Folder> Model_Document::addFolder(
+    std::shared_ptr<ModelAPI_Feature> theAddBefore)
+{
+  return myObjs->createFolder(theAddBefore);
+}
+
+void Model_Document::removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder)
+{
+  if (theFolder)
+    myObjs->removeFolder(theFolder);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderAbove(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+  return myObjs->findFolder(theFeatures, false);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderBelow(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+  return myObjs->findFolder(theFeatures, true);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder)
+{
+  return myObjs->findContainingFolder(theFeature, theIndexInFolder);
+}
+
+bool Model_Document::moveToFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const std::shared_ptr<ModelAPI_Folder>& theFolder)
+{
+  return myObjs->moveToFolder(theFeatures, theFolder);
+}
+
+bool Model_Document::removeFromFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const bool theBefore)
+{
+  return myObjs->removeFromFolder(theFeatures, theBefore);
+}
+
 std::shared_ptr<ModelAPI_Feature> Model_Document::feature(
     const std::shared_ptr<ModelAPI_Result>& theResult)
 {
@@ -1271,25 +1319,82 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2)
   return TDF_LabelMapHasher::IsEqual(theLab1, theLab2);
 }
 
+// searches in this document feature that contains this label
+FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) {
+  TDF_Label aCurrentLab = theLab;
+  while(aCurrentLab.Depth() > 3)
+    aCurrentLab = aCurrentLab.Father();
+  return myObjs->feature(aCurrentLab);
+}
+
 void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName)
 {
-  myNamingNames[theName] = theLabel;
+  std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
+
+  if (aFind != myNamingNames.end()) { // to avoid duplicate-labels
+    // to keep correct order inspite of history line management
+    std::list<TDF_Label>::iterator anAddAfterThis = aFind->second.end();
+    FeaturePtr anAddedFeature = featureByLab(theLabel);
+    std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
+    while(aLabIter != aFind->second.end()) {
+      if (theLabel.IsEqual(*aLabIter)) {
+        std::list<TDF_Label>::iterator aTmpIter = aLabIter;
+        aLabIter++;
+        aFind->second.erase(aTmpIter);
+      } else {
+        FeaturePtr aCurFeature = featureByLab(*aLabIter);
+        if (aCurFeature.get() && anAddedFeature.get() &&
+            myObjs->isLater(anAddedFeature, aCurFeature))
+          anAddAfterThis = aLabIter;
+
+        aLabIter++;
+      }
+    }
+    if (anAddAfterThis != aFind->second.end()) {
+      anAddAfterThis++;
+      if (anAddAfterThis != aFind->second.end()) {
+        myNamingNames[theName].insert(anAddAfterThis, theLabel); // inserts before anAddAfterThis
+        return;
+      }
+    }
+  }
+  myNamingNames[theName].push_back(theLabel);
 }
 
-void Model_Document::changeNamingName(const std::string theOldName, const std::string theNewName)
+void Model_Document::changeNamingName(const std::string theOldName,
+                                      const std::string theNewName,
+                                      const TDF_Label& theLabel)
 {
-  std::map<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theOldName);
+  std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theOldName);
   if (aFind != myNamingNames.end()) {
-    myNamingNames[theNewName] = aFind->second;
-    myNamingNames.erase(theOldName);
+    std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
+    for(; aLabIter != aFind->second.end(); aLabIter++) {
+      if (theLabel.IsEqual(*aLabIter)) { // found the label
+        myNamingNames[theNewName].push_back(theLabel);
+        if (aFind->second.size() == 1) { // only one element, so, just change the name
+          myNamingNames.erase(theOldName);
+        } else { // remove from the list
+          aFind->second.erase(aLabIter);
+        }
+        return;
+      }
+    }
   }
 }
 
-TDF_Label Model_Document::findNamingName(std::string theName)
+TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theContext)
 {
-  std::map<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theName);
+  std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
   if (aFind != myNamingNames.end()) {
-    return aFind->second;
+      std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
+      for(; aLabIter != aFind->second.rend(); aLabIter++) {
+        if (theContext.get()) {
+          // context is defined and not like this, so, skip
+          if (theContext == myObjs->object(aLabIter->Father()))
+            return *aLabIter;
+        }
+      }
+      return *(aFind->second.rbegin()); // no more variannts, so, return the last
   }
   // not found exact name, try to find by sub-components
   std::string::size_type aSlash = theName.rfind('/');
@@ -1298,24 +1403,33 @@ TDF_Label Model_Document::findNamingName(std::string theName)
     aFind = myNamingNames.find(anObjName);
     if (aFind != myNamingNames.end()) {
       TCollection_ExtendedString aSubName(theName.substr(aSlash + 1).c_str());
-      // searching sub-labels with this name
-      TDF_ChildIDIterator aNamesIter(aFind->second, TDataStd_Name::GetID(), Standard_True);
-      for(; aNamesIter.More(); aNamesIter.Next()) {
-        Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value());
-        if (aName->Get() == aSubName)
-          return aName->Label();
-      }
-      // 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 && aSuffixPos != aSubName.Length()) {
-        TCollection_ExtendedString anIndexStr = aSubName.Split(aSuffixPos);
-        aSubName.Remove(aSuffixPos);
-        aNamesIter.Initialize(aFind->second, TDataStd_Name::GetID(), Standard_True);
+      // iterate all possible same-named labels starting from the last one (the recent)
+      std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
+      for(; aLabIter != aFind->second.rend(); aLabIter++) {
+        if (theContext.get()) {
+          // context is defined and not like this, so, skip
+          if (theContext != myObjs->object(aLabIter->Father()))
+            continue;
+        }
+        // searching sub-labels with this name
+        TDF_ChildIDIterator aNamesIter(*aLabIter, TDataStd_Name::GetID(), Standard_True);
         for(; aNamesIter.More(); aNamesIter.Next()) {
           Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value());
-          if (aName->Get() == aSubName) {
+          if (aName->Get() == aSubName)
             return aName->Label();
+        }
+        // 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 && aSuffixPos != aSubName.Length()) {
+          TCollection_ExtendedString anIndexStr = aSubName.Split(aSuffixPos);
+          aSubName.Remove(aSuffixPos);
+          aNamesIter.Initialize(*aLabIter, TDataStd_Name::GetID(), Standard_True);
+          for(; aNamesIter.More(); aNamesIter.Next()) {
+            Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value());
+            if (aName->Get() == aSubName) {
+              return aName->Label();
+            }
           }
         }
       }
@@ -1324,9 +1438,98 @@ TDF_Label Model_Document::findNamingName(std::string theName)
   return TDF_Label(); // not found
 }
 
-ResultPtr Model_Document::findByName(const std::string theName)
+bool Model_Document::isLaterByDep(FeaturePtr theThis, FeaturePtr theOther) {
+  // check dependencies first: if theOther depends on theThis, theThis is not later
+  std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+  theOther->data()->referencesToObjects(aRefs);
+  std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >::iterator
+    aRefIt = aRefs.begin();
+  for(; aRefIt != aRefs.end(); aRefIt++) {
+    std::list<ObjectPtr>::iterator aRefObjIt = aRefIt->second.begin();
+    for(; aRefObjIt != aRefIt->second.end(); aRefObjIt++) {
+      ObjectPtr aRefObj = *aRefObjIt;
+      if (aRefObj.get()) {
+        FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObj);
+        if (!aRefFeat.get()) { // take feature of the result
+          aRefFeat = feature(std::dynamic_pointer_cast<ModelAPI_Result>(aRefObj));
+        }
+        if (aRefFeat.get() && aRefFeat == theThis) {
+          return false; // other references to this, so this later than other
+        }
+      }
+    }
+  }
+  return myObjs->isLater(theThis, theOther);
+}
+
+int Model_Document::numberOfNameInHistory(
+  const ObjectPtr& theNameObject, const TDF_Label& theStartFrom)
 {
-  return myObjs->findByName(theName);
+  std::map<std::string, std::list<TDF_Label> >::iterator aFind =
+    myNamingNames.find(theNameObject->data()->name());
+  if (aFind == myNamingNames.end() || aFind->second.size() < 2) {
+    return 1; // no need to specify the name by additional identifiers
+  }
+  // get the feature of the object for relative compare
+  FeaturePtr aStart = myObjs->feature(theStartFrom);
+  if (!aStart.get()) // strange, but can not find feature by the label
+    return 1;
+  // feature that contain result with this name
+  FeaturePtr aNameFeature;
+  ResultPtr aNameResult = std::dynamic_pointer_cast<ModelAPI_Result>(theNameObject);
+  if (aNameResult)
+    aNameFeature = myObjs->feature(aNameResult);
+  else
+    aNameFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theNameObject);
+  // iterate all labels with this name to find the nearest just before or equal relative
+  std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
+  for(; aLabIter != aFind->second.rend(); aLabIter++) {
+    FeaturePtr aLabFeat = featureByLab(*aLabIter);
+    if (!aLabFeat.get())
+      continue;
+    if (isLaterByDep(aStart, aLabFeat)) // skip also start: its result don't used
+      break;
+  }
+  int aResIndex = 1;
+  for(; aLabIter != aFind->second.rend(); aLabIter++) {
+    FeaturePtr aLabFeat = featureByLab(*aLabIter);
+    if (!aLabFeat.get())
+      continue;
+    if (aLabFeat == aNameFeature || isLaterByDep(aNameFeature, aLabFeat))
+      return aResIndex;
+    aResIndex++;
+  }
+  return aResIndex; // strange
+}
+
+ResultPtr Model_Document::findByName(
+  std::string& theName, std::string& theSubShapeName, bool& theUniqueContext)
+{
+  int aNumInHistory = 0;
+  std::string aName = theName;
+  ResultPtr aRes = myObjs->findByName(aName);
+  theUniqueContext = !(aRes.get() && myNamingNames.find(aName) != myNamingNames.end());
+  while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index
+    aNumInHistory++;
+    aName = aName.substr(1);
+    aRes = myObjs->findByName(aName);
+  }
+  if (aNumInHistory) {
+    std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(aName);
+    if (aFind != myNamingNames.end() && aFind->second.size() > aNumInHistory) {
+      std::list<TDF_Label>::reverse_iterator aLibIt = aFind->second.rbegin();
+      for(; aNumInHistory != 0; aNumInHistory--)
+        aLibIt++;
+      const TDF_Label& aResultLab = *aLibIt;
+      aRes = std::dynamic_pointer_cast<ModelAPI_Result>(myObjs->object(aResultLab.Father()));
+      if (aRes) { // modify the incoming names
+        if (!theSubShapeName.empty())
+          theSubShapeName = theSubShapeName.substr(theName.size() - aName.size());
+        theName = aName;
+      }
+    }
+  }
+  return aRes;
 }
 
 std::list<std::shared_ptr<ModelAPI_Feature> > Model_Document::allFeatures()
@@ -1334,6 +1537,11 @@ std::list<std::shared_ptr<ModelAPI_Feature> > Model_Document::allFeatures()
   return myObjs->allFeatures();
 }
 
+std::list<std::shared_ptr<ModelAPI_Object> > Model_Document::allObjects()
+{
+  return myObjs->allObjects();
+}
+
 void Model_Document::setActive(const bool theFlag)
 {
   if (theFlag != myIsActive) {
@@ -1662,3 +1870,15 @@ void Model_Document::eraseAllFeatures()
   if (myObjs)
     myObjs->eraseAllFeatures();
 }
+
+void Model_Document::setExecuteFeatures(const bool theFlag)
+{
+  myExecuteFeatures = theFlag;
+  const std::set<int> aSubs = subDocuments();
+  std::set<int>::iterator aSubIter = aSubs.begin();
+  for (; aSubIter != aSubs.end(); aSubIter++) {
+    if (!subDoc(*aSubIter)->myObjs)
+      continue;
+    subDoc(*aSubIter)->setExecuteFeatures(theFlag);
+  }
+}
index 67e48301e9fca54d78df0138c05b2875d51de8c8..0f6b32ed6e8093863a453ecf130ee42d200155d7 100644 (file)
@@ -122,8 +122,10 @@ class Model_Document : public ModelAPI_Document
 
   //! Returns the object index in the group. Object must be visible. Otherwise returns -1.
   //! \param theObject object of this document
+  //! \param theAllowFolder take into account grouping feature by folders
   //! \returns index started from zero, or -1 if object is invisible or belongs to another document
-  MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Object> theObject);
+  MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Object> theObject,
+                                       const bool theAllowFolder = false);
 
   //! Internal sub-document by ID
   MODEL_EXPORT virtual std::shared_ptr<Model_Document> subDoc(int theDocID);
@@ -137,10 +139,15 @@ class Model_Document : public ModelAPI_Document
   //! Returns the feature in the group by the index (started from zero)
   //! \param theGroupID group that contains a feature
   //! \param theIndex zero-based index of feature in the group
-  MODEL_EXPORT virtual ObjectPtr object(const std::string& theGroupID, const int theIndex);
+  //! \param theAllowFolder take into account grouping feature by folders
+  MODEL_EXPORT virtual ObjectPtr object(const std::string& theGroupID,
+                                        const int theIndex,
+                                        const bool theAllowFolder = false);
 
   //! Returns the number of features in the group
-  MODEL_EXPORT virtual int size(const std::string& theGroupID);
+  //! \param theGroupID group of objects
+  //! \param theAllowFolder take into account grouping feature by folders
+  MODEL_EXPORT virtual int size(const std::string& theGroupID, const bool theAllowFolder = false);
 
   //! Returns the feature that is currently edited in this document, normally
   //! this is the latest created feature
@@ -199,24 +206,76 @@ class Model_Document : public ModelAPI_Document
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Feature>
     feature(const std::shared_ptr<ModelAPI_Result>& theResult);
 
+  //! Creates a folder (group of the features in the object browser)
+  //! \param theAddBefore a feature, the folder is added before
+  //!                     (if empty, the folder is added after the last feature)
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> addFolder(
+      std::shared_ptr<ModelAPI_Feature> theAddBefore = std::shared_ptr<ModelAPI_Feature>());
+  //! Removes the folder from the document (all features in the folder will be kept).
+  MODEL_EXPORT virtual void removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder);
+  //! Search a folder above the list of features applicable to store them
+  //! (it means the list of features stored in the folder should be consequential)
+  //! \return Empty pointer if there is no applicable folder
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findFolderAbove(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures);
+  //! Search a folder below the list of features applicable to store them
+  //! (it means the list of features stored in the folder should be consequential)
+  //! \return Empty pointer if there is no applicable folder
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findFolderBelow(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures);
+  //! Search a folder containing the given feature.
+  //! Addtionally calculates a zero-based index of the feature in this folder.
+  //! \param theFeature feature to search
+  //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+  //! \return the folder containing the feature or empty pointer if the feature is top-level.
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder);
+  //! Add a list of features to the folder. The correctness of the adding is not performed
+  //! (such checks have been done in corresponding find.. method).
+  //! \return \c true if the movement is successfull
+  MODEL_EXPORT virtual bool moveToFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const std::shared_ptr<ModelAPI_Folder>& theFolder);
+  //! Remove features from the folder
+  //! \param theFeatures list of features to be removed
+  //! \param theBefore   extract features before the folder (this parameter is applicable only
+  //!                    when all features in the folder are taking out,
+  //!                    in other cases the direction is taken automatically)
+  //! \return \c true if the features have been moved out
+  MODEL_EXPORT virtual bool removeFromFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const bool theBefore = true);
+
   ///! Returns true if parametric updater need to execute feature on recomputartion
   ///! On abort, undo or redo it is not necessary: results in document are updated automatically
-  bool& executeFeatures() {return myExecuteFeatures;}
+  bool executeFeatures() {return myExecuteFeatures;}
+
+  ///! On abort, undo or redo it is not necessary: results in document are updated automatically
+  void setExecuteFeatures(const bool theFlag);
 
   //! Registers the name of the shape for the topological naming needs
   void addNamingName(const TDF_Label theLabel, std::string theName);
   //! Updates the name of some object
-  void changeNamingName(std::string theOldName, const std::string theNewName);
+  void changeNamingName(std::string theOldName, const std::string theNewName,
+    const TDF_Label& theLabel);
   //! Returns the label, keeper of the name  for the topological naming needs
-  TDF_Label findNamingName(std::string theName);
+  TDF_Label findNamingName(std::string theName, ResultPtr theContext);
+  //! Returns the number of the name in the history relatively to the given object (by label).
+  //! Start from 1 (this object).
+  int numberOfNameInHistory(const ObjectPtr& theNameObject, const TDF_Label& theStartFrom);
   //! Returns the result by name of the result (names of results must be unique, used for naming
   //! selection by name.
-  ResultPtr findByName(const std::string theName);
+  ResultPtr findByName(std::string& theName, std::string& theSubShapeName, bool& theUniqueContext);
 
   ///! Returns all features of the document including the hidden features which are not in
   ///! history. Not very fast method, for calling once, not in big cycles.
   MODEL_EXPORT virtual std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures();
 
+  //! Returns all objects of the document including the hidden features which are not in
+  //! history. Not very fast method, for calling once, not in big cycles.
+  MODEL_EXPORT virtual std::list<std::shared_ptr<ModelAPI_Object> > allObjects();
+
   /// Returns the global identifier of the current transaction (needed for the update algo)
   MODEL_EXPORT virtual int transactionID();
   /// Increases the transaction ID
@@ -309,6 +368,12 @@ class Model_Document : public ModelAPI_Document
   /// Label that constains structures for selection of constructions of another document
   TDF_Label extConstructionsLabel() const;
 
+  /// searches in this document feature that contains this label
+  FeaturePtr featureByLab(const TDF_Label& theLab);
+
+  /// returns true if theThis is later in the features trre and dependencies than theOther
+  bool isLaterByDep(FeaturePtr theThis, FeaturePtr theOther);
+
   friend class Model_Application;
   friend class Model_Session;
   friend class Model_Update;
@@ -351,7 +416,8 @@ class Model_Document : public ModelAPI_Document
   std::list<Transaction> myRedos;
 
   //! Optimization for finding the shape-label by topological naming names
-  std::map<std::string, TDF_Label> myNamingNames;
+  //! The name -> list of labels where this name is appeared (the last created name is last here)
+  std::map<std::string, std::list<TDF_Label> > myNamingNames;
   //! If it is true, features are not executed on update (on abort, undo, redo)
   bool myExecuteFeatures;
 
index c8e1ca72f1e6f0738d49b03a5084697a04c0ba82..3a933410b1bdb405ffb5fead5fb907c5e5e9e414 100644 (file)
 #include <TDF_LabelMap.hxx>
 #include <TDF_ListIteratorOfLabelList.hxx>
 
+static const std::string& groupNameFoldering(const std::string& theGroupID,
+                                             const bool theAllowFolder)
+{
+  if (theAllowFolder) {
+    static const std::string anOutOfFolderName = std::string("__") + ModelAPI_Feature::group();
+    static const std::string aDummyName;
+    return theGroupID == ModelAPI_Feature::group() ? anOutOfFolderName : aDummyName;
+  }
+  return theGroupID;
+}
+
+
 static const int TAG_OBJECTS = 2;  // tag of the objects sub-tree (features, results)
 
 // feature sub-labels
@@ -69,7 +81,7 @@ void Model_Objects::setOwner(DocumentPtr theDoc)
   myDoc = theDoc;
   // update all fields and recreate features and result objects if needed
   TDF_LabelList aNoUpdated;
-  synchronizeFeatures(aNoUpdated, true, true, true, true);
+  synchronizeFeatures(aNoUpdated, true, false, true, true);
   myHistory.clear();
 }
 
@@ -92,6 +104,15 @@ Model_Objects::~Model_Objects()
     aFeature->erase();
     myFeatures.UnBind(aFeaturesIter.Key());
   }
+  while (!myFolders.IsEmpty()) {
+    NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator aFoldersIter(myFolders);
+    ObjectPtr aFolder = aFoldersIter.Value();
+    static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+    ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Folder::group());
+    ModelAPI_EventCreator::get()->sendUpdated(aFolder, EVENT_DISP);
+    aFolder->erase();
+    myFolders.UnBind(aFoldersIter.Key());
+  }
   myHistory.clear();
   aLoop->activateFlushes(isActive);
   // erase update, because features are destroyed and update should not performed for them anywhere
@@ -367,9 +388,8 @@ void Model_Objects::clearHistory(ObjectPtr theObj)
 {
   if (theObj.get()) {
     const std::string aGroup = theObj->groupName();
-    std::map<std::string, std::vector<ObjectPtr> >::iterator aHIter = myHistory.find(aGroup);
-    if (aHIter != myHistory.end())
-      myHistory.erase(aHIter); // erase from map => this means that it is not synchronized
+    updateHistory(aGroup);
+
     if (theObj->groupName() == ModelAPI_Feature::group()) { // clear results group of the feature
       FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
       std::string aResultGroup = featureResultGroup(aFeature);
@@ -387,9 +407,12 @@ void Model_Objects::createHistory(const std::string& theGroupID)
 {
   std::map<std::string, std::vector<ObjectPtr> >::iterator aHIter = myHistory.find(theGroupID);
   if (aHIter == myHistory.end()) {
-    std::vector<ObjectPtr> aResult = std::vector<ObjectPtr>();
+    std::vector<ObjectPtr> aResult;
+    std::vector<ObjectPtr> aResultOutOfFolder;
+    FeaturePtr aLastFeatureInFolder;
     // iterate the array of references and get feature by feature from the array
     bool isFeature = theGroupID == ModelAPI_Feature::group();
+    bool isFolder = theGroupID == ModelAPI_Folder::group();
     Handle(TDataStd_ReferenceArray) aRefs;
     if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
       for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) {
@@ -401,6 +424,9 @@ void Model_Objects::createHistory(const std::string& theGroupID)
           if (isFeature) { // here may be also disabled features
             if (!isSub && aFeature->isInHistory()) {
               aResult.push_back(aFeature);
+              // the feature is out of the folders
+              if (aLastFeatureInFolder.get() == NULL)
+                aResultOutOfFolder.push_back(aFeature);
             }
           } else if (!aFeature->isDisabled()) { // iterate all results of not-disabled feature
             // construction results of sub-features should not be in the tree
@@ -418,12 +444,40 @@ void Model_Objects::createHistory(const std::string& theGroupID)
               }
             }
           }
+
+          // the feature closes the folder, so the next features will be treated as out-of-folder
+          if (aLastFeatureInFolder.get() && aLastFeatureInFolder == aFeature)
+            aLastFeatureInFolder = FeaturePtr();
+
+        } else {
+          // it may be a folder
+          ObjectPtr aFolder = folder(aRefs->Value(a));
+          if (aFolder.get()) {
+            // store folder information for the Features group only
+            if (isFeature || isFolder) {
+              aResult.push_back(aFolder);
+              if (!isFolder)
+                aResultOutOfFolder.push_back(aFolder);
+            }
+
+            // get the last feature in the folder
+            AttributeReferencePtr aLastFeatAttr =
+                aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+            if (aLastFeatAttr)
+              aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+          }
         }
       }
     }
     // to be sure that isConcealed did not update the history (issue 1089) during the iteration
-    if (myHistory.find(theGroupID) == myHistory.end())
+    if (myHistory.find(theGroupID) == myHistory.end()) {
       myHistory[theGroupID] = aResult;
+
+      // store the features placed out of any folder
+      const std::string& anOutOfFolderGroupID = groupNameFoldering(theGroupID, true);
+      if (!anOutOfFolderGroupID.empty())
+        myHistory[anOutOfFolderGroupID] = aResultOutOfFolder;
+    }
   }
 }
 
@@ -435,8 +489,21 @@ void Model_Objects::updateHistory(const std::shared_ptr<ModelAPI_Object> theObje
 void Model_Objects::updateHistory(const std::string theGroup)
 {
   std::map<std::string, std::vector<ObjectPtr> >::iterator aHIter = myHistory.find(theGroup);
-  if (aHIter != myHistory.end())
+  if (aHIter != myHistory.end()) {
     myHistory.erase(aHIter); // erase from map => this means that it is not synchronized
+
+    // erase history for the group of objects placed out of any folder
+    const std::string& anOutOfFolderGroupID = groupNameFoldering(theGroup, true);
+    if (!anOutOfFolderGroupID.empty())
+      myHistory.erase(anOutOfFolderGroupID);
+  }
+}
+
+ObjectPtr Model_Objects::folder(TDF_Label theLabel) const
+{
+  if (myFolders.IsBound(theLabel))
+    return myFolders.Find(theLabel);
+  return ObjectPtr();
 }
 
 FeaturePtr Model_Objects::feature(TDF_Label theLabel) const
@@ -489,12 +556,15 @@ ObjectPtr Model_Objects::object(TDF_Label theLabel)
   return FeaturePtr();  // not found
 }
 
-ObjectPtr Model_Objects::object(const std::string& theGroupID, const int theIndex)
+ObjectPtr Model_Objects::object(const std::string& theGroupID,
+                                const int theIndex,
+                                const bool theAllowFolder)
 {
   if (theIndex == -1)
     return ObjectPtr();
   createHistory(theGroupID);
-  return myHistory[theGroupID][theIndex];
+  const std::string& aGroupID = groupNameFoldering(theGroupID, theAllowFolder);
+  return aGroupID.empty() ? myHistory[theGroupID][theIndex] : myHistory[aGroupID][theIndex];
 }
 
 std::shared_ptr<ModelAPI_Object> Model_Objects::objectByName(
@@ -538,10 +608,19 @@ std::shared_ptr<ModelAPI_Object> Model_Objects::objectByName(
   return ObjectPtr();
 }
 
-const int Model_Objects::index(std::shared_ptr<ModelAPI_Object> theObject)
+const int Model_Objects::index(std::shared_ptr<ModelAPI_Object> theObject,
+                               const bool theAllowFolder)
 {
   std::string aGroup = theObject->groupName();
+  // treat folder as feature
+  if (aGroup == ModelAPI_Folder::group())
+    aGroup = ModelAPI_Feature::group();
   createHistory(aGroup);
+
+  // get the group of features out of folder (if enabled)
+  if (theAllowFolder && !groupNameFoldering(aGroup, theAllowFolder).empty())
+    aGroup = groupNameFoldering(aGroup, theAllowFolder);
+
   std::vector<ObjectPtr>& allObjs = myHistory[aGroup];
   std::vector<ObjectPtr>::iterator anObjIter = allObjs.begin(); // iterate to search object
   for(int anIndex = 0; anObjIter != allObjs.end(); anObjIter++, anIndex++) {
@@ -552,10 +631,11 @@ const int Model_Objects::index(std::shared_ptr<ModelAPI_Object> theObject)
   return -1;
 }
 
-int Model_Objects::size(const std::string& theGroupID)
+int Model_Objects::size(const std::string& theGroupID, const bool theAllowFolder)
 {
   createHistory(theGroupID);
-  return int(myHistory[theGroupID].size());
+  const std::string& aGroupID = groupNameFoldering(theGroupID, theAllowFolder);
+  return aGroupID.empty() ? int(myHistory[theGroupID].size()) : int(myHistory[aGroupID].size());
 }
 
 void Model_Objects::allResults(const std::string& theGroupID, std::list<ResultPtr>& theResults)
@@ -587,6 +667,13 @@ TDF_Label Model_Objects::featuresLabel() const
   return myMain.FindChild(TAG_OBJECTS);
 }
 
+static std::string composeName(const std::string& theFeatureKind, const int theIndex)
+{
+  std::stringstream aNameStream;
+  aNameStream << theFeatureKind << "_" << theIndex;
+  return aNameStream.str();
+}
+
 void Model_Objects::setUniqueName(FeaturePtr theFeature)
 {
   if (!theFeature->data()->name().empty())
@@ -600,9 +687,7 @@ void Model_Objects::setUniqueName(FeaturePtr theFeature)
       aNumObjects++;
   }
   // generate candidate name
-  std::stringstream aNameStream;
-  aNameStream << theFeature->getKind() << "_" << aNumObjects + 1;
-  aName = aNameStream.str();
+  aName = composeName(theFeature->getKind(), aNumObjects + 1);
   // check this is unique, if not, increase index by 1
   for (aFIter.Initialize(myFeatures); aFIter.More();) {
     FeaturePtr aFeature = aFIter.Value();
@@ -617,9 +702,7 @@ void Model_Objects::setUniqueName(FeaturePtr theFeature)
 
     if (isSameName) {
       aNumObjects++;
-      std::stringstream aNameStream;
-      aNameStream << theFeature->getKind() << "_" << aNumObjects + 1;
-      aName = aNameStream.str();
+      aName = composeName(theFeature->getKind(), aNumObjects + 1);
       // reinitialize iterator to make sure a new name is unique
       aFIter.Initialize(myFeatures);
     } else
@@ -628,6 +711,28 @@ void Model_Objects::setUniqueName(FeaturePtr theFeature)
   theFeature->data()->setName(aName);
 }
 
+void Model_Objects::setUniqueName(FolderPtr theFolder)
+{
+  if (!theFolder->name().empty())
+    return; // name is already defined
+
+  int aNbFolders = myFolders.Size();
+  std::string aName = composeName(ModelAPI_Folder::ID(), aNbFolders);
+
+  // check the uniqueness of the name
+  NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator anIt(myFolders);
+  while (anIt.More()) {
+    if (anIt.Value()->data()->name() == aName) {
+      aName = composeName(ModelAPI_Folder::ID(), aNbFolders);
+      // reinitialize iterator to make sure a new name is unique
+      anIt.Initialize(myFolders);
+    } else
+      anIt.Next();
+  }
+
+  theFolder->data()->setName(aName);
+}
+
 void Model_Objects::initData(ObjectPtr theObj, TDF_Label theLab, const int theTag)
 {
   std::shared_ptr<Model_Data> aData(new Model_Data);
@@ -638,6 +743,10 @@ void Model_Objects::initData(ObjectPtr theObj, TDF_Label theLab, const int theTa
   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
   if (aFeature.get()) {
     setUniqueName(aFeature);  // must be before "initAttributes" because duplicate part uses name
+  } else { // is it a folder?
+    FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(theObj);
+    if (aFolder)
+      setUniqueName(aFolder);
   }
   theObj->initAttributes();
 }
@@ -680,16 +789,23 @@ void Model_Objects::synchronizeFeatures(
   }
 
   // update all objects by checking are they on labels or not
-  std::set<FeaturePtr> aNewFeatures, aKeptFeatures;
+  std::set<ObjectPtr> aNewFeatures, aKeptFeatures;
   TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID());
   for (; aLabIter.More(); aLabIter.Next()) {
     TDF_Label aFeatureLabel = aLabIter.Value()->Label();
-    FeaturePtr aFeature;
-    if (!myFeatures.IsBound(aFeatureLabel)) {  // a new feature is inserted
+    if (!myFeatures.IsBound(aFeatureLabel) && !myFolders.IsBound(aFeatureLabel)) {
+      // a new feature or folder is inserted
+
+      std::string aFeatureID = TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
+                               aLabIter.Value())->Get()).ToCString();
+      bool isFolder = aFeatureID == ModelAPI_Folder::ID();
+
+      std::shared_ptr<Model_Session> aSession =
+          std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get());
+
       // create a feature
-      aFeature = std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get())->createFeature(
-        TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(aLabIter.Value())->Get())
-        .ToCString(), anOwner);
+      ObjectPtr aFeature = isFolder ? ObjectPtr(new ModelAPI_Folder)
+                                    : ObjectPtr(aSession->createFeature(aFeatureID, anOwner));
       if (!aFeature.get()) {
         // somethig is wrong, most probably, the opened document has invalid structure
         Events_InfoMessage("Model_Objects", "Invalid type of object in the document").send();
@@ -698,7 +814,10 @@ void Model_Objects::synchronizeFeatures(
       }
       aFeature->init();
       // this must be before "setData" to redo the sketch line correctly
-      myFeatures.Bind(aFeatureLabel, aFeature);
+      if (isFolder)
+        myFolders.Bind(aFeatureLabel, aFeature);
+      else
+        myFeatures.Bind(aFeatureLabel, std::dynamic_pointer_cast<ModelAPI_Feature>(aFeature));
       aNewFeatures.insert(aFeature);
       initData(aFeature, aFeatureLabel, TAG_FEATURE_ARGUMENTS);
       updateHistory(aFeature);
@@ -706,18 +825,25 @@ void Model_Objects::synchronizeFeatures(
       // event: model is updated
       ModelAPI_EventCreator::get()->sendUpdated(aFeature, aCreateEvent);
     } else {  // nothing is changed, both iterators are incremented
-      aFeature = myFeatures.Find(aFeatureLabel);
-      aKeptFeatures.insert(aFeature);
+      ObjectPtr anObject;
+      FeaturePtr aFeature;
+      if (myFeatures.Find(aFeatureLabel, aFeature)) {
+        aKeptFeatures.insert(aFeature);
+        anObject = aFeature;
+      } else
+        if (myFolders.Find(aFeatureLabel, anObject))
+          aKeptFeatures.insert(anObject);
+
       if (anUpdatedMap.Contains(aFeatureLabel)) {
         if (!theOpen) { // on abort/undo/redo reinitialize attributes if something is changed
           std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
-            aFeature->data()->attributes("");
+            anObject->data()->attributes("");
           std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
           for(; anAttr != anAttrs.end(); anAttr++)
             (*anAttr)->reinit();
         }
-        ModelAPI_EventCreator::get()->sendUpdated(aFeature, anUpdateEvent);
-        if (aFeature->getKind() == "Parameter") {
+        ModelAPI_EventCreator::get()->sendUpdated(anObject, anUpdateEvent);
+        if (aFeature && aFeature->getKind() == "Parameter") {
           // if parameters are changed, update the results (issue 937)
           const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
           std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
@@ -756,6 +882,24 @@ void Model_Objects::synchronizeFeatures(
     } else
       aFIter.Next();
   }
+  // verify folders are checked: if not => is was removed
+  for (NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator aFldIt(myFolders);
+       aFldIt.More(); aFldIt.Next()) {
+    ObjectPtr aCurObj = aFldIt.Value();
+    if (aKeptFeatures.find(aCurObj) == aKeptFeatures.end() &&
+        aNewFeatures.find(aCurObj) == aNewFeatures.end()) {
+      ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Folder::group());
+      // results of this feature must be redisplayed (hided)
+      // redisplay also removed feature (used for sketch and AISObject)
+      ModelAPI_EventCreator::get()->sendUpdated(aCurObj, aRedispEvent);
+      updateHistory(aCurObj);
+      aCurObj->erase();
+
+      // unbind after the "erase" call: on abort sketch
+      // is removes sub-objects that corrupts aFIter
+      myFolders.UnBind(aFldIt.Key());
+    }
+  }
 
   if (theUpdateReferences) {
     synchronizeBackRefs();
@@ -783,8 +927,8 @@ void Model_Objects::synchronizeFeatures(
     myHistory.clear();
   }
 
-  if (theExecuteFeatures)
-    anOwner->executeFeatures() = false;
+  if (!theExecuteFeatures)
+    anOwner->setExecuteFeatures(false);
   aLoop->activateFlushes(isActive);
 
   if (theFlush) {
@@ -797,8 +941,8 @@ void Model_Objects::synchronizeFeatures(
     aLoop->flush(aRedispEvent);
     aLoop->flush(aToHideEvent);
   }
-  if (theExecuteFeatures)
-    anOwner->executeFeatures() = true;
+  if (!theExecuteFeatures)
+    anOwner->setExecuteFeatures(true);
 }
 
 /// synchronises back references for the given object basing on the collected data
@@ -813,7 +957,10 @@ void Model_Objects::synchronizeBackRefsForObject(const std::set<AttributePtr>& t
   for(; aNewIter != theNewRefs.end(); aNewIter++) {
     if (aData->refsToMe().find(*aNewIter) == aData->refsToMe().end()) {
       FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aNewIter)->owner());
-      aData->addBackReference(aRefFeat, (*aNewIter)->id());
+      if (aRefFeat)
+        aData->addBackReference(aRefFeat, (*aNewIter)->id());
+      else // add back reference to a folder
+        aData->addBackReference((*aNewIter)->owner(), (*aNewIter)->id());
     }
   }
   if (theNewRefs.size() != aData->refsToMe().size()) { // some back ref must be removed
@@ -852,6 +999,29 @@ void Model_Objects::synchronizeBackRefsForObject(const std::set<AttributePtr>& t
   aData->updateConcealmentFlag();
 }
 
+static void collectReferences(std::shared_ptr<ModelAPI_Data> theData,
+                              std::map<ObjectPtr, std::set<AttributePtr> >& theRefs)
+{
+  if (theData.get()) {
+    std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+    theData->referencesToObjects(aRefs);
+    std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefsIt = aRefs.begin();
+    for(; aRefsIt != aRefs.end(); aRefsIt++) {
+      std::list<ObjectPtr>::iterator aRefTo = aRefsIt->second.begin();
+      for(; aRefTo != aRefsIt->second.end(); aRefTo++) {
+        if (*aRefTo) {
+          std::map<ObjectPtr, std::set<AttributePtr> >::iterator aFound = theRefs.find(*aRefTo);
+          if (aFound == theRefs.end()) {
+            theRefs[*aRefTo] = std::set<AttributePtr>();
+            aFound = theRefs.find(*aRefTo);
+          }
+          aFound->second.insert(theData->attribute(aRefsIt->first));
+        }
+      }
+    }
+  }
+}
+
 void Model_Objects::synchronizeBackRefs()
 {
   // collect all back references in the separated container: to update everything at once,
@@ -862,25 +1032,12 @@ void Model_Objects::synchronizeBackRefs()
   NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeatures(myFeatures);
   for(; aFeatures.More(); aFeatures.Next()) {
     FeaturePtr aFeature = aFeatures.Value();
-    std::shared_ptr<Model_Data> aFData = std::dynamic_pointer_cast<Model_Data>(aFeature->data());
-    if (aFData.get()) {
-      std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
-      aFData->referencesToObjects(aRefs);
-      std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefsIt = aRefs.begin();
-      for(; aRefsIt != aRefs.end(); aRefsIt++) {
-        std::list<ObjectPtr>::iterator aRefTo = aRefsIt->second.begin();
-        for(; aRefTo != aRefsIt->second.end(); aRefTo++) {
-          if (*aRefTo) {
-            std::map<ObjectPtr, std::set<AttributePtr> >::iterator aFound = allRefs.find(*aRefTo);
-            if (aFound == allRefs.end()) {
-              allRefs[*aRefTo] = std::set<AttributePtr>();
-              aFound = allRefs.find(*aRefTo);
-            }
-            aFound->second.insert(aFeature->data()->attribute(aRefsIt->first));
-          }
-        }
-      }
-    }
+    collectReferences(aFeature->data(), allRefs);
+  }
+  NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator aFolders(myFolders);
+  for(; aFolders.More(); aFolders.Next()) {
+    ObjectPtr aFolder = aFolders.Value();
+    collectReferences(aFolder->data(), allRefs);
   }
   // second iteration: just compare back-references with existing in features and results
   for(aFeatures.Initialize(myFeatures); aFeatures.More(); aFeatures.Next()) {
@@ -933,22 +1090,57 @@ TDF_Label Model_Objects::resultLabel(
   return aData->label().Father().FindChild(TAG_FEATURE_RESULTS).FindChild(theResultIndex + 1);
 }
 
+bool Model_Objects::hasCustomName(DataPtr theFeatureData,
+                                  ResultPtr theResult,
+                                  int theResultIndex,
+                                  std::string& theParentName) const
+{
+  ResultCompSolidPtr aCompSolidRes =
+      std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theFeatureData->owner());
+  if (aCompSolidRes) {
+    FeaturePtr anOwner = ModelAPI_Feature::feature(theResult->data()->owner());
+
+    // names of sub-solids in CompSolid should be default (for example,
+    // result of boolean operation 'Boolean_1' is a CompSolid which is renamed to 'MyBOOL',
+    // however, sub-elements of 'MyBOOL' should be named 'Boolean_1_1', 'Boolean_1_2' etc.)
+    std::ostringstream aDefaultName;
+    aDefaultName << anOwner->name();
+    // compute default name of CompSolid (name of feature + index of CompSolid's result)
+    int aCompSolidResultIndex = 0;
+    const std::list<ResultPtr>& aResults = anOwner->results();
+    for (std::list<ResultPtr>::const_iterator anIt = aResults.begin();
+         anIt != aResults.end(); ++anIt, ++aCompSolidResultIndex)
+      if (aCompSolidRes == *anIt)
+        break;
+    aDefaultName << "_" << (aCompSolidResultIndex + 1);
+    theParentName = aDefaultName.str();
+    return false;
+  }
+
+  theParentName = ModelAPI_Tools::getDefaultName(theResult, theResultIndex);
+  return true;
+}
+
 void Model_Objects::storeResult(std::shared_ptr<ModelAPI_Data> theFeatureData,
-                                 std::shared_ptr<ModelAPI_Result> theResult,
-                                 const int theResultIndex)
+                                std::shared_ptr<ModelAPI_Result> theResult,
+                                const int theResultIndex)
 {
   theResult->init();
   theResult->setDoc(myDoc);
   initData(theResult, resultLabel(theFeatureData, theResultIndex), TAG_FEATURE_ARGUMENTS);
   if (theResult->data()->name().empty()) {
     // if was not initialized, generate event and set a name
-    std::stringstream aNewName;
-    aNewName<<theFeatureData->name();
-    // if there are several results (issue #899: any number of result),
-    // add unique prefix starting from second
-    if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
-      aNewName<<"_"<<theResultIndex + 1;
-    theResult->data()->setName(aNewName.str());
+    std::string aNewName = theFeatureData->name();
+    if (!hasCustomName(theFeatureData, theResult, theResultIndex, aNewName)) {
+      std::stringstream aName;
+      aName << aNewName;
+      // if there are several results (issue #899: any number of result),
+      // add unique prefix starting from second
+      if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
+        aName << "_" << theResultIndex + 1;
+      aNewName = aName.str();
+    }
+    theResult->data()->setName(aNewName);
   }
 }
 
@@ -1076,6 +1268,442 @@ std::shared_ptr<ModelAPI_ResultParameter> Model_Objects::createParameter(
   return aResult;
 }
 
+std::shared_ptr<ModelAPI_Folder> Model_Objects::createFolder(
+    const std::shared_ptr<ModelAPI_Feature>& theBeforeThis)
+{
+  FolderPtr aFolder(new ModelAPI_Folder);
+  if (!aFolder)
+    return aFolder;
+
+  TDF_Label aFeaturesLab = featuresLabel();
+  TDF_Label aFolderLab = aFeaturesLab.NewChild();
+  // store feature in the features array: before "initData" because in macro features
+  // in initData it creates new features, appeared later than this
+  TDF_Label aPrevFeatureLab;
+  if (theBeforeThis.get()) { // searching for the previous feature label
+    std::shared_ptr<Model_Data> aPrevData =
+        std::dynamic_pointer_cast<Model_Data>(theBeforeThis->data());
+    if (aPrevData.get()) {
+      aPrevFeatureLab = nextLabel(aPrevData->label().Father(), true);
+    }
+  } else { // find the label of the last feature
+    Handle(TDataStd_ReferenceArray) aRefs;
+    if (aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+      aPrevFeatureLab = aRefs->Value(aRefs->Upper());
+  }
+  AddToRefArray(aFeaturesLab, aFolderLab, aPrevFeatureLab);
+
+  // keep the feature ID to restore document later correctly
+  TDataStd_Comment::Set(aFolderLab, ModelAPI_Folder::ID().c_str());
+  myFolders.Bind(aFolderLab, aFolder);
+  // must be before the event sending: for OB the feature is already added
+  updateHistory(ModelAPI_Folder::group());
+  updateHistory(ModelAPI_Feature::group());
+
+  // must be after binding to the map because of "Box" macro feature that
+  // creates other features in "initData"
+  initData(aFolder, aFolderLab, TAG_FEATURE_ARGUMENTS);
+  // event: folder is added, must be before "initData" to update OB correctly on Duplicate:
+  // first new part, then the content
+  static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+  ModelAPI_EventCreator::get()->sendUpdated(aFolder, anEvent);
+
+  return aFolder;
+}
+
+void Model_Objects::removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder)
+{
+  std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theFolder->data());
+  if (!aData.get() || !aData->isValid())
+    return;
+
+  // this must be before erase since theFolder erasing removes all information about it
+  clearHistory(theFolder);
+  // erase fields
+  theFolder->erase();
+
+  TDF_Label aFolderLabel = aData->label().Father();
+  if (myFolders.IsBound(aFolderLabel))
+    myFolders.UnBind(aFolderLabel);
+
+  static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  ModelAPI_EventCreator::get()->sendUpdated(theFolder, EVENT_DISP);
+  // erase all attributes under the label of feature
+  aFolderLabel.ForgetAllAttributes();
+  // remove it from the references array
+  RemoveFromRefArray(featuresLabel(), aFolderLabel);
+  // event: feature is deleted
+  ModelAPI_EventCreator::get()->sendDeleted(theFolder->document(), ModelAPI_Folder::group());
+  updateHistory(ModelAPI_Folder::group());
+  updateHistory(ModelAPI_Feature::group());
+}
+
+// Returns one of the limiting features of the list
+static FeaturePtr limitingFeature(std::list<FeaturePtr>& theFeatures, const bool isLast)
+{
+  FeaturePtr aFeature;
+  if (isLast) {
+    aFeature = theFeatures.back();
+    theFeatures.pop_back();
+  } else {
+    aFeature = theFeatures.front();
+    theFeatures.pop_front();
+  }
+  return aFeature;
+}
+
+// Verify the feature is sub-element in composite feature or it is not used in the history
+static bool isSkippedFeature(FeaturePtr theFeature)
+{
+  bool isSub = ModelAPI_Tools::compositeOwner(theFeature).get() != NULL;
+  return isSub || (theFeature && !theFeature->isInHistory());
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Objects::findFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const bool theBelow)
+{
+  if (theFeatures.empty())
+    return FolderPtr(); // nothing to move
+
+  TDF_Label aFeaturesLab = featuresLabel();
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+    return FolderPtr(); // no reference array (something is wrong)
+
+  std::list<std::shared_ptr<ModelAPI_Feature> > aFeatures = theFeatures;
+  std::shared_ptr<ModelAPI_Feature> aLimitingFeature = limitingFeature(aFeatures, theBelow);
+
+  std::shared_ptr<Model_Data> aData =
+      std::static_pointer_cast<Model_Data>(aLimitingFeature->data());
+  if (!aData || !aData->isValid())
+    return FolderPtr(); // invalid feature
+
+  // label of the first feature in the list for fast searching
+  TDF_Label aFirstFeatureLabel = aData->label().Father();
+
+  // find a folder above the features and
+  // check the given features represent a sequential list of objects following the folder
+  FolderPtr aFoundFolder;
+  TDF_Label aLastFeatureInFolder;
+  int aRefIndex = aRefs->Lower();
+  for(; aRefIndex <= aRefs->Upper(); ++aRefIndex) { // iterate all existing features
+    TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+    if (IsEqual(aCurLabel, aFirstFeatureLabel))
+      break; // no need to continue searching
+
+    // searching the folder below, just continue to search last feature from the list
+    if (theBelow)
+      continue;
+
+    // if feature is in sub-component, skip it
+    FeaturePtr aCurFeature = feature(aCurLabel);
+    if (isSkippedFeature(aCurFeature))
+      continue;
+
+    if (!aLastFeatureInFolder.IsNull()) {
+      if (IsEqual(aCurLabel, aLastFeatureInFolder))
+        aLastFeatureInFolder.Nullify(); // the last feature in the folder is achived
+      continue;
+    }
+
+    aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aCurLabel));
+    if (aFoundFolder) {
+      AttributeReferencePtr aLastFeatAttr =
+          aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+      if (aLastFeatAttr) {
+        // setup iterating inside a folder to find last feature
+        ObjectPtr aLastFeature = aLastFeatAttr->value();
+        if (aLastFeature) {
+          aData = std::static_pointer_cast<Model_Data>(aLastFeature->data());
+          if (aData && aData->isValid())
+            aLastFeatureInFolder = aData->label().Father();
+        }
+      }
+    }
+  }
+
+  if (theBelow && aRefIndex < aRefs->Upper()) {
+    TDF_Label aLabel;
+    // skip following features which are sub-components or not in history
+    for (int anIndex = aRefIndex + 1; anIndex <= aRefs->Upper(); ++anIndex) {
+      aLabel = aRefs->Value(anIndex);
+      FeaturePtr aCurFeature = feature(aLabel);
+      if (!isSkippedFeature(aCurFeature))
+        break;
+    }
+    // check the next object is a folder
+    aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aLabel));
+  }
+
+  if (!aLastFeatureInFolder.IsNull() || // the last feature of the folder above is not found
+      !aFoundFolder)
+    return FolderPtr();
+
+  // check the given features are sequential list
+  int aStep = theBelow ? -1 : 1;
+  for (aRefIndex += aStep;
+       !aFeatures.empty() && aRefIndex >= aRefs->Lower() && aRefIndex <= aRefs->Upper();
+       aRefIndex += aStep) {
+    TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+    // if feature is in sub-component, skip it
+    FeaturePtr aCurFeature = feature(aCurLabel);
+    if (isSkippedFeature(aCurFeature))
+      continue;
+
+    aLimitingFeature = limitingFeature(aFeatures, theBelow);
+    if (!aCurFeature->data()->isEqual(aLimitingFeature->data()))
+      return FolderPtr(); // not a sequential list
+  }
+
+  return aFoundFolder;
+}
+
+bool Model_Objects::moveToFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const std::shared_ptr<ModelAPI_Folder>& theFolder)
+{
+  if (theFeatures.empty() || !theFolder)
+    return false;
+
+  // labels for the folder and last feature in the list
+  TDF_Label aFolderLabel, aLastFeatureLabel;
+  std::shared_ptr<Model_Data> aData =
+      std::static_pointer_cast<Model_Data>(theFolder->data());
+  if (aData && aData->isValid())
+    aFolderLabel = aData->label().Father();
+  aData = std::static_pointer_cast<Model_Data>(theFeatures.back()->data());
+  if (aData && aData->isValid())
+    aLastFeatureLabel = aData->label().Father();
+
+  if (aFolderLabel.IsNull() || aLastFeatureLabel.IsNull())
+    return false;
+
+  AttributeReferencePtr aFirstFeatAttr =
+      theFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  AttributeReferencePtr aLastFeatAttr =
+      theFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+  bool initFirstAttr = !aFirstFeatAttr->value().get();
+  bool initLastAttr  = !aLastFeatAttr->value().get();
+
+  // check the folder is below the list of features
+  bool isFolderBelow = false;
+  TDF_Label aFeaturesLab = featuresLabel();
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+    return false; // no reference array (something is wrong)
+  for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) {
+    TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+    if (aCurLabel == aFolderLabel)
+      break; // folder is above the features
+    else if (aCurLabel == aLastFeatureLabel) {
+      isFolderBelow = true;
+      break;
+    }
+  }
+
+  if (isFolderBelow) {
+    aData = std::static_pointer_cast<Model_Data>(theFeatures.front()->data());
+    if (!aData || !aData->isValid())
+      return false;
+    TDF_Label aPrevFeatureLabel = aData->label().Father();
+    // label of the feature before the first feature in the list
+    for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex)
+      if (aPrevFeatureLabel == aRefs->Value(aRefIndex)) {
+        if (aRefIndex == aRefs->Lower())
+          aPrevFeatureLabel.Nullify();
+        else
+          aPrevFeatureLabel = aRefs->Value(aRefIndex - 1);
+        break;
+      }
+
+    // move the folder in the list of references before the first feature
+    RemoveFromRefArray(aFeaturesLab, aFolderLabel);
+    AddToRefArray(aFeaturesLab, aFolderLabel, aPrevFeatureLabel);
+    // update first feature of the folder
+    initFirstAttr = true;
+  } else {
+    // update last feature of the folder
+    initLastAttr = true;
+  }
+
+  if (initFirstAttr)
+    aFirstFeatAttr->setValue(theFeatures.front());
+  if (initLastAttr)
+    aLastFeatAttr->setValue(theFeatures.back());
+
+  updateHistory(ModelAPI_Feature::group());
+  return true;
+}
+
+static FolderPtr inFolder(const FeaturePtr& theFeature, const std::string& theFolderAttr)
+{
+  const std::set<AttributePtr>& aRefs = theFeature->data()->refsToMe();
+  for (std::set<AttributePtr>::iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt) {
+    if ((*anIt)->id() != theFolderAttr)
+      continue;
+
+    ObjectPtr anOwner = (*anIt)->owner();
+    FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(anOwner);
+    if (aFolder.get())
+      return aFolder;
+  }
+  return FolderPtr();
+}
+
+static FolderPtr isExtractionCorrect(const FolderPtr& theFirstFeatureFolder,
+                                     const FolderPtr& theLastFeatureFolder,
+                                     bool& isExtractBefore)
+{
+  if (theFirstFeatureFolder.get()) {
+    if (theLastFeatureFolder.get())
+      return theFirstFeatureFolder == theLastFeatureFolder ? theFirstFeatureFolder : FolderPtr();
+    else
+      isExtractBefore = true;
+    return theFirstFeatureFolder;
+  } else if (theLastFeatureFolder.get()) {
+    isExtractBefore = false;
+    return theLastFeatureFolder;
+  }
+  // no folder found
+  return FolderPtr();
+}
+
+bool Model_Objects::removeFromFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const bool theBefore)
+{
+  if (theFeatures.empty())
+    return false;
+
+  FolderPtr aFirstFeatureFolder =
+      inFolder(theFeatures.front(), ModelAPI_Folder::FIRST_FEATURE_ID());
+  FolderPtr aLastFeatureFolder =
+      inFolder(theFeatures.back(),  ModelAPI_Folder::LAST_FEATURE_ID());
+
+  bool isExtractBeforeFolder = theBefore;
+  FolderPtr aFoundFolder =
+      isExtractionCorrect(aFirstFeatureFolder, aLastFeatureFolder, isExtractBeforeFolder);
+  if (!aFoundFolder)
+    return false; // list of features cannot be extracted
+
+  // references of the current folder
+  ObjectPtr aFolderStartFeature;
+  ObjectPtr aFolderEndFeature;
+  if (aFirstFeatureFolder != aLastFeatureFolder) {
+    aFolderStartFeature = aFoundFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID())->value();
+    aFolderEndFeature   = aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID())->value();
+  }
+
+  FeaturePtr aFeatureToFind;
+  if (isExtractBeforeFolder) {
+    aFeatureToFind = theFeatures.back();
+    // if the last feature is composite, obtain its last sub-feature for correct positioning of
+    // the folder in the reference array when theFeatures will be extracted before folder
+    CompositeFeaturePtr aComposite =
+        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeatureToFind);
+    if (aComposite)
+      aFeatureToFind = aComposite->subFeature(aComposite->numberOfSubs() - 1);
+  } else
+    aFeatureToFind = theFeatures.front();
+  std::shared_ptr<Model_Data> aData =
+      std::static_pointer_cast<Model_Data>(aFeatureToFind->data());
+  if (!aData || !aData->isValid())
+    return false;
+  TDF_Label aLabelToFind = aData->label().Father();
+
+  // search the label in the list of references
+  TDF_Label aFeaturesLab = featuresLabel();
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+    return false; // no reference array (something is wrong)
+  int aRefIndex = aRefs->Lower();
+  for (; aRefIndex <= aRefs->Upper(); ++aRefIndex)
+    if (aRefs->Value(aRefIndex) == aLabelToFind)
+      break;
+
+  // update folder position
+  if (isExtractBeforeFolder) {
+    aData = std::dynamic_pointer_cast<Model_Data>(aFoundFolder->data());
+    TDF_Label aFolderLabel = aData->label().Father();
+    TDF_Label aPrevFeatureLabel = aRefs->Value(aRefIndex);
+    // update start reference of the folder
+    if (aFolderStartFeature.get())
+      aFolderStartFeature = feature(aRefs->Value(aRefIndex + 1));
+    // move the folder in the list of references after the last feature from the list
+    RemoveFromRefArray(aFeaturesLab, aFolderLabel);
+    AddToRefArray(aFeaturesLab, aFolderLabel, aPrevFeatureLabel);
+  } else {
+    // update end reference of the folder
+    if (aFolderEndFeature.get())
+      aFolderEndFeature = feature(aRefs->Value(aRefIndex - 1));
+  }
+
+  // update folder references
+  aFoundFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID())->setValue(aFolderStartFeature);
+  aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID())->setValue(aFolderEndFeature);
+
+  updateHistory(ModelAPI_Feature::group());
+  return true;
+}
+
+FolderPtr Model_Objects::findContainingFolder(const FeaturePtr& theFeature, int& theIndexInFolder)
+{
+  // search the label in the list of references
+  TDF_Label aFeaturesLab = featuresLabel();
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+    return FolderPtr(); // no reference array (something is wrong)
+
+  std::shared_ptr<Model_Data> aData =
+      std::static_pointer_cast<Model_Data>(theFeature->data());
+  if (!aData || !aData->isValid())
+    return FolderPtr();
+  TDF_Label aLabelToFind = aData->label().Father();
+
+  theIndexInFolder = -1;
+  FolderPtr aFoundFolder;
+  TDF_Label aLastFeatureLabel;
+
+  for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) {
+    TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+    if (isSkippedFeature(feature(aCurLabel)))
+      continue;
+
+    if (aFoundFolder)
+      ++theIndexInFolder;
+
+    if (aCurLabel == aLabelToFind) // the feature is reached
+      return aFoundFolder;
+
+    if (!aFoundFolder) {
+      // if the current label refers to a folder, feel all necessary data
+      aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aCurLabel));
+      if (aFoundFolder) {
+        theIndexInFolder = -1;
+
+        AttributeReferencePtr aLastRef =
+            aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+        if (aLastRef->value()) {
+          aData = std::static_pointer_cast<Model_Data>(aLastRef->value()->data());
+          if (aData && aData->isValid())
+            aLastFeatureLabel = aData->label().Father();
+        } else // folder is empty
+          aFoundFolder = FolderPtr();
+      }
+    } else if (aLastFeatureLabel == aCurLabel) {
+      // folder is finished, clear all stored data
+      theIndexInFolder = -1;
+      aFoundFolder = FolderPtr();
+    }
+  }
+
+  // folder is not found
+  theIndexInFolder = -1;
+  return FolderPtr();
+}
+
+
 std::shared_ptr<ModelAPI_Feature> Model_Objects::feature(
     const std::shared_ptr<ModelAPI_Result>& theResult)
 {
@@ -1187,6 +1815,8 @@ void Model_Objects::updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& t
 
 ResultPtr Model_Objects::findByName(const std::string theName)
 {
+  ResultPtr aResult;
+  FeaturePtr aResFeature; // keep feature to return the latest one
   NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator anObjIter(myFeatures);
   for(; anObjIter.More(); anObjIter.Next()) {
     FeaturePtr& aFeature = anObjIter.ChangeValue();
@@ -1198,13 +1828,33 @@ ResultPtr Model_Objects::findByName(const std::string theName)
     for (; aRIter != allResults.cend(); aRIter++) {
       ResultPtr aRes = *aRIter;
       if (aRes.get() && aRes->data() && aRes->data()->isValid() && !aRes->isDisabled() &&
-          aRes->data()->name() == theName) {
-        return aRes;
+          aRes->data()->name() == theName)
+      {
+        if (!aResult.get() || isLater(aFeature, aResFeature)) { // select the latest
+          aResult = aRes;
+          aResFeature = aFeature;
+        }
       }
     }
   }
-  // not found
-  return ResultPtr();
+  return aResult;
+}
+
+TDF_Label Model_Objects::nextLabel(TDF_Label theCurrent, const bool theReverse)
+{
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+    for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { // iterate all existing features
+      TDF_Label aCurLab = aRefs->Value(a);
+      if (aCurLab.IsEqual(theCurrent)) {
+        a += theReverse ? -1 : 1;
+        if (a >= aRefs->Lower() && a <= aRefs->Upper())
+          return aRefs->Value(a);
+        break; // finish iiteration: it's last feature
+      }
+    }
+  }
+  return TDF_Label();
 }
 
 FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theReverse)
@@ -1212,18 +1862,9 @@ FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theRever
   std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theCurrent->data());
   if (aData.get() && aData->isValid()) {
     TDF_Label aFeatureLabel = aData->label().Father();
-    Handle(TDataStd_ReferenceArray) aRefs;
-    if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
-      for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { // iterate all existing features
-        TDF_Label aCurLab = aRefs->Value(a);
-        if (aCurLab.IsEqual(aFeatureLabel)) {
-          a += theReverse ? -1 : 1;
-          if (a >= aRefs->Lower() && a <= aRefs->Upper())
-            return feature(aRefs->Value(a));
-          break; // finish iiteration: it's last feature
-        }
-      }
-    }
+    TDF_Label aNextLabel = nextLabel(aFeatureLabel, theReverse);
+    if (!aNextLabel.IsNull())
+      return feature(aNextLabel);
   }
   return FeaturePtr(); // not found, last, or something is wrong
 }
@@ -1271,6 +1912,22 @@ bool Model_Objects::isLater(FeaturePtr theLater, FeaturePtr theCurrent) const
   return false; // not found, or something is wrong
 }
 
+std::list<std::shared_ptr<ModelAPI_Object> > Model_Objects::allObjects()
+{
+  std::list<std::shared_ptr<ModelAPI_Object> > aResult;
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+    for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) {
+      ObjectPtr anObject = object(aRefs->Value(a));
+      if (!anObject.get()) // is it a folder?
+        anObject = folder(aRefs->Value(a));
+      if (anObject.get())
+        aResult.push_back(anObject);
+    }
+  }
+  return aResult;
+}
+
 std::list<std::shared_ptr<ModelAPI_Feature> > Model_Objects::allFeatures()
 {
   std::list<std::shared_ptr<ModelAPI_Feature> > aResult;
index 97507367db5ab1741de54c60e43c094e53267335..856d3c90b12f87cb96a40e91ada6c4dec8ac0327 100644 (file)
@@ -24,6 +24,7 @@
 #include <Model.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
 #include <ModelAPI_Result.h>
 #include <ModelAPI_ResultParameter.h>
 
@@ -90,16 +91,23 @@ class Model_Objects
 
   //! Returns the object index in the group. Object must be visible. Otherwise returns -1.
   //! \param theObject object of this document
+  //! \param theAllowFolder take into account grouping feature by folders
   //! \returns index started from zero, or -1 if object is invisible or belongs to another document
-  const int index(std::shared_ptr<ModelAPI_Object> theObject);
+  const int index(std::shared_ptr<ModelAPI_Object> theObject,
+                  const bool theAllowFolder = false);
 
   //! Returns the feature in the group by the index (started from zero)
   //! \param theGroupID group that contains a feature
   //! \param theIndex zero-based index of feature in the group
-  ObjectPtr object(const std::string& theGroupID, const int theIndex);
+  //! \param theAllowFolder take into account grouping feature by folders
+  ObjectPtr object(const std::string& theGroupID,
+                   const int theIndex,
+                   const bool theAllowFolder = false);
 
   //! Returns the number of features in the group
-  int size(const std::string& theGroupID);
+  //! \param theGroupID group of objects
+  //! \param theAllowFolder take into account grouping feature by folders
+  int size(const std::string& theGroupID, const bool theAllowFolder = false);
 
   //! Returns all (and disabled) results of the given type.
   //! Not fast method (iterates all features).
@@ -141,6 +149,41 @@ class Model_Objects
   std::shared_ptr<ModelAPI_Feature>
     feature(const std::shared_ptr<ModelAPI_Result>& theResult);
 
+  /// Creates a folder (group of the features in the object browser)
+  std::shared_ptr<ModelAPI_Folder> createFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theBeforeThis);
+  //! Removes the folder from the document (all features in the folder will be kept).
+  void removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder);
+  //! Search a folder applicable for the list of features
+  //! (it means the list of features stored in the folder should be consequential)
+  //! \param theFeatures list of features to be added to folder
+  //! \param theBelow    search the folder below the features (if \c false, search above)
+  //! \return Empty pointer if there is no applicable folder
+  std::shared_ptr<ModelAPI_Folder> findFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const bool theBelow);
+  //! Search a folder containing the given feature.
+  //! Addtionally calculates a zero-based index of the feature in this folder.
+  //! \param theFeature feature to search
+  //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+  //! \return the folder containing the feature or empty pointer if the feature is top-level.
+  std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder);
+  //! Add a list of features to the folder. The correctness of the adding is not performed
+  //! (such checks have been done in corresponding find.. method).
+  //! \return \c true if the movement is successfull
+  bool moveToFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+                    const std::shared_ptr<ModelAPI_Folder>& theFolder);
+  //! Remove features from the folder
+  //! \param theFeatures list of features to be removed
+  //! \param theBefore   extract features before the folder (this parameter is applicable only
+  //!                    when all features in the folder are taking out,
+  //!                    in other cases the direction is taken automatically)
+  //! \return \c true if the features have been moved out
+  bool removeFromFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+                        const bool theBefore = true);
+
   //! Sets the owner of this manager
   void setOwner(DocumentPtr theDoc);
 
@@ -159,6 +202,9 @@ class Model_Objects
   //! feature type + "_" + index
   void setUniqueName(FeaturePtr theFeature);
 
+  //! Initializes the foldet with an unique name ("Folder_" + index)
+  void setUniqueName(FolderPtr theFolder);
+
   //! Synchronizes myFeatures list with the updated document
   //! \param theUpdated list of labels that are marked as modified, so featrues must be also
   //! \param theUpdateReferences causes the update of back-references
@@ -214,6 +260,11 @@ class Model_Objects
   /// Returns true if theLater is in history of features creation later than theCurrent
   bool isLater(FeaturePtr theLater, FeaturePtr theCurrent) const;
 
+  /// Returns the next or previous label
+  /// \param theCurrent given label
+  /// \param theReverse if it is true, iterates in reverced order (next becomes previous)
+  TDF_Label nextLabel(TDF_Label theCurrent, const bool theReverse = false);
+
   /// Returns the result group identifier of the given feature (for this at least one result must
   /// be created before)
   std::string featureResultGroup(FeaturePtr theFeature);
@@ -222,6 +273,10 @@ class Model_Objects
   //! history. Not very fast method, for calling once, not in big cycles.
   std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures();
 
+  //! Returns all objects of the document including the hidden features which are not in
+  //! history. Not very fast method, for calling once, not in big cycles.
+  std::list<std::shared_ptr<ModelAPI_Object> > allObjects();
+
   //! synchronises back references for the given object basing on the collected data
   void synchronizeBackRefsForObject(
     const std::set<std::shared_ptr<ModelAPI_Attribute>>& theNewRefs, ObjectPtr theObject);
@@ -229,6 +284,16 @@ class Model_Objects
   /// Just removes all features without touching the document data (to be able undo)
   virtual void eraseAllFeatures();
 
+  // Check whether the pre-image of the result had user-defined name.
+  // If yes, return this name.
+  bool hasCustomName(DataPtr theFeatureData,
+                     ResultPtr theResult,
+                     int theResultIndex,
+                     std::string& theParentName) const;
+
+  /// Return object representing a folder or empty pointer
+  ObjectPtr folder(TDF_Label theLabel) const;
+
  private:
   TDF_Label myMain; ///< main label of the data storage
 
@@ -238,6 +303,9 @@ class Model_Objects
   /// For optimization mapped by labels
   NCollection_DataMap<TDF_Label, FeaturePtr> myFeatures;
 
+  /// Managed folders
+  NCollection_DataMap<TDF_Label, ObjectPtr> myFolders;
+
   /// Map from group id to the array that contains all objects located in history.
   /// Each array is updated by demand from scratch, by browing all the features in the history.
   std::map<std::string, std::vector<ObjectPtr> > myHistory;
index f69c4d604e54126812a73a30bf46f6b497b3395e..731a520de0bb6fcff6f1d14a725b60612737cb04 100644 (file)
@@ -47,7 +47,7 @@ void Model_ResultBody::colorConfigInfo(std::string& theSection, std::string& the
 bool Model_ResultBody::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, const bool theFlag)
 {
   bool aChanged = ModelAPI_ResultBody::setDisabled(theThis, theFlag);
-  if (aChanged) { // state is changed, so modifications are needed
+  if (aChanged && data()->isValid()) { // state is changed, so modifications are needed
     myBuilder->evolutionToSelection(theFlag);
   }
   return aChanged;
index c650196d92863db878ad59395ba7b238f860ab73..2446e4048e2582c495b42e8d7165bd3d9b26131b 100755 (executable)
@@ -240,8 +240,7 @@ void Model_ResultCompSolid::updateSubs(const std::shared_ptr<GeomAPI_Shape>& the
   } else if (!mySubs.empty()) { // erase all subs
     while(!mySubs.empty()) {
       ResultBodyPtr anErased = *(mySubs.rbegin());
-      if (anErased->data()->isValid())
-        anErased->setDisabled(anErased, true);
+      anErased->setDisabled(anErased, true); // even if it is invalid (to erase subs on abort/undo)
       mySubs.pop_back();
     }
     mySubsMap.clear();
index ddac1acb2a1099999b4d4ce7e31f281b7e5ac011..255f5e3802ce81352513e45182dd92b5dad70178 100644 (file)
@@ -54,6 +54,7 @@ void Model_ResultPart::initAttributes()
   data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
   data()->addAttribute(BASE_REF_ID(), ModelAPI_AttributeReference::typeId());
   data()->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId());
 
   if (aDocRef->isInitialized() && // initialized immideately means already exist and will be loaded
       !Model_Application::getApplication()->hasDocument(aDocRef->docId()))
index 89c044cb4ff24e32e9ba24f64c91cdbbabce1347..6de12da8d0ad49553c9819a2ae402c9ae9bc86fa 100644 (file)
@@ -83,7 +83,7 @@ std::string Model_SelectionNaming::getShapeName(
         // indexes are added to sub-shapes not primitives
         // (primitives must not be located at the same label)
         if(!aName.empty() && aNS->Evolution() != TNaming_PRIMITIVE && isNeedContextName) {
-          const TDF_Label& aLabel = aNS->Label();//theDoc->findNamingName(aName);
+          const TDF_Label& aLabel = aNS->Label();
           static const std::string aPostFix("_");
           TNaming_Iterator anItL(aNS);
           for(int i = 1; anItL.More(); anItL.Next(), i++) {
@@ -112,7 +112,21 @@ std::string Model_SelectionNaming::getShapeName(
             aNewContext = theDoc->objects()->object(aNSDataLab);
           }
           if (aNewContext.get()) {
-            aName = aNewContext->data()->name() + "/" + aName;
+            // this is to avoid duplicated names of results problem
+            std::string aContextName = aNewContext->data()->name();
+            // myLab corresponds to the current time
+            TDF_Label aCurrentLab = myLab;
+            while(aCurrentLab.Depth() > 3)
+              aCurrentLab = aCurrentLab.Father();
+
+            int aNumInHistoryNames =
+              theDoc->numberOfNameInHistory(aNewContext, aCurrentLab);
+            while(aNumInHistoryNames > 1) { // add "_" before name the needed number of times
+              aContextName = "_" + aContextName;
+              aNumInHistoryNames--;
+            }
+
+            aName = aContextName + "/" + aName;
           }
         }
       }
@@ -469,20 +483,21 @@ const TopoDS_Shape getShapeFromNS(
 }
 
 const TopoDS_Shape findFaceByName(
-  const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc)
+  const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
+  const ResultPtr theDetectedContext, bool theContextIsUnique)
 {
   TopoDS_Shape aFace;
-  //std::string::size_type n, nb = theSubShapeName.rfind('/');
-  //if (nb == std::string::npos) nb = 0;
-  //std::string aSubString = theSubShapeName.substr(nb + 1);
   std::string aSubString = theSubShapeName;
 
-  TDF_Label aLabel = theDoc->findNamingName(aSubString);
+  static const ResultPtr anEmpty;
+  TDF_Label aLabel = theDoc->findNamingName(aSubString,
+    theContextIsUnique ? theDetectedContext : anEmpty);
   if (aLabel.IsNull()) { // try to remove additional artificial suffix
     std::string::size_type n = aSubString.rfind('_');
     if (n != std::string::npos) {
       aSubString = aSubString.substr(0, n);
-       aLabel = theDoc->findNamingName(aSubString);
+      aLabel = theDoc->findNamingName(aSubString,
+        theContextIsUnique ? theDetectedContext : anEmpty);
     }
   }
   if(aLabel.IsNull()) return aFace;
@@ -721,7 +736,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
 
   std::string aContName = getContextName(aSubShapeName);
   if(aContName.empty()) return false;
-  ResultPtr aCont = aDoc->findByName(aContName);
+  bool anUniqueContext = false;
+  ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName, anUniqueContext);
    // possible this is body where postfix is added to distinguish several shapes on the same label
   int aSubShapeId = -1; // -1 means sub shape not found
   // for result body the name wihtout "_" has higher priority than with it: it is always added
@@ -729,8 +745,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
        aContName == aSubShapeName) {
     size_t aPostIndex = aContName.rfind('_');
     if (aPostIndex != std::string::npos) {
-      std::string aSubContName = aContName.substr(0, aPostIndex);
-      ResultPtr aSubCont = aDoc->findByName(aSubContName);
+      std::string anEmpty, aSubContName = aContName.substr(0, aPostIndex);
+      ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty, anUniqueContext);
       if (aSubCont.get()) {
         try {
           std::string aNum = aContName.substr(aPostIndex + 1);
@@ -747,18 +763,20 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
   }
 
 
+  static const ResultPtr anEmpty;
   TopoDS_Shape aSelection;
   switch (aType)
   {
   case TopAbs_FACE:
   case TopAbs_WIRE:
     {
-      aSelection = findFaceByName(aSubShapeName, aDoc);
+      aSelection = findFaceByName(aSubShapeName, aDoc, aCont, anUniqueContext);
     }
     break;
   case TopAbs_EDGE:
     {
-      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
+      const TDF_Label& aLabel =
+        aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -769,7 +787,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     break;
   case TopAbs_VERTEX:
     {
-      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
+      const TDF_Label& aLabel =
+        aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -817,8 +836,15 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     if(aN >= 1) {
       TopTools_ListOfShape aList;
       std::list<std::string>::iterator it = aListofNames.begin();
-      for(; it != aListofNames.end(); it++){
-        const TopoDS_Shape aFace = findFaceByName(*it, aDoc);
+      for(; it != aListofNames.end(); it++) {
+        ResultPtr aFaceContext = aCont;
+        if (it != aListofNames.begin()) { // there may be other context for different sub-faces
+          std::string aContName = getContextName(*it);
+          if(!aContName.empty()) {
+            aFaceContext = aDoc->findByName(aContName, *it, anUniqueContext);
+          }
+        }
+        const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext, anUniqueContext);
         if(!aFace.IsNull())
           aList.Append(aFace);
       }
@@ -830,8 +856,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
   if (aN < 2) {
     size_t aConstrNamePos = aSubShapeName.find("/");
     bool isFullName = aConstrNamePos == std::string::npos;
-    std::string aContrName = aContName;
-    ResultPtr aConstr = aDoc->findByName(aContrName);
+    std::string anEmpty, aContrName = aContName;
+    ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty, anUniqueContext);
     if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
       theCont = aConstr;
       if (isFullName) {
index 10bd28f205db172f7fe67331aa8bf482d3e7ef34..8a0b7b89f6d10bb8ee6cc6360eb848b3d39ea837 100644 (file)
@@ -35,6 +35,7 @@
 #include <Config_ValidatorMessage.h>
 #include <Config_ModuleReader.h>
 #include <Config_ValidatorReader.h>
+#include <Config_PluginMessage.h>
 
 #include <ModelAPI_CompositeFeature.h>
 #include <ModelAPI_ResultPart.h>
@@ -165,6 +166,29 @@ std::list<std::string> Model_Session::redoList()
   return ROOT_DOC->redoList();
 }
 
+ModelAPI_Plugin* Model_Session::getPlugin(const std::string& thePluginName)
+{
+  if (myPluginObjs.find(thePluginName) == myPluginObjs.end()) {
+    // before load the used plugins
+    if (myUsePlugins.find(thePluginName) != myUsePlugins.end()) {
+      std::string aUse = myUsePlugins[thePluginName];
+      std::stringstream aUseStream(aUse);
+      std::string aPluginName;
+      while (std::getline(aUseStream, aPluginName, ',')) {
+        if (myPluginObjs.find(aPluginName) == myPluginObjs.end())
+          getPlugin(aPluginName);
+      }
+    }
+    // load plugin library if not yet done
+    Config_ModuleReader::loadPlugin(thePluginName);
+  }
+  if (myPluginObjs.find(thePluginName) == myPluginObjs.end()) {
+    Events_InfoMessage("Model_Session", "Can not load plugin '%1'").arg(thePluginName).send();
+    return NULL;
+  }
+  return myPluginObjs[thePluginName];
+}
+
 FeaturePtr Model_Session::createFeature(std::string theFeatureID, Model_Document* theDocOwner)
 {
   if (this != myImpl) {
@@ -178,26 +202,20 @@ FeaturePtr Model_Session::createFeature(std::string theFeatureID, Model_Document
     std::pair<std::string, std::string>& aPlugin = myPlugins[theFeatureID]; // plugin and doc kind
     if (!aPlugin.second.empty() && aPlugin.second != theDocOwner->kind()) {
       Events_InfoMessage("Model_Session",
-          "Feature '%1' can be created only in document '%2' by the XML definition")
-          .arg(theFeatureID).arg(aPlugin.second).send();
+        "Feature '%1' can be created only in document '%2' by the XML definition")
+        .arg(theFeatureID).arg(aPlugin.second).send();
       return FeaturePtr();
     }
-    myCurrentPluginName = aPlugin.first;
-    if (myPluginObjs.find(myCurrentPluginName) == myPluginObjs.end()) {
-      // load plugin library if not yet done
-      Config_ModuleReader::loadPlugin(myCurrentPluginName);
-    }
-    if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
-      FeaturePtr aCreated = myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID);
+    ModelAPI_Plugin* aPluginObj = getPlugin(aPlugin.first);
+    if (aPluginObj) {
+      FeaturePtr aCreated = aPluginObj->createFeature(theFeatureID);
       if (!aCreated) {
-        Events_InfoMessage("Model_Session",
-            "Can not initialize feature '%1' in plugin '%2'")
-            .arg(theFeatureID).arg(myCurrentPluginName).send();
+        Events_InfoMessage("Model_Session", "Can not initialize feature '%1' in plugin '%2'")
+          .arg(theFeatureID).arg(aPlugin.first).send();
       }
       return aCreated;
     } else {
-      Events_InfoMessage("Model_Session",
-        "Can not load plugin '%1'").arg(myCurrentPluginName).send();
+      Events_InfoMessage("Model_Session", "Can not load plugin '%1'").arg(aPlugin.first).send();
     }
   } else {
     Events_InfoMessage("Model_Session",
@@ -416,6 +434,7 @@ Model_Session::Model_Session()
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED), 0, true);
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED), 0, true);
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_VALIDATOR_LOADED));
+  aLoop->registerListener(this, Events_Loop::eventByName(Config_PluginMessage::EVENT_ID()));
 }
 
 void Model_Session::processEvent(const std::shared_ptr<Events_Message>& theMessage)
@@ -423,6 +442,7 @@ void Model_Session::processEvent(const std::shared_ptr<Events_Message>& theMessa
   static const Events_ID kFeatureEvent =
     Events_Loop::eventByName(Config_FeatureMessage::MODEL_EVENT());
   static const Events_ID kValidatorEvent = Events_Loop::eventByName(EVENT_VALIDATOR_LOADED);
+  static const Events_ID kPluginEvent = Events_Loop::eventByName(Config_PluginMessage::EVENT_ID());
   if (theMessage->eventID() == kFeatureEvent) {
     const std::shared_ptr<Config_FeatureMessage> aMsg =
       std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
@@ -444,6 +464,9 @@ void Model_Session::processEvent(const std::shared_ptr<Events_Message>& theMessa
         if(aMsgAttr->isConcealment()) {
           validators()->registerConcealment(aMsgAttr->featureId(), aMsgAttr->attributeId());
         }
+        if(aMsgAttr->isMainArgument()) {
+          validators()->registerMainArgument(aMsgAttr->featureId(), aMsgAttr->attributeId());
+        }
         const std::list<std::pair<std::string, std::string> >& aCases = aMsgAttr->getCases();
         if (!aCases.empty()) {
           validators()->registerCase(aMsgAttr->featureId(), aMsgAttr->attributeId(), aCases);
@@ -463,6 +486,15 @@ void Model_Session::processEvent(const std::shared_ptr<Events_Message>& theMessa
                                       aMsg->parameters());
       }
     }
+  } else if (theMessage->eventID() == kPluginEvent) { // plugin is started to load
+    std::shared_ptr<Config_PluginMessage> aMsg =
+      std::dynamic_pointer_cast<Config_PluginMessage>(theMessage);
+    if (aMsg.get()) {
+      myCurrentPluginName = aMsg->pluginId();
+      if (!aMsg->uses().empty()) {
+        myUsePlugins[myCurrentPluginName] = aMsg->uses();
+      }
+    }
   } else {  // create/update/delete
     if (myCheckTransactions && !isOperation())
       Events_InfoMessage("Model_Session",
index 89b9d548c1d5d1b1416b57dde0ad8ec9b92c1aa6..7342ae2d35845dab086fdf2cad9af3d0fa477f91 100644 (file)
@@ -44,6 +44,8 @@ class Model_Session : public ModelAPI_Session, public Events_Listener
   std::map<std::string, ModelAPI_Plugin*> myPluginObjs;  ///< instances of the already plugins
   std::string myCurrentPluginName;  ///< name of the plugin that must be loaded currently
   std::shared_ptr<ModelAPI_Document> myCurrentDoc;  ///< current working document
+   ///< map from plugin id to plugins which are used by it (must be loaded before this one)
+  std::map<std::string, std::string> myUsePlugins;
 
   /// if true, generates error if document is updated outside of transaction
   bool myCheckTransactions;
@@ -149,6 +151,9 @@ class Model_Session : public ModelAPI_Session, public Events_Listener
   /// Creates the feature object using plugins functionality
   FeaturePtr createFeature(std::string theFeatureID, Model_Document* theDocOwner);
 
+  /// Get the plugin by name. If it is not loaded, load plugin.
+  ModelAPI_Plugin* getPlugin(const std::string& thePluginName);
+
   friend class Model_Document;
   friend class Model_Objects;
 };
index 4274d9c5e037da15b727e7a340718375f23c942b..8e2ac8137228b26224f0245b17bd2d08095d3399 100755 (executable)
@@ -90,6 +90,7 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
   bool isNotExecuted = theFeature->isPersistentResult() &&
     !std::dynamic_pointer_cast<Model_Document>((theFeature)->document())->executeFeatures();
   if (isNotExecuted) {
+    redisplayWithResults(theFeature, ModelAPI_StateNothing, false); // redisplay even not executed
     if (!theReason.get()) // no reason => no construction reason
       return false;
     if (myNotPersistentRefs.find(theFeature) == myNotPersistentRefs.end()) {
@@ -104,7 +105,10 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
 
   // update arguments for "apply button" state change
   if ((!theFeature->isPreviewNeeded() && !myIsFinish) || myIsPreviewBlocked) {
-    myProcessOnFinish.insert(theFeature);
+    if (theReason.get())
+      myProcessOnFinish[theFeature].insert(theReason);
+    else if (myProcessOnFinish.find(theFeature) == myProcessOnFinish.end())
+      myProcessOnFinish[theFeature] = std::set<std::shared_ptr<ModelAPI_Feature> >();
 #ifdef DEB_UPDATE
       std::cout<<"*** Add process on finish "<<theFeature->name()<<std::endl;
 #endif
@@ -319,10 +323,20 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
     if (theMessage->eventID() == kOpFinishEvent) {
       myIsFinish = true;
       // add features that wait for finish as modified
-      std::set<std::shared_ptr<ModelAPI_Feature> >::iterator aFeature = myProcessOnFinish.begin();
-      for(; aFeature != myProcessOnFinish.end(); aFeature++)
-        if ((*aFeature)->data()->isValid()) // there may be already removed wait for features
-          addModified(*aFeature, FeaturePtr());
+      std::map<std::shared_ptr<ModelAPI_Feature>, std::set<std::shared_ptr<ModelAPI_Feature> > >::
+        iterator aFeature = myProcessOnFinish.begin();
+      for(; aFeature != myProcessOnFinish.end(); aFeature++) {
+        if (aFeature->first->data()->isValid()) {// there may be already removed while wait
+          if (aFeature->second.empty()) {
+            addModified(aFeature->first, FeaturePtr());
+            continue;
+          }
+          std::set<std::shared_ptr<ModelAPI_Feature> >::iterator aReasons;
+          for(aReasons = aFeature->second.begin(); aReasons != aFeature->second.end(); aReasons++) {
+            addModified(aFeature->first, *aReasons);
+          }
+        }
+      }
       myIsFinish = false;
     }
     // processed features must be only on finish, so clear anyway (to avoid reimport on load)
@@ -628,7 +642,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
   return true;
 }
 
-void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_ExecState theState)
+void Model_Update::redisplayWithResults(
+  FeaturePtr theFeature, const ModelAPI_ExecState theState, bool theUpdateState)
 {
   // make updated and redisplay all results
   static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
@@ -641,7 +656,8 @@ void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_Ex
     if (!aRes->isDisabled()) {
       // update state only for enabled results
       // (Placement Result Part may make the original Part Result as invalid)
-      aRes->data()->execState(theState);
+      if (theUpdateState)
+        aRes->data()->execState(theState);
     }
     if (theFeature->data()->updateID() > aRes->data()->updateID()) {
       aRes->data()->setUpdateID(theFeature->data()->updateID());
@@ -650,7 +666,8 @@ void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_Ex
   }
   // to redisplay "presentable" feature (for ex. distance constraint)
   ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP);
-  theFeature->data()->execState(theState);
+  if (theUpdateState)
+    theFeature->data()->execState(theState);
 }
 
 /// Updates the state by the referenced object: if something bad with it, set state for this one
index cef7c0b49c4484241fb791aa0b132bee4b7dacbc..9a6ecc711bb27da78d47103aaec41dab8d9a67e9 100644 (file)
@@ -56,8 +56,10 @@ class Model_Update : public Events_Listener
   bool myIsFinish;
   /// try if processing is currently performed
   bool myIsProcessed;
-  /// set that contains features that must be executed only on finish of the operation
-  std::set<std::shared_ptr<ModelAPI_Feature> > myProcessOnFinish;
+  /// map that contains features that must be executed only on finish of the operation
+  /// the value in map is the set of reasons
+  std::map<std::shared_ptr<ModelAPI_Feature>, std::set<std::shared_ptr<ModelAPI_Feature> > >
+    myProcessOnFinish;
   /// to avoid infinitive cycling: feature -> count of the processing periods during this update
   std::map<std::shared_ptr<ModelAPI_Feature>, int > myProcessed;
   /// if preview in hte property panel is blocked and
@@ -89,7 +91,7 @@ protected:
 
   /// Sends the redisplay events for feature and results, updates the updated status
   void redisplayWithResults(std::shared_ptr<ModelAPI_Feature> theFeature,
-    const ModelAPI_ExecState theState);
+    const ModelAPI_ExecState theState, bool theUpdateState = true);
 
   /// On operation start/end/abort the "Just" fileds must be cleared and processed in the right way
   //! \param theFlushRedisplay a boolean value if the redisplay signal should be flushed
index fa0235b0d2fd0cf804d9d34326fca00940f041dc..41fa0f7014a03e24137734cbd4bc447925905271 100644 (file)
@@ -363,3 +363,17 @@ bool Model_ValidatorsFactory::isCase(FeaturePtr theFeature, std::string theAttri
   }
   return anInCase; // if no additional conditions, this attribute is the case to be validated
 }
+
+void Model_ValidatorsFactory::registerMainArgument(std::string theFeature,
+                                                   std::string theAttribute)
+{
+  std::map<std::string, std::string>::iterator aFound = myMainArgument.find(theFeature);
+  if (aFound == myMainArgument.end())
+    myMainArgument[theFeature] = theAttribute;
+}
+
+bool Model_ValidatorsFactory::isMainArgument(std::string theFeature, std::string theAttribute)
+{
+  std::map<std::string, std::string>::iterator aFound = myMainArgument.find(theFeature);
+  return aFound != myMainArgument.end() && aFound->second == theAttribute;
+}
index 014d7ce673aa0e54578b8f3d7cf216b2bfc374b9..939cdf21390017aebd1c22b3bc2de2de5e62e94e 100644 (file)
@@ -56,6 +56,8 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory
   // (switchId (ID of the attribute) and case Ids (possible values of the switch attribute))
   std::map<std::string, std::map<std::string,
           std::map<std::string, std::set<std::string> > > > myCases;
+  /// Stores main attribute for each feature
+  std::map<std::string, std::string> myMainArgument;
 
  public:
   /// Registers the instance of the validator by the ID
@@ -115,6 +117,12 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory
   /// Returns true if the attribute must be checked (the case is selected)
   virtual bool isCase(FeaturePtr theFeature, std::string theAttribute);
 
+  /// Register the attribute as a main argument of the feature
+  virtual void registerMainArgument(std::string theFeature, std::string theAttribute);
+
+  /// Returns true is the attribute is a main argument of the feature
+  virtual bool isMainArgument(std::string theFeature, std::string theAttribute);
+
 
 protected:
   /// Adds the defualt validators that are usefull for all features.
index e043a23a2731cb5d8bedcb33639334b311749e19..aa0b87e0ce66083fec1b5cf8caf75cd63307291e 100644 (file)
@@ -51,6 +51,7 @@ SET(PROJECT_HEADERS
     ModelAPI_Expression.h
     ModelAPI_Feature.h
     ModelAPI_FeatureValidator.h
+    ModelAPI_Folder.h
     ModelAPI_IReentrant.h
     ModelAPI_Object.h
     ModelAPI_Plugin.h
@@ -94,6 +95,7 @@ SET(PROJECT_SOURCES
     ModelAPI_Expression.cpp
     ModelAPI_Feature.cpp
     ModelAPI_FeatureValidator.cpp
+    ModelAPI_Folder.cpp
     ModelAPI_IReentrant.cpp
     ModelAPI_Object.cpp
     ModelAPI_Plugin.cpp
@@ -172,4 +174,23 @@ ADD_UNIT_TESTS(TestConstants.py
                Test2241.py
                Test2252.py
                Test2276.py
+               TestCustomName_BooleanCut.py
+               TestCustomName_CommonCompSolid.py
+               TestCustomName_CutCompSolid.py
+               TestCustomName_CutGroup.py
+               TestCustomName_DefaultName.py
+               TestCustomName_ExtrudeFace.py
+               TestCustomName_ExtrusionCut.py
+               TestCustomName_ExtrusionCutFace.py
+               TestCustomName_MultiTranslation.py
+               TestCustomName_Partition.py
+               TestCustomName_Placement.py
+               TestCustomName_Recover.py
+               TestCustomName_Rename.py
+               TestCustomName_RotateGroup.py
+               TestCustomName_Translation.py
+               TestFolder_Create.py
+               TestFolder_Update.py
+               TestFolder_Remove.py
+               TestFolder_Stability.py
 )
index 7c0466cdb0152f1ac71ea99f8dd0f5af10bec3b4..61403edf66643f8052bee4eda00678c645211761 100644 (file)
@@ -51,6 +51,7 @@
 %feature("director") ModelAPI_Feature;
 %feature("director") ModelAPI_CompositeFeature;
 %feature("director") ModelAPI_Data;
+%feature("director") ModelAPI_Folder;
 
 // shared pointers
 // For ModelAPI_ResultConstruction.shape()
@@ -62,6 +63,7 @@
 %shared_ptr(ModelAPI_Feature)
 %shared_ptr(ModelAPI_CompositeFeature)
 %shared_ptr(ModelAPI_Data)
+%shared_ptr(ModelAPI_Folder)
 %shared_ptr(ModelAPI_Attribute)
 %shared_ptr(ModelAPI_AttributeDocRef)
 %shared_ptr(ModelAPI_AttributeDouble)
   }
 }
 
+%apply int& OUTPUT {int& theIndexInFolder};
+
 // all supported interfaces
 %include "ModelAPI_Entity.h"
 %include "ModelAPI_Document.h"
 %include "ModelAPI_ResultParameter.h"
 %include "ModelAPI_Tools.h"
 %include "ModelAPI_ResultCompSolid.h"
+%include "ModelAPI_Folder.h"
 
 // std::list -> []
 %template(StringList) std::list<std::string>;
@@ -167,6 +172,7 @@ template<class T1, class T2> std::shared_ptr<T1> shared_ptr_cast(std::shared_ptr
 %template(featureToCompositeFeature) shared_ptr_cast<ModelAPI_CompositeFeature, ModelAPI_Feature>;
 %template(objectToFeature) shared_ptr_cast<ModelAPI_Feature, ModelAPI_Object>;
 %template(objectToResult) shared_ptr_cast<ModelAPI_Result, ModelAPI_Object>;
+%template(objectToFolder) shared_ptr_cast<ModelAPI_Folder, ModelAPI_Object>;
 %template(compositeFeatureToFeature) shared_ptr_cast<ModelAPI_Feature, ModelAPI_CompositeFeature>;
 
 %template(modelAPI_Result) shared_ptr_cast<ModelAPI_Result, ModelAPI_Object>;
index c28a1ae8800541e63caca2ceb1183d138f1de535..e1848123e782d42e57cbd8095417128b887fd79a 100644 (file)
@@ -199,6 +199,10 @@ class MODELAPI_EXPORT ModelAPI_Data
   /// Sets true if the object is deleted, but some data is still keept in memory
   virtual void setIsDeleted(const bool theFlag) = 0;
 
+  /// Returns \c true if theAttribute1 is going earlier than theAttribute2 in the data
+  virtual bool isPrecedingAttribute(const std::string& theAttribute1,
+                                    const std::string& theAttribute2) const = 0;
+
  protected:
   /// Objects are created for features automatically
   ModelAPI_Data();
index 24d7c4c4bde7c58e1c4120108947845c2fe3f194..e234aefe5a45721b42e061dde2a01a58b0e4702b 100644 (file)
@@ -31,6 +31,7 @@
 #include <set>
 
 class ModelAPI_Feature;
+class ModelAPI_Folder;
 class ModelAPI_Object;
 class ModelAPI_Result;
 class ModelAPI_ResultConstruction;
@@ -89,8 +90,10 @@ public:
   //! Returns the object in the group by the index (started from zero)
   //! \param theGroupID group that contains an object
   //! \param theIndex zero-based index of feature in the group
+  //! \param theAllowFolder take into account grouping feature by folders
   virtual std::shared_ptr<ModelAPI_Object> object(const std::string& theGroupID,
-                                                    const int theIndex) = 0;
+                                                  const int theIndex,
+                                                  const bool theAllowFolder = false) = 0;
 
   //! Returns the first found object in the group by the object name
   //! \param theGroupID group that contains an object
@@ -101,11 +104,15 @@ public:
 
   //! Returns the object index in the group. Object must be visible. Otherwise returns -1.
   //! \param theObject object of this document
+  //! \param theAllowFolder take into account grouping feature by folders
   //! \returns index started from zero, or -1 if object is invisible or belongs to another document
-  virtual const int index(std::shared_ptr<ModelAPI_Object> theObject) = 0;
+  virtual const int index(std::shared_ptr<ModelAPI_Object> theObject,
+                          const bool theAllowFolder = false) = 0;
 
   //! Returns the number of objects in the group of objects
-  virtual int size(const std::string& theGroupID) = 0;
+  //! \param theGroupID group of objects
+  //! \param theAllowFolder take into account grouping feature by folders
+  virtual int size(const std::string& theGroupID, const bool theAllowFolder = false) = 0;
 
   //! Returns the feature that is currently edited in this document, normally
   //! this is the latest created feature
@@ -170,6 +177,50 @@ public:
   //! history. Not very fast method, for calling once, not in big cycles.
   virtual std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures() = 0;
 
+  //! Returns all objects of the document including the hidden features which are not in
+  //! history. Not very fast method, for calling once, not in big cycles.
+  virtual std::list<std::shared_ptr<ModelAPI_Object> > allObjects() = 0;
+
+  //! Creates a folder (group of the features in the object browser)
+  //! \param theAddBefore a feature, the folder is added before
+  //!                     (if empty, the folder is added after the last feature)
+  virtual std::shared_ptr<ModelAPI_Folder> addFolder(
+      std::shared_ptr<ModelAPI_Feature> theAddBefore = std::shared_ptr<ModelAPI_Feature>()) = 0;
+  //! Removes the folder from the document (all features in the folder will be kept).
+  virtual void removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder) = 0;
+  //! Search a folder above the list of features applicable to store them
+  //! (it means the list of features stored in the folder should be consequential)
+  //! \return Empty pointer if there is no applicable folder
+  virtual std::shared_ptr<ModelAPI_Folder> findFolderAbove(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures) = 0;
+  //! Search a folder below the list of features applicable to store them
+  //! (it means the list of features stored in the folder should be consequential)
+  //! \return Empty pointer if there is no applicable folder
+  virtual std::shared_ptr<ModelAPI_Folder> findFolderBelow(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures) = 0;
+  //! Search a folder containing the given feature.
+  //! Addtionally calculates a zero-based index of the feature in this folder.
+  //! \param theFeature feature to search
+  //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+  //! \return the folder containing the feature or empty pointer if the feature is top-level.
+  virtual std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder) = 0;
+  //! Add a list of features to the folder. The correctness of the adding is not performed
+  //! (such checks have been done in corresponding find.. method).
+  //! \return \c true if the movement is successfull
+  virtual bool moveToFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+                            const std::shared_ptr<ModelAPI_Folder>& theFolder) = 0;
+  //! Remove features from the folder
+  //! \param theFeatures list of features to be removed
+  //! \param theBefore   extract features before the folder (this parameter is applicable only
+  //!                    when all features in the folder are taking out,
+  //!                    in other cases the direction is taken automatically)
+  //! \return \c true if the features have been moved out
+  virtual bool removeFromFolder(
+      const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+      const bool theBefore = true) = 0;
+
   //! Informs the document that it becomes active and some actions must be performed
   virtual void setActive(const bool theFlag) = 0;
   //! Returns true if this document is currently active
diff --git a/src/ModelAPI/ModelAPI_Folder.cpp b/src/ModelAPI/ModelAPI_Folder.cpp
new file mode 100644 (file)
index 0000000..1cc97cb
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModelAPI_Folder.h"
+
+#include <ModelAPI_AttributeReference.h>
+
+ModelAPI_Folder::ModelAPI_Folder()
+{
+}
+
+ModelAPI_Folder::~ModelAPI_Folder()
+{
+}
+
+void ModelAPI_Folder::init()
+{
+}
+
+void ModelAPI_Folder::initAttributes()
+{
+  data()->addAttribute(FIRST_FEATURE_ID(), ModelAPI_AttributeReference::typeId());
+  data()->addAttribute(LAST_FEATURE_ID(),  ModelAPI_AttributeReference::typeId());
+}
+
+void ModelAPI_Folder::execute()
+{
+}
diff --git a/src/ModelAPI/ModelAPI_Folder.h b/src/ModelAPI/ModelAPI_Folder.h
new file mode 100644 (file)
index 0000000..b89fd87
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModelAPI_Folder_H_
+#define ModelAPI_Folder_H_
+
+#include <ModelAPI.h>
+#include <ModelAPI_Object.h>
+
+/**\class ModelAPI_Folder
+ * \ingroup DataModel
+ * \brief Folder feature (groups the features).
+ */
+class ModelAPI_Folder : public ModelAPI_Object
+{
+public:
+  MODELAPI_EXPORT ModelAPI_Folder();
+  /// To virtually destroy the fields of successors
+  MODELAPI_EXPORT virtual ~ModelAPI_Folder();
+
+  /// Folder feature ID
+  static const std::string& ID()
+  {
+    static const std::string MY_FOLDER_ID("Folder");
+    return MY_FOLDER_ID;
+  }
+
+  /// Returns the group identifier of all features
+  inline static std::string group()
+  {
+    static std::string MY_GROUP = "Folders";
+    return MY_GROUP;
+  }
+
+  /// Returns the group identifier of this result
+  virtual std::string groupName()
+  {
+    return group();
+  }
+
+  /// Attribute referring first feature in the folder
+  static const std::string& FIRST_FEATURE_ID()
+  {
+    static const std::string MY_FIRST_FEATURE_ID("first_feature");
+    return MY_FIRST_FEATURE_ID;
+  }
+
+  /// Attribute referring last feature in the folder
+  static const std::string& LAST_FEATURE_ID()
+  {
+    static const std::string MY_LAST_FEATURE_ID("last_feature");
+    return MY_LAST_FEATURE_ID;
+  }
+
+  /// Request for initialization of data model of the object: adding all attributes
+  MODELAPI_EXPORT virtual void initAttributes();
+
+  /// Computes or recomputes the results
+  MODELAPI_EXPORT virtual void execute();
+
+  /// Returns the feature is disabled or not.
+  virtual bool isDisabled()
+  { return false; }
+
+  //
+  // Helper methods, aliases for data()->method()
+  // -----------------------------------------------------------------------------------------------
+  /// Returns the name stored in the attribute
+  inline std::string name()
+  {
+    return data()->name();
+  }
+  /// Returns the reference attribute by the identifier
+  inline std::shared_ptr<ModelAPI_AttributeReference> reference(const std::string& theID)
+  {
+    return data()->reference(theID);
+  }
+
+protected:
+  /// This method is called just after creation of the object: it must initialize
+  /// all fields, normally initialized in the constructor
+  MODELAPI_EXPORT virtual void init();
+};
+
+//! Pointer on a folder object
+typedef std::shared_ptr<ModelAPI_Folder> FolderPtr;
+
+#endif
index 6569136a672e789abffecc1f4441154fcd0ccae6..588d138bf17cb447927b3273fed0f6fdfbeb1988 100644 (file)
@@ -37,13 +37,15 @@ void ModelAPI_Result::initAttributes()
   DataPtr aData = data();
   aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
   aData->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId());
+  aData->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId());
 }
 
 bool ModelAPI_Result::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, const bool theFlag)
 {
   if (myIsDisabled != theFlag) {
     myIsDisabled = theFlag;
-    data()->setIsDeleted(theFlag); // store it in data model (to get back on undo/redo, etc)
+    if (data()->isValid())
+      data()->setIsDeleted(theFlag); // store it in data model (to get back on undo/redo, etc)
     // this must be before "updated" message send to have history updated for OB update
     document()->updateHistory(groupName()); // to update the history cash data in the document
     // generate related events
index 5036b12fba5ea2ff73721394a299dbb5531c9baa..c418e7ac70c85286387f7b407f6d17f24089cbb9 100644 (file)
@@ -49,13 +49,21 @@ class ModelAPI_Result : public ModelAPI_Object
   }
 
   /// Reference to the deflection of the result.
-  /// The double value is used. The values is in [0, 1] range
+  /// The double value is used. The value is in [0, 1] range
   inline static const std::string& DEFLECTION_ID()
   {
     static const std::string MY_DEFLECTION_ID("Deflection");
     return MY_DEFLECTION_ID;
   }
 
+  /// Reference to the transparency of the result.
+  /// The double value is used. The value is in [0, 1] range
+  inline static const std::string& TRANSPARENCY_ID()
+  {
+    static const std::string MY_TRANSPARENCY_ID("Transparency");
+    return MY_TRANSPARENCY_ID;
+  }
+
   /// Returns true if the result is concealed from the data tree (referenced by other objects)
   MODELAPI_EXPORT virtual bool isConcealed();
 
index 3be42d1f47248161f147105f5eecac93fa1d1534..90d41f6567a9ee53fca8e9b83598b51a62a884e8 100755 (executable)
@@ -32,6 +32,7 @@
 #include <list>
 #include <map>
 #include <iostream>
+#include <sstream>
 
 #include <Events_Loop.h>
 #include <ModelAPI_Events.h>
@@ -381,6 +382,7 @@ bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
   return ModelAPI_Tools::removeFeatures(aFeatures, false);
 }
 
+//***********************************************************************
 bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
                     const bool theFlushRedisplay)
 {
@@ -405,6 +407,7 @@ bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
   return true;
 }
 
+//***********************************************************************
 // Fills the references list by all references of the feature from the references map.
 // This is a recusive method to find references by next found feature in the map of references.
 // \param theFeature a feature to find references
@@ -622,4 +625,88 @@ void getConcealedResults(const FeaturePtr& theFeature,
   }
 }
 
+std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
+                           const int theResultIndex)
+{
+  typedef std::list< std::pair < std::string, std::list<ObjectPtr> > > ListOfReferences;
+
+  SessionPtr aSession = ModelAPI_Session::get();
+  FeaturePtr anOwner = ModelAPI_Feature::feature(theResult->data()->owner());
+
+  ResultCompSolidPtr aCompSolidRes = compSolidOwner(theResult);
+  if (aCompSolidRes) {
+    // names of sub-solids in CompSolid should be default (for example,
+    // result of boolean operation 'Boolean_1_1' is a CompSolid which is renamed to 'MyBOOL',
+    // however, sub-elements of 'MyBOOL' should be named 'Boolean_1_1_1', 'Boolean_1_1_2' etc.)
+    std::ostringstream aDefaultName;
+    aDefaultName << anOwner->name();
+    // compute default name of CompSolid (name of feature + index of CompSolid's result)
+    int aCompSolidResultIndex = 0;
+    const std::list<ResultPtr>& aResults = anOwner->results();
+    for (std::list<ResultPtr>::const_iterator anIt = aResults.begin();
+         anIt != aResults.end(); ++anIt, ++aCompSolidResultIndex)
+      if (aCompSolidRes == *anIt)
+        break;
+    aDefaultName << "_" << (aCompSolidResultIndex + 1) << "_" << (theResultIndex + 1);
+    return aDefaultName.str();
+  }
+
+  DataPtr aData = anOwner->data();
+
+  ListOfReferences aReferences;
+  aData->referencesToObjects(aReferences);
+
+  // find first result with user-defined name
+  ListOfReferences::const_iterator aFoundRef = aReferences.end();
+  for (ListOfReferences::const_iterator aRefIt = aReferences.begin();
+       aRefIt != aReferences.end(); ++aRefIt) {
+    bool isConcealed = aSession->validators()->isConcealed(anOwner->getKind(), aRefIt->first);
+    bool isMainArg = isConcealed &&
+                     aSession->validators()->isMainArgument(anOwner->getKind(), aRefIt->first);
+    if (isConcealed) {
+      // check the referred object is a Body
+      // (for example, ExtrusionCut has a sketch as a first attribute which is concealing)
+      bool isBody = aRefIt->second.size() > 1 || (aRefIt->second.size() == 1 &&
+                    aRefIt->second.front()->groupName() == ModelAPI_ResultBody::group());
+      if (isBody && (isMainArg || aFoundRef == aReferences.end() ||
+          aData->isPrecedingAttribute(aRefIt->first, aFoundRef->first)))
+        aFoundRef = aRefIt;
+
+      if (isMainArg)
+        break;
+    }
+  }
+
+  // find an object which is concealed by theResult
+  if (aFoundRef != aReferences.end() && !aFoundRef->second.empty()) {
+    std::list<ObjectPtr>::const_iterator anObjIt = aFoundRef->second.begin();
+    int aResultIndex = theResultIndex;
+    while (--aResultIndex >= 0) {
+      ++anObjIt;
+      if (anObjIt == aFoundRef->second.end()) {
+        anObjIt = aFoundRef->second.begin();
+        break;
+      }
+    }
+    // check the result is a Body
+    if ((*anObjIt)->groupName() == ModelAPI_ResultBody::group()) {
+      // check the result is part of CompSolid
+      ResultPtr anObjRes = std::dynamic_pointer_cast<ModelAPI_Result>(*anObjIt);
+      ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(anObjRes);
+      if (aParentCompSolid)
+        anObjRes = aParentCompSolid;
+      return anObjRes->data()->name();
+    }
+  }
+
+  // compose default name by the name of the feature and the index of result
+  std::stringstream aDefaultName;
+  aDefaultName << anOwner->name();
+  // if there are several results (issue #899: any number of result),
+  // add unique prefix starting from second
+  if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
+    aDefaultName << "_" << theResultIndex + 1;
+  return aDefaultName.str();
+}
+
 } // namespace ModelAPI_Tools
index c119924cb88d16a43106dd9a0de15b69879d9de0..1a2db5e05b2ecc979215b76d11979e245c3f2ba4 100755 (executable)
@@ -186,6 +186,11 @@ MODELAPI_EXPORT void findRefsToFeatures(
 */
 MODELAPI_EXPORT void getConcealedResults(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                    std::list<std::shared_ptr<ModelAPI_Result> >& theResults);
+
+/*! Return the default name of the result according the the features it depends.
+ */
+MODELAPI_EXPORT std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
+                                           const int theResultIndex);
 }
 
 #endif
index 8f584ffefb4d6205122c52ff48528a46a14bd273..a2c8af67abe69d060c96f75bcb140f12376753e4 100644 (file)
@@ -115,6 +115,12 @@ class MODELAPI_EXPORT ModelAPI_ValidatorsFactory
   /// Returns true that it was registered that attribute conceals the referenced result
   virtual bool isConcealed(std::string theFeature, std::string theAttribute) = 0;
 
+  /// Register the attribute as a main argument of the feature
+  virtual void registerMainArgument(std::string theFeature, std::string theAttribute) = 0;
+
+  /// Returns true is the attribute is a main argument of the feature
+  virtual bool isMainArgument(std::string theFeature, std::string theAttribute) = 0;
+
   /// Register the case-attribute: this attribute is checked only if its case is selected
   virtual void registerCase(std::string theFeature, std::string theAttribute,
     const std::list<std::pair<std::string, std::string> >& theCases) = 0;
index 470b8e3d46370fb71390c05a79a13674b1dcca3f..e9d740ce076c8dedb9bd0c6e5a909c048cd52d8f 100644 (file)
@@ -60,6 +60,7 @@
   #include "ModelAPI_ResultField.h"
   #include "ModelAPI_Tools.h"
   #include "ModelAPI_ResultCompSolid.h"
+  #include "ModelAPI_Folder.h"
 
   #include <memory>
   #include <string>
index d94163a191e231dab4433599a4676e5ada4a8c41..bd2599e08c9ca09a496b8c57848ff9458289c8a2 100644 (file)
@@ -93,7 +93,7 @@ aSession.setActiveDocument(aPartSet)
 aPlane = aPartSet.addFeature("Plane")
 aPlane.string("creation_method").setValue("by_other_plane")
 aPlane.string("by_other_plane_option").setValue("by_distance_from_other")
-aPlane.selection("plane").selectSubShape("face", "Part_1/Extrusion_1_1/Generated_Face_1")
+aPlane.selection("plane").selectSubShape("face", "Part_1/Extrusion_1_1/Generated_Face_2")
 aPlane.real("distance").setValue(0.001)
 aPlane.boolean("reverse").setValue(False)
 aSession.finishOperation()
index c9b8d2ecf224d39cab84646ba30451f6375e7873..ef0f8c564e011606b8f3e6684eb9aa04d9e38b02 100755 (executable)
@@ -155,13 +155,13 @@ def check_owner(selection, topology_type, feature):
   aSession.abortOperation()
 
 # check faces
-check_owner("Extrusion_1_1/Generated_Face_1", "face", aBox)
-check_owner("Boolean_2_1/Modified_3", "face", aBox)
-check_owner("Boolean_1_1/Modified_1", "face", aHoleExt)
-check_owner("Boolean_2_1/Modified_2", "face", aTower)
+check_owner("_Extrusion_1_1/Generated_Face_1", "face", aBox)
+check_owner("Extrusion_3_1/Modified_3", "face", aBox)
+check_owner("Extrusion_1_1/Modified_1", "face", aHoleExt)
+check_owner("Extrusion_3_1/Modified_2", "face", aTower)
 # check edges without ambiguity
-check_owner("Boolean_2_1/Modified_3&Extrusion_1_1/Generated_Face_2", "edge", aBox)
-check_owner("Boolean_2_1/Modified_2&Extrusion_3_1/To_Face_1_1", "edge", aTower)
+check_owner("Extrusion_3_1/Modified_3&_Extrusion_1_1/Generated_Face_2", "edge", aBox)
+check_owner("Extrusion_3_1/Modified_2&_Extrusion_3_1/To_Face_1", "edge", aTower)
 
 # check the connected topology method: solid is not a compound of connected topology
 assert(aFuse.firstResult().shape().isConnectedTopology() == False)
index 53780a819979e2b8c01f3164915d46cc154f9c8b..431f7300d10ecd8a6a7ced984063650190976512 100644 (file)
@@ -79,8 +79,8 @@ model.do()
 #=========================================================================
 # Make a cylindrical hole using one of the produced faces
 #=========================================================================
-ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"))
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "_Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Modfied_4"))
 SketchCircle_1 = Sketch_3.addCircle(143.412751420315, -228.52745656314, 32.158435160764)
 ExtrusionCut_2.setNestedSketch(Sketch_3)
 
@@ -92,8 +92,8 @@ Part_1.document().setCurrentFeature(ExtrusionCut_1.feature(), True)
 #=========================================================================
 # Modify the cylindrical hole base face by another groove in the history before the hole is created
 #=========================================================================
-ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), -50, [model.selection("SOLID", "ExtrusionCut_1_1")])
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
+ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "__Extrusion_1_1/Generated_Face_3"), -50, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "__Extrusion_1_1/Generated_Face_1"))
 SketchLine_9 = Sketch_4.addLine(-176.701443076057, -151.212050129331, -91.83965287802501, -151.212050129331)
 SketchLine_10 = Sketch_4.addLine(-91.83965287802501, -151.212050129331, -91.83965287802501, -84.473709256573)
 SketchLine_11 = Sketch_4.addLine(-91.83965287802501, -84.473709256573, -176.701443076057, -84.473709256573)
@@ -125,6 +125,6 @@ import ModelAPI
 
 assert(ModelAPI.ModelAPI_Session.get().validators().validate(Sketch_4.feature()))
 assert(ModelAPI.ModelAPI_Session.get().validators().validate(ExtrusionCut_2.feature()))
-assert(Sketch_3.feature().selection("External").namingName() == "ExtrusionCut_3_1/Modfied_6")
+assert(Sketch_3.feature().selection("External").namingName() == "_Extrusion_1_1/Modfied_4")
 
 assert(model.checkPythonDump())
index daf3d34731eeb2e6ef43b24a0d864e34d9bc0b09..f332784e26f1084a3f47ebaeca9f037c0776867e 100644 (file)
@@ -66,7 +66,7 @@ Sketch_1.result().setName("tutu")
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "tutu/Face-SketchLine_1f-SketchLine_3f-SketchArc_1_2f-SketchArc_2_2f")], model.selection(), 10, 0)
 Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "tutu/Edge-SketchLine_2")])
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], model.selection("EDGE", "PartSet/OZ"), 100, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Extrusion_2_1/Generated_Edge_2&Extrusion_2_1/To_Edge_1"), model.selection("VERTEX", "Extrusion_2_1/Generated_Edge_1&Extrusion_2_1/To_Edge_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Edge_1_1/Generated_Edge_2&Edge_1_1/To_Edge_1"), model.selection("VERTEX", "Edge_1_1/Generated_Edge_1&Edge_1_1/To_Edge_1")])
 model.end()
 
 # check that resulting group selection is valid
index f7da0bf4c09382cc76dcef728823b5370be34129..0926071b411a39f5574b4cc39a7d44986d6ab46a 100644 (file)
@@ -55,11 +55,11 @@ 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)
+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")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("FACE", "Face_1_1")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Extrusion_1_1"))
+Remove_SubShapes_1.setSubShapesToKeep([model.selection("COMPSOLID", "Partition_1_1_1")])
 model.end()
 
 
@@ -67,10 +67,5 @@ model.end()
 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")
+assert(Remove_SubShapes_1.subshapesToKeep().size() == 1)
+assert(Remove_SubShapes_1.subshapesToKeep().value(0).namingName() == "Partition_1_1_1")
index 5b5684d5ba96de42044b45fae7c226070b39cb7c..dd5e5f8694c59b07eb34c221463c36216f277c4d 100644 (file)
@@ -99,7 +99,7 @@ Face_3 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-Sketc
 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"))
+SketchPoint_1 = Sketch_3.addPoint(model.selection("VERTEX", "Face_1_1/Edge_6&Face_1_1/Edge_7"))
 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)
@@ -121,16 +121,20 @@ 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"))
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_1_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Face_4_1/Edge_4&Face_4_1/Edge_5"))
+Translation_1.result().setName("Translation_1_1")
 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"))
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_2_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Face_4_1/Edge_2&Face_4_1/Edge_3"))
+Translation_2.result().setName("Translation_2_1")
 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"))
+Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Translation_2_1/Translated_Edge_1_4&Translation_2_1/Translated_Edge_1_3"))
+Translation_3.result().setName("Translation_3_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"))
+Translation_4 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_4_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Face_4_1/Edge_1&Face_4_1/Edge_9"))
+Translation_4.result().setName("Translation_4_1")
 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")
@@ -144,9 +148,10 @@ 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")])
+Shell_1.result().setName("Shell_1_1")
 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")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Face_3_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.end()
 
 # move groups
@@ -156,16 +161,27 @@ 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)
+# check that group 2 is correct, but Group_1 and Group_3 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)
+
+assert(Group_1.groupList().size() != 0)
+for a in range(Group_1.groupList().size()):
+  assert(len(Group_1.groupList().value(a).namingName()) == 0)
+
+assert(aFactory.validate(Group_3.feature()))
+assert(Group_3.groupList().size() != 0)
+for a in range(Group_3.groupList().size()):
+  assert(Group_3.groupList().value(a).value().shapeTypeStr() == "FACE")
+  assert(len(Group_3.groupList().value(a).namingName()) > 0)
+
+# for Group in [Group_1, Group_2, Group_3]:
+#   if Group == Group_2:
+#     assert(aFactory.validate(Group.feature()))
+#   assert(Group.groupList().size() != 0)
+#   for a in range(Group.groupList().size()):
+#     if Group != Group_2:
+#       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)
diff --git a/src/ModelAPI/Test/TestCustomName_BooleanCut.py b/src/ModelAPI/Test/TestCustomName_BooleanCut.py
new file mode 100644 (file)
index 0000000..fb24a17
--- /dev/null
@@ -0,0 +1,79 @@
+## 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 SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(70, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 50)
+SketchLine_3 = Sketch_1.addLine(0, 50, 70, 50)
+SketchLine_4 = Sketch_1.addLine(70, 50, 70, 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(), 70)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 50)
+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(), 10, 0)
+Extrusion_1.result().setName("box")
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r"))
+SketchLine_5 = Sketch_2.addLine(10, 55, 50, 55)
+SketchLine_6 = Sketch_2.addLine(50, 55, 50, -5)
+SketchLine_7 = Sketch_2.addLine(50, -5, 10, -5)
+SketchLine_8 = Sketch_2.addLine(10, -5, 10, 55)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintDistanceVertical_1 = Sketch_2.setVerticalDistance(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_7.endPoint(), -5)
+SketchConstraintDistanceHorizontal_1 = Sketch_2.setHorizontalDistance(SketchLine_8.startPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), -10)
+SketchConstraintLength_3 = Sketch_2.setLength(SketchLine_8.result(), 60)
+SketchConstraintLength_4 = Sketch_2.setLength(SketchLine_7.result(), 40)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")], model.selection(), 15, 5)
+Extrusion_2.result().setName("tool")
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "box")], [model.selection("SOLID", "tool")])
+model.do()
+
+assert(Boolean_1.result().name() == Extrusion_1.result().name()), "Boolean CUT name '{}' != '{}'".format(Boolean_1.result().name(), Extrusion_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_CommonCompSolid.py b/src/ModelAPI/Test/TestCustomName_CommonCompSolid.py
new file mode 100644 (file)
index 0000000..8e1e794
--- /dev/null
@@ -0,0 +1,62 @@
+## 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()
+Box_1 = model.addBox(Part_1_doc, 100, 100, 10)
+Box_1.result().setName("plate")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "plate/Front"), 50, True)
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "plate/Left"), 50, True)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "plate"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")])
+#Partition_1.result().setName("plate")
+Partition_1.result().subResult(0).setName("Partition_1_1_1")
+Partition_1.result().subResult(1).setName("top_left")
+Partition_1.result().subResult(2).setName("bottom_right")
+Partition_1.result().subResult(3).setName("Partition_1_1_4")
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Partition_1_1_1/Modified_Face_3_3"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Partition_1_1_1/Modified_Face_3_3&top_left/Modified_Face_3_1&bottom_right/Modified_Face_3_2"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchCircle_1 = Sketch_1.addCircle(50, 50, 40)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 40)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection(), 10, model.selection("FACE", "Partition_1_1_1/Modified_Face_3_4"), 10)
+Extrusion_1.result().setName("cylinder")
+Boolean_1 = model.addCommon(Part_1_doc, [model.selection("COMPSOLID", "plate")], [model.selection("SOLID", "cylinder")])
+model.do()
+
+# check the name of result is kept
+CommonResult = Boolean_1.result()
+CommonResultName = CommonResult.name()
+assert(CommonResultName == Partition_1.result().name()), "Name of Boolean COMMON result '{}' != '{}'".format(CommonResultName, Partition_1.result().name())
+# check sub-result names are lost
+BooleanName = Boolean_1.name() + "_1"
+for i in range(0, CommonResult.numberOfSubs()):
+  refName = BooleanName + '_' + str(i + 1)
+  subResult = CommonResult.subResult(i)
+  assert(subResult.name() == refName), "Boolean COMMON sub-result {} name '{}' != '{}'".format(i, subResult.name(), refName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_CutCompSolid.py b/src/ModelAPI/Test/TestCustomName_CutCompSolid.py
new file mode 100644 (file)
index 0000000..831f49f
--- /dev/null
@@ -0,0 +1,89 @@
+## 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 SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(80, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 80)
+SketchLine_3 = Sketch_1.addLine(0, 80, 80, 80)
+SketchLine_4 = Sketch_1.addLine(80, 80, 80, 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(35, 80, 65, 0)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_3.result())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_1.result())
+SketchLine_6 = Sketch_1.addLine(0, 20, 80, 50)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_6.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_4.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_5.result(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), 80)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_6.startPoint(), SketchLine_1.endPoint(), -20)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_1.startPoint(), 15)
+SketchConstraintDistanceVertical_2 = Sketch_1.setVerticalDistance(SketchLine_6.endPoint(), SketchLine_1.startPoint(), -50)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 50, 0)
+Extrusion_1.result().setName("compsolid")
+
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "compsolid/Generated_Face_5"))
+SketchCircle_1 = Sketch_2.addCircle(65, -30, 10)
+SketchConstraintRadius_1 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "compsolid/Generated_Face_5&compsolid/Generated_Face_4&compsolid/To_Face_3"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintDistanceVertical_3 = Sketch_2.setVerticalDistance(SketchAPI_Point(SketchPoint_2).coordinates(), SketchCircle_1.center(), 20)
+SketchConstraintDistanceHorizontal_2 = Sketch_2.setHorizontalDistance(SketchCircle_1.center(), SketchAPI_Point(SketchPoint_2).coordinates(), 15)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2f")], model.selection(), model.selection(), 10, model.selection("FACE", "compsolid/Generated_Face_1"), 10)
+Extrusion_2.result().setName("cyl")
+
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1_3")], [model.selection("SOLID", "cyl")])
+model.do()
+
+# check the name of Extrusion_1 is kept
+CutResult = Boolean_1.result()
+CutResultName = CutResult.name()
+assert(CutResultName == Extrusion_1.result().name()), "Name of Boolean CUT result '{}' != '{}'".format(CutResultName, Extrusion_1.result().name())
+# check sub-result names are lost
+BooleanName = Boolean_1.name() + "_1"
+for i in range(0, CutResult.numberOfSubs()):
+  refName = BooleanName + '_' + str(i + 1)
+  subResult = CutResult.subResult(i)
+  assert(subResult.name() == refName), "Boolean CUT sub-result {} name '{}' != '{}'".format(i, subResult.name(), refName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_CutGroup.py b/src/ModelAPI/Test/TestCustomName_CutGroup.py
new file mode 100644 (file)
index 0000000..d4fb33a
--- /dev/null
@@ -0,0 +1,107 @@
+## 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 SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(70, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 40)
+SketchLine_3 = Sketch_1.addLine(0, 40, 70, 40)
+SketchLine_4 = Sketch_1.addLine(70, 40, 70, 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_1.result(), 70)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 40)
+SketchCircle_1 = Sketch_1.addCircle(30, 70, 20)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 20)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 30, True)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchLine_2.startPoint(), -30)
+SketchLine_5 = Sketch_1.addLine(12.50000000006628, -45.31088913249455, 30, -15)
+SketchLine_6 = Sketch_1.addLine(30, -15, 47.50000000006629, -45.31088913249455)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_1.addLine(47.50000000006629, -45.31088913249455, 12.50000000006628, -45.31088913249455)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_7.endPoint())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_7.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_6.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_7.result(), 35)
+SketchConstraintDistanceHorizontal_2 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_2.startPoint(), -30)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_5.endPoint(), SketchLine_2.startPoint(), 15)
+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(), 10, 0)
+Extrusion_1.result().setName("box")
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r")], model.selection(), 20, 20)
+Extrusion_2.result().setName("prism")
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 10, 0)
+Extrusion_3.result().setName("cylinder")
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "box/From_Face_1"))
+SketchLine_8 = Sketch_2.addLine(45, 30, 25, 30)
+SketchLine_9 = Sketch_2.addLine(25, 30, 25, -100)
+SketchLine_10 = Sketch_2.addLine(25, -100, 45, -100)
+SketchLine_11 = Sketch_2.addLine(45, -100, 45, 30)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_8.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_9.result())
+SketchConstraintHorizontal_5 = Sketch_2.setHorizontal(SketchLine_10.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_11.result())
+SketchConstraintLength_4 = Sketch_2.setLength(SketchLine_10.result(), 20)
+SketchConstraintLength_5 = Sketch_2.setLength(SketchLine_9.result(), 130)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "box/Generated_Face_3&box/Generated_Face_2&box/From_Face_1"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintDistanceVertical_2 = Sketch_2.setVerticalDistance(SketchLine_8.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), -30)
+SketchConstraintDistanceHorizontal_3 = Sketch_2.setHorizontalDistance(SketchLine_8.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), -25)
+model.do()
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_8f-SketchLine_9f-SketchLine_10f-SketchLine_11f")], model.selection(), 5, 15)
+Extrusion_4.result().setName("cut_tool")
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "box"), model.selection("SOLID", "prism"), model.selection("SOLID", "cylinder")], [model.selection("SOLID", "cut_tool")])
+model.do()
+
+Extrusions = [Extrusion_1, Extrusion_2, Extrusion_3]
+BooleanResults = Boolean_1.results()
+for i in xrange(len(BooleanResults)):
+  assert(BooleanResults[i].name() == Extrusions[i].result().name()), "Name of result {} of Boolean CUT '{}' != '{}'".format(i, BooleanResults[i].name(), Extrusions[i].result().name())
+  BooleanName = Boolean_1.name() + "_" + str(i + 1)
+  for sub in range(0, BooleanResults[i].numberOfSubs()):
+    refName = BooleanName + '_' + str(sub + 1)
+    subResult = BooleanResults[i].subResult(sub)
+    assert(subResult.name() == refName), "Name of sub-result {} of result {} of Boolean CUT '{}' != '{}'".format(sub, i, subResult.name(), refName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_DefaultName.py b/src/ModelAPI/Test/TestCustomName_DefaultName.py
new file mode 100644 (file)
index 0000000..f1149d7
--- /dev/null
@@ -0,0 +1,35 @@
+## 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()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), 10)
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("SOLID", "Sphere_1_1")])
+Boolean_1.result().setName("Boolean_1_1")
+model.do()
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_ExtrudeFace.py b/src/ModelAPI/Test/TestCustomName_ExtrudeFace.py
new file mode 100644 (file)
index 0000000..e1fa838
--- /dev/null
@@ -0,0 +1,50 @@
+## 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, 68.31067519504786, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(68.31067519504786, 0, 0, 68.31067519504786)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 68.31067519504786, 0, 0)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_1.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3")])
+Face_1.result().setName("triangle")
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "triangle")], model.selection(), 10, 0)
+model.do()
+
+assert(Extrusion_1.result().name() == Face_1.result().name()), "Extrusion name '{}' != '{}'".format(Extrusion_1.result().name(), Face_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_ExtrusionCut.py b/src/ModelAPI/Test/TestCustomName_ExtrusionCut.py
new file mode 100644 (file)
index 0000000..9d08321
--- /dev/null
@@ -0,0 +1,65 @@
+## 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(50.00000000000001, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 50)
+SketchLine_3 = Sketch_1.addLine(0, 50, 50, 50)
+SketchLine_4 = Sketch_1.addLine(50, 50, 50.00000000000001, 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_1.result(), 50)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_2.result(), SketchLine_1.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(), 20, 0)
+Extrusion_1.result().setName("plate")
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "plate")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "plate/To_Face_1"))
+SketchCircle_1 = Sketch_2.addCircle(30, 35, 10)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "plate/Generated_Face_4&plate/To_Face_1"), False)
+SketchLine_5 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_1 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_5.result(), 20, True)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "plate/Generated_Face_1&plate/To_Face_1"), False)
+SketchLine_6 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_6.result(), 15, True)
+SketchConstraintRadius_1 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+ExtrusionCut_1.setNestedSketch(Sketch_2)
+model.do()
+
+assert(ExtrusionCut_1.result().name() == Extrusion_1.result().name()), "ExtrusionCut name '{}' != '{}'".format(ExtrusionCut_1.result().name(), Extrusion_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_ExtrusionCutFace.py b/src/ModelAPI/Test/TestCustomName_ExtrusionCutFace.py
new file mode 100644 (file)
index 0000000..b20f90a
--- /dev/null
@@ -0,0 +1,41 @@
+## 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()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Box_1.result().setName("box")
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "box/Front"))
+SketchCircle_1 = Sketch_1.addCircle(7, 6, 2)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Face_1.result().setName("circle")
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "circle")], model.selection(), 0, 3, [model.selection("SOLID", "box")])
+model.do()
+
+assert(ExtrusionCut_1.result().name() == Box_1.result().name()), "ExtrusionCut name '{}' != '{}'".format(ExtrusionCut_1.result().name(), Box_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_MultiTranslation.py b/src/ModelAPI/Test/TestCustomName_MultiTranslation.py
new file mode 100644 (file)
index 0000000..6e008ee
--- /dev/null
@@ -0,0 +1,48 @@
+## 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 *
+
+NB_COPIES = 3
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Cylinder_1.result().setName("cylinder")
+MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "cylinder")], model.selection("EDGE", "cylinder/Face_1"), 10, NB_COPIES)
+model.do()
+
+TransResult = MultiTranslation_1.result()
+TransResultName = TransResult.name()
+assert(TransResultName == Cylinder_1.result().name()), "MultiTranslation name '{}' != '{}'".format(TransResultName, Cylinder_1.result().name())
+# check sub-result names
+assert(NB_COPIES == TransResult.numberOfSubs()), "Number of results {} is not equal to reference {}".format(TransResult.numberOfSubs(), NB_COPIES)
+MultiTranslationName = MultiTranslation_1.name() + "_1"
+for i in range(0, NB_COPIES):
+  refName = MultiTranslationName + '_' + str(i + 1)
+  subResult = TransResult.subResult(i)
+  assert(subResult.name() == refName), "MultiTranslation sub-result {} name '{}' != '{}'".format(i, subResult.name(), refName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_Partition.py b/src/ModelAPI/Test/TestCustomName_Partition.py
new file mode 100644 (file)
index 0000000..b660c67
--- /dev/null
@@ -0,0 +1,46 @@
+## 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()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Cylinder_1.result().setName("cylinder")
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Box_1.result().setName("box")
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "box"), model.selection("SOLID", "cylinder")])
+model.do()
+
+PartitionResult = Partition_1.result()
+PartitionResultName = PartitionResult.name()
+assert(PartitionResultName == Box_1.result().name()), "Partition name '{}' != '{}'".format(PartitionResultName, Box_1.result().name())
+# check sub-result names
+PartitionName = Partition_1.name() + "_1"
+for i in range(0, PartitionResult.numberOfSubs()):
+  refName = PartitionName + '_' + str(i + 1)
+  subResult = PartitionResult.subResult(i)
+  assert(subResult.name() == refName), "Partition sub-result {} name '{}' != '{}'".format(i, subResult.name(), refName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_Placement.py b/src/ModelAPI/Test/TestCustomName_Placement.py
new file mode 100644 (file)
index 0000000..b8cd116
--- /dev/null
@@ -0,0 +1,56 @@
+## 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(30, 76.16895059675974, 30, 16.16895059675975)
+SketchLine_2 = Sketch_1.addLine(30, 16.16895059675975, 55.98076211353315, 31.16895059675975)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(55.98076211353315, 31.16895059675975, 30, 76.16895059675974)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_2.result(), SketchLine_3.result())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_3.result(), 30)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 60)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_4 = SketchProjection_1.createdFeature()
+SketchConstraintMirror_1_objects = [SketchLine_2.result(), SketchLine_1.result(), SketchLine_3.result()]
+SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_4.result(), SketchConstraintMirror_1_objects)
+[SketchLine_5, SketchLine_6, SketchLine_7] = SketchConstraintMirror_1.mirrored()
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_2.startPoint(), SketchLine_4.result(), 30, True)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f")], model.selection(), 20, 0)
+Extrusion_1.result().setName("prism")
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_6"), 360, 0)
+Revolution_1.result().setName("spinner")
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "spinner")], model.selection("VERTEX", "spinner/Lateral_Edge_1&spinner/Base_Edge_1"), model.selection("FACE", "prism/Generated_Face_2"), False, True)
+model.do()
+
+assert(Placement_1.result().name() == Revolution_1.result().name()), "Placement name '{}' != '{}'".format(Placement_1.result().name(), Revolution_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_Recover.py b/src/ModelAPI/Test/TestCustomName_Recover.py
new file mode 100644 (file)
index 0000000..e069c44
--- /dev/null
@@ -0,0 +1,46 @@
+## 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()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Cylinder_1.result().setName("cylinder")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "cylinder/Face_2"), 10, False)
+Symmetry_1 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "cylinder")], model.selection("FACE", "Plane_1"))
+model.do()
+
+# check the name of the Symmetry
+SymmetryName = Symmetry_1.result().name()
+assert(SymmetryName == Cylinder_1.result().name()), "Symmetry name '{}' != '{}'".format(SymmetryName, Cylinder_1.result().name())
+
+# recover original cylinder
+Recover_1 = model.addRecover(Part_1_doc, Symmetry_1, [Cylinder_1.result()])
+model.do()
+
+# check the name of the recovered result is not the cylinder name
+assert(Recover_1.result().name() != SymmetryName), "Recovered feature SHOULD NOT have the same name as original feature '{}'".format(SymmetryName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_Rename.py b/src/ModelAPI/Test/TestCustomName_Rename.py
new file mode 100644 (file)
index 0000000..f755a72
--- /dev/null
@@ -0,0 +1,61 @@
+## 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()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Cylinder_1.result().setName("cylinder")
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Box_1.result().setName("box")
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "box"), model.selection("SOLID", "cylinder")])
+model.do()
+
+# check name of result and its subs before rename
+PartitionResult = Partition_1.result()
+PartitionResultName = PartitionResult.name()
+assert(PartitionResultName == Box_1.result().name()), "Partition name '{}' != '{}'".format(PartitionResultName, Box_1.result().name())
+# check sub-result names
+PartitionName = Partition_1.name() + "_1"
+PartitionSubresultNames = []
+for i in range(0, PartitionResult.numberOfSubs()):
+  refName = PartitionName + '_' + str(i + 1)
+  subResult = PartitionResult.subResult(i)
+  assert(subResult.name() == refName), "Partition sub-result {} name '{}' != '{}'".format(i, subResult.name(), refName)
+  PartitionSubresultNames.append(refName)
+
+# rename original objects before the Partition
+Cylinder_1.result().setName("new_cylinder")
+Box_1.result().setName("new_box")
+model.do()
+
+# check names of the Partition does not changed
+assert(PartitionResultName == PartitionResult.name()), "After rename: Partition name '{}' != '{}'".format(PartitionResult.name(), PartitionResultName)
+for i in range(0, PartitionResult.numberOfSubs()):
+  refName = PartitionSubresultNames[i]
+  subResult = PartitionResult.subResult(i)
+  assert(subResult.name() == refName), "After rename: Partition sub-result {} name '{}' != '{}'".format(i, subResult.name(), refName)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_RotateGroup.py b/src/ModelAPI/Test/TestCustomName_RotateGroup.py
new file mode 100644 (file)
index 0000000..cb36786
--- /dev/null
@@ -0,0 +1,55 @@
+## 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()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Cylinder_1.result().setName("cylinder")
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOZ"))
+SketchArc_1 = Sketch_1.addArc(13.72530642620941, 12.64599334927434, 17.72530642621026, 15.64599334928998, 17.72530642621026, 9.645993349258699, False)
+SketchArc_2 = Sketch_1.addArc(21.72530642620941, 12.64599334927434, 17.72530642621026, 9.645993349258699, 17.72530642621026, 15.64599334928998, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchArc_2.endPoint())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchArc_1.results()[1], SketchArc_2.results()[1])
+SketchLine_1 = Sketch_1.addLine(13.72530642620941, 12.64599334927434, 21.72530642620941, 12.64599334927434)
+SketchLine_1.setAuxiliary(True)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_1.endPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 5)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_1.startPoint(), SketchLine_1.endPoint(), 8, True)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchArc_2_2f")], model.selection(), 10, 0)
+Extrusion_1.result().setName("prism")
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "prism"), model.selection("SOLID", "cylinder")], model.selection("EDGE", "PartSet/OX"), 30)
+model.do()
+
+RotationResults = Rotation_1.results()
+assert(RotationResults[0].name() == Extrusion_1.result().name()), "Rotation name [0] '{}' != '{}'".format(RotationResults[0].name(), Extrusion_1.result().name())
+assert(RotationResults[1].name() == Cylinder_1.result().name()),  "Rotation name [1] '{}' != '{}'".format(RotationResults[1].name(), Cylinder_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestCustomName_Translation.py b/src/ModelAPI/Test/TestCustomName_Translation.py
new file mode 100644 (file)
index 0000000..bad08c5
--- /dev/null
@@ -0,0 +1,36 @@
+## 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()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Cylinder_1.result().setName("cylinder")
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "cylinder")], model.selection("EDGE", "cylinder/Face_1"), 20)
+model.do()
+
+assert(Translation_1.result().name() == Cylinder_1.result().name()), "Translation name '{}' != '{}'".format(Translation_1.result().name(), Cylinder_1.result().name())
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestFolder_Create.py b/src/ModelAPI/Test/TestFolder_Create.py
new file mode 100644 (file)
index 0000000..36d429a
--- /dev/null
@@ -0,0 +1,108 @@
+## 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>
+##
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-22"
+
+#=========================================================================
+# Test 1. Check the Folder is created in PartSet
+#=========================================================================
+aSession = ModelAPI_Session.get()
+aPartSetDoc = aSession.activeDocument()
+
+aSession.startOperation()
+aPoint0 = aPartSetDoc.addFeature("Point")
+aPoint0Data = aPoint0.data()
+assert(aPoint0Data is not None)
+aPoint0Data.real("x").setValue(0.)
+aPoint0Data.real("y").setValue(0.)
+aPoint0Data.real("z").setValue(0.)
+aPoint0Data.string("creation_method").setValue("by_xyz")
+aSession.finishOperation()
+
+aSession.startOperation()
+aPoint1 = aPartSetDoc.addFeature("Point")
+aPoint1Data = aPoint1.data()
+assert(aPoint1Data is not None)
+aPoint1Data.real("x").setValue(0.)
+aPoint1Data.real("y").setValue(0.)
+aPoint1Data.real("z").setValue(0.)
+aPoint1Data.string("creation_method").setValue("by_xyz")
+aSession.finishOperation()
+
+assert(aPartSetDoc.size("Features") == 2), "Wrong number of features: {}".format(aPartSetDoc.size("Features"))
+
+# Folder before the feature
+aSession.startOperation()
+aFolder1 = aPartSetDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+assert(aPartSetDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartSetDoc.size("Folders"))
+assert(aPartSetDoc.size("Features") == 3), "Wrong number of features: {}".format(aPartSetDoc.size("Features"))
+FOLDER_NAME_EXPECTED = "Folder_1"
+assert(aFolder1.name() == FOLDER_NAME_EXPECTED), "Actual name '{}', expected '{}'".format(aFolder1.name(), FOLDER_NAME_EXPECTED)
+
+## Folder at the end of features list
+#aSession.startOperation()
+#aPartSetDoc.addFolder()
+#aSession.finishOperation()
+#assert(aPartSetDoc.size("Folders") == 2)
+
+#=========================================================================
+# Test 2. Check the Folder is created in a Part
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# check part is a last feature
+aFeaturesList = aSession.moduleDocument().allObjects()
+aLast = aFeaturesList[len(aFeaturesList)-1]
+assert(aLast.data().isEqual(aPart.data())), "Part is not a last object in the list"
+
+# add point and a folder before it
+aPartDoc = aSession.activeDocument()
+aSession.startOperation()
+aPoint2 = aPartDoc.addFeature("Point")
+aPoint2Data = aPoint2.data()
+assert(aPoint2Data is not None)
+aPoint2Data.real("x").setValue(0.)
+aPoint2Data.real("y").setValue(0.)
+aPoint2Data.real("z").setValue(0.)
+aPoint2Data.string("creation_method").setValue("by_xyz")
+aSession.finishOperation()
+
+assert(aPartDoc.size("Features") == 1), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint2)
+aSession.finishOperation()
+
+assert(aPartDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == 2), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+FOLDER_NAME_EXPECTED = "Folder_1"
+assert(aFolder2.name() == FOLDER_NAME_EXPECTED), "Actual name '{}', expected '{}'".format(aFolder2.name(), FOLDER_NAME_EXPECTED)
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestFolder_Remove.py b/src/ModelAPI/Test/TestFolder_Remove.py
new file mode 100644 (file)
index 0000000..6e78b58
--- /dev/null
@@ -0,0 +1,154 @@
+## 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>
+##
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-24"
+
+aSession = ModelAPI_Session.get()
+
+
+def newPoint(theDocument, theX, theY, theZ):
+    aSession.startOperation()
+    aPoint = theDocument.addFeature("Point")
+    aPointData = aPoint.data()
+    assert(aPointData is not None)
+    aPointData.real("x").setValue(theX)
+    aPointData.real("y").setValue(theY)
+    aPointData.real("z").setValue(theZ)
+    aPointData.string("creation_method").setValue("by_xyz")
+    aSession.finishOperation()
+    return aPoint
+
+
+#=========================================================================
+# Prepare some features and folders
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# add points
+aPartDoc = aSession.activeDocument()
+aPoint1 = newPoint(aPartDoc,  0.,  0., 0.)
+aPoint2 = newPoint(aPartDoc, 10.,  0., 0.)
+aPoint3 = newPoint(aPartDoc, 10., 10., 0.)
+aPoint4 = newPoint(aPartDoc,  0., 10., 0.)
+
+# add folders
+aSession.startOperation()
+aFolder1 = aPartDoc.addFolder(aPoint2)
+aSession.finishOperation()
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint2)
+aSession.finishOperation()
+aSession.startOperation()
+aFolder3 = aPartDoc.addFolder(aPoint3)
+aSession.finishOperation()
+
+# place points into folders
+toFolder = FeatureList()
+toFolder.append(aPoint1)
+
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+toFolder = FeatureList()
+toFolder.append(aPoint3)
+toFolder.append(aPoint4)
+
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_FULL = 7
+NB_FEATURES_OUT  = 4
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder1, True) == 0), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder1, True))
+assert(aPartDoc.index(aFolder2, True) == 1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder2, True))
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aPartDoc.index(aPoint1, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint1, True))
+assert(aPartDoc.index(aPoint2, True) ==  2), "Wrong index of the point: {}".format(aPartDoc.index(aPoint2, True))
+assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+
+#=========================================================================
+# Test 1. Remove empty folder
+#=========================================================================
+aSession.startOperation()
+aPartDoc.removeFolder(aFolder2)
+aSession.finishOperation()
+
+NB_FEATURES_FULL -= 1
+NB_FEATURES_OUT  -= 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder1, True) == 0), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder1, True))
+assert(aPartDoc.index(aFolder2, True) == -1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder2, True))
+assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aPartDoc.index(aPoint1, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint1, True))
+assert(aPartDoc.index(aPoint2, True) ==  1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint2, True))
+assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+
+#=========================================================================
+# Test 2. Remove non-empty folder
+#=========================================================================
+aSession.startOperation()
+aPartDoc.removeFolder(aFolder3)
+aSession.finishOperation()
+
+NB_FEATURES_FULL -= 1
+NB_FEATURES_OUT  += 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder1, True) == 0), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder1, True))
+assert(aPartDoc.index(aFolder2, True) == -1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder2, True))
+assert(aPartDoc.index(aFolder3, True) == -1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aPartDoc.index(aPoint1, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint1, True))
+assert(aPartDoc.index(aPoint2, True) ==  1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint2, True))
+assert(aPartDoc.index(aPoint3, True) ==  2), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) ==  3), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestFolder_Sketch.py b/src/ModelAPI/Test/TestFolder_Sketch.py
new file mode 100644 (file)
index 0000000..bf6768a
--- /dev/null
@@ -0,0 +1,187 @@
+## 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 checks adding sketch into a folder
+"""
+
+from ModelAPI import *
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+Sketch_0 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_0.addLine(10, -10, 10, 10)
+model.do()
+
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(50, 50, 25)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2f")], model.selection(), 50, 0)
+
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchCircle_2 = Sketch_2.addCircle(100, -100, 50)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 10, 0)
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_2_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/To_Face_1"))
+SketchProjection_1 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_1__cc"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchCircle_3 = Sketch_3.addCircle(100, -100, 25)
+SketchConstraintCoincidence_1 = Sketch_3.setCoincident(SketchPoint_1.result(), SketchCircle_3.center())
+ExtrusionCut_1.setNestedSketch(Sketch_3)
+model.do()
+model.end()
+
+
+aSession = ModelAPI_Session.get()
+aPartDoc = aSession.activeDocument()
+
+#=========================================================================
+# Test 1. Sketch and extrusion could be added to the folder above
+#=========================================================================
+aSession.startOperation()
+Folder_1 = aPartDoc.addFolder(Sketch_1.feature())
+aSession.finishOperation()
+
+NB_FEATURES_FULL = 7
+NB_FEATURES_OUT  = 7
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+toFolder = FeatureList()
+toFolder.append(Sketch_1.feature())
+toFolder.append(Extrusion_1.feature())
+
+# move features to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None and aFolder.data().isEqual(Folder_1.data()))
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 2
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the sketch in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_1.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 0)
+# check the index of the extrusion in the folder
+aFound = aPartDoc.findContainingFolder(Extrusion_1.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 1)
+
+
+#=========================================================================
+# Test 2. Sketch could be added to the folder below
+#=========================================================================
+aSession.startOperation()
+Folder_2 = aPartDoc.addFolder(Extrusion_2.feature())
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT  += 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+toFolder = FeatureList()
+toFolder.append(Sketch_2.feature())
+
+# move feature to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None and aFolder.data().isEqual(Folder_2.data()))
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the sketch in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_2.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 0)
+
+
+#=========================================================================
+# Test 3. Sketch could be removed from the folder
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(Sketch_1.feature())
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+assert(aPartDoc.index(Sketch_1.feature(), True) == 1), "Wrong index of the {}: {}".format(Sketch_1.feature().name(), aPartDoc.index(Sketch_1.feature(), True))
+NB_FEATURES_OUT += 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+
+#=========================================================================
+# Test 4. Add 2 sketches to the folder below
+#=========================================================================
+
+toFolder = FeatureList()
+toFolder.append(Sketch_0.feature())
+toFolder.append(Sketch_1.feature())
+
+# move features to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None and aFolder.data().isEqual(Folder_1.data()))
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 2
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the sketch in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_0.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 0)
+# check the index of the extrusion in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_1.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 1)
+
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestFolder_Stability.py b/src/ModelAPI/Test/TestFolder_Stability.py
new file mode 100644 (file)
index 0000000..bbd867c
--- /dev/null
@@ -0,0 +1,98 @@
+## 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 checks stability of the foldering mechanism due to incorrect input parameters
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-23"
+
+aSession = ModelAPI_Session.get()
+
+
+def newPoint(theDocument, theX, theY, theZ):
+    aSession.startOperation()
+    aPoint = theDocument.addFeature("Point")
+    aPointData = aPoint.data()
+    assert(aPointData is not None)
+    aPointData.real("x").setValue(theX)
+    aPointData.real("y").setValue(theY)
+    aPointData.real("z").setValue(theZ)
+    aPointData.string("creation_method").setValue("by_xyz")
+    aSession.finishOperation()
+    return aPoint
+
+
+#=========================================================================
+# Initialization of the model
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# add point and a folder before it
+aPartDoc = aSession.activeDocument()
+aPoint1 = newPoint(aPartDoc, 0., 0., 0.)
+
+aSession.startOperation()
+aFolder1 = aPartDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+NB_FEATURES_FULL = 2
+NB_FEATURES_OUT  = 2
+
+assert(aPartDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+
+#=========================================================================
+# Test 1. Check number of features out of folder
+#         and absense of the crash while getting size of incorrect group
+#=========================================================================
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+assert(aPartDoc.size("Construction", True) == 1), "Wrong size: {}".format(aPartDoc.size("Construction", True))
+
+#=========================================================================
+# Test 2. Add a feature to the folder and check number of features once again
+#=========================================================================
+toFolder = FeatureList()
+toFolder.append(aPoint1)
+
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT  += 1
+
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_OUT -= 1
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+assert(aPartDoc.size("Construction", True) == 1), "Wrong size: {}".format(aPartDoc.size("Construction", True))
+
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/ModelAPI/Test/TestFolder_Update.py b/src/ModelAPI/Test/TestFolder_Update.py
new file mode 100644 (file)
index 0000000..c16eb03
--- /dev/null
@@ -0,0 +1,355 @@
+## 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>
+##
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-23"
+
+aSession = ModelAPI_Session.get()
+
+
+def newPoint(theDocument, theX, theY, theZ):
+    aSession.startOperation()
+    aPoint = theDocument.addFeature("Point")
+    aPointData = aPoint.data()
+    assert(aPointData is not None)
+    aPointData.real("x").setValue(theX)
+    aPointData.real("y").setValue(theY)
+    aPointData.real("z").setValue(theZ)
+    aPointData.string("creation_method").setValue("by_xyz")
+    aSession.finishOperation()
+    return aPoint
+
+
+#=========================================================================
+# Test 1. Add a point into a folder above
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# add point and a folder before it
+aPartDoc = aSession.activeDocument()
+aPoint1 = newPoint(aPartDoc, 0., 0., 0.)
+
+aSession.startOperation()
+aFolder1 = aPartDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+NB_FEATURES_FULL = 2
+NB_FEATURES_OUT  = 2
+
+assert(aPartDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == 2), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+FOLDER_NAME_EXPECTED = "Folder_1"
+assert(aFolder1.name() == FOLDER_NAME_EXPECTED), "Actual name '{}', expected '{}'".format(aFolder1.name(), FOLDER_NAME_EXPECTED)
+
+toFolder = FeatureList()
+toFolder.append(aPoint1)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint1)
+assert(aFound[0].data().isEqual(aFolder1.data()))
+assert(aFound[1] == 0)
+
+#=========================================================================
+# Test 2. Add a point into a folder below
+#=========================================================================
+aPoint2 = newPoint(aPartDoc, 10., 0., 0.)
+aPoint3 = newPoint(aPartDoc, 10., 10., 0.)
+
+NB_FEATURES_FULL += 2
+NB_FEATURES_OUT += 2
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# add a folder
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint3)
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Folders") == 2), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+toFolder = FeatureList()
+toFolder.append(aPoint2)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_OUT -= 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint2)
+assert(aFound[0].data().isEqual(aFolder2.data()))
+assert(aFound[1] == 0)
+aFound = aPartDoc.findContainingFolder(aPoint3)
+assert(aFound == -1)
+
+#=========================================================================
+# Test 3. Add several points into a folder
+#=========================================================================
+aPoint4 = newPoint(aPartDoc, 0., 10., 0.)
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# index without respect to foldering
+assert(aPartDoc.index(aPoint4) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4))
+# index according to folders
+assert(aPartDoc.index(aPoint4, True) == 3), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+# add a folder
+aSession.startOperation()
+aFolder3 = aPartDoc.addFolder(aPoint3)
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Folders") == 3), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# index without respect to foldering
+assert(aPartDoc.index(aFolder3) == 4), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3))
+assert(aPartDoc.index(aPoint4) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4))
+# index according to folders
+assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint4, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+toFolder = FeatureList()
+toFolder.append(aPoint3)
+toFolder.append(aPoint4)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_OUT -= 2
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# index without respect to foldering
+assert(aPartDoc.index(aFolder3) == 4), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3))
+assert(aPartDoc.index(aPoint3) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3))
+assert(aPartDoc.index(aPoint4) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4))
+# index according to folders
+assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint3)
+assert(aFound[0].data().isEqual(aFolder3.data()))
+assert(aFound[1] == 0)
+aFound = aPartDoc.findContainingFolder(aPoint4)
+assert(aFound[0].data().isEqual(aFolder3.data()))
+assert(aFound[1] == 1)
+
+
+# add more points to the folder to move them out
+aPoint5 = newPoint(aPartDoc, 0., 0., 10.)
+aPoint6 = newPoint(aPartDoc, 10., 0., 10.)
+aPoint7 = newPoint(aPartDoc, 10., 10., 10.)
+aPoint8 = newPoint(aPartDoc, 0., 10., 10.)
+
+toFolder = FeatureList()
+toFolder.append(aPoint5)
+toFolder.append(aPoint6)
+toFolder.append(aPoint7)
+toFolder.append(aPoint8)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_FULL += 4
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aPoint5, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint5, True))
+assert(aPartDoc.index(aPoint6, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint7, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint7, True))
+assert(aPartDoc.index(aPoint8, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 4. Remove a point from a folder before it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint3)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 1
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aPoint3, True) == 2), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 5. Remove a point from a folder after it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint8)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 1
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aPoint8, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 6. Try to remove several points which are not start nor end in a folder
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint5)
+fromFolder.append(aPoint6)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut is False)
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint5, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint5, True))
+assert(aPartDoc.index(aPoint6, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint8, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 7. Remove several points from a folder after it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint6)
+fromFolder.append(aPoint7)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 2
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint6, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint7, True) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint7, True))
+assert(aPartDoc.index(aPoint8, True) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 8. Remove all remaining points from a folder after it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint4)
+fromFolder.append(aPoint5)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder, False)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 2
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint4, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+assert(aPartDoc.index(aPoint5, True) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint5, True))
+assert(aPartDoc.index(aPoint6, True) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint7, True) == 7), "Wrong index of the point: {}".format(aPartDoc.index(aPoint7, True))
+assert(aPartDoc.index(aPoint8, True) == 8), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+# folder is empty
+assert(aFolder3.reference("first_feature").value() is None)
+assert(aFolder3.reference("last_feature").value() is None)
+
+
+from salome.shaper import model
+assert(model.checkPythonDump())
index f33878dcfc911ac0280a69afbd78c9b747784af4..9c0cfb10c7dabc5f3fe155efa7986b9f92d606f8 100644 (file)
@@ -33,6 +33,7 @@ SET(PROJECT_HEADERS
   ModelHighAPI_Services.h
   ModelHighAPI_Tools.h
   ModelHighAPI_FeatureStore.h
+  ModelHighAPI_Folder.h
 )
 
 SET(PROJECT_SOURCES
@@ -46,6 +47,7 @@ SET(PROJECT_SOURCES
   ModelHighAPI_Services.cpp
   ModelHighAPI_Tools.cpp
   ModelHighAPI_FeatureStore.cpp
+  ModelHighAPI_Folder.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 7010d848143a09e50c63e061a6426e09b2fa5984..0b49cf05c46f9696caef19d8b3a333fd61b969ad 100644 (file)
@@ -57,6 +57,7 @@
 
 // shared pointers
 %shared_ptr(ModelHighAPI_Interface)
+%shared_ptr(ModelHighAPI_Folder)
 
 // typemaps
 
 %include "ModelHighAPI_Dumper.h"
 %include "ModelHighAPI_Integer.h"
 %include "ModelHighAPI_Interface.h"
+%include "ModelHighAPI_Folder.h"
 %include "ModelHighAPI_RefAttr.h"
 %include "ModelHighAPI_Reference.h"
 %include "ModelHighAPI_Selection.h"
index c005e37f024c72b879ab113212078447dcae4955..a5073da9e1ec3a84d6581afb1e64b45f228ecd9e 100644 (file)
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Entity.h>
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
 #include <ModelAPI_Result.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Tools.h>
 
 #include <PartSetPlugin_Part.h>
 
@@ -94,6 +96,9 @@ void ModelHighAPI_Dumper::clear(bool bufferOnly)
     myFeatureCount.clear();
     while (!myEntitiesStack.empty())
       myEntitiesStack.pop();
+
+    myPostponed.clear();
+    myDumpPostponedInProgress = false;
   }
 }
 
@@ -123,14 +128,26 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity,
     return aFound->second.myCurrentName;
 
   // entity is not found, store it
-  std::string aName;
+  std::string aName, aKind;
   bool isDefaultName = false;
+  bool isSaveNotDumped = theSaveNotDumped;
   std::ostringstream aDefaultName;
   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theEntity);
   if (aFeature) {
     aName = aFeature->name();
-    const std::string& aKind = aFeature->getKind();
-    DocumentPtr aDoc = aFeature->document();
+    aKind = aFeature->getKind();
+  } else {
+    FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(theEntity);
+    if (aFolder) {
+      aName = aFolder->data()->name();
+      aKind = ModelAPI_Folder::ID();
+      isSaveNotDumped = false;
+    }
+  }
+
+  ObjectPtr anObject = std::dynamic_pointer_cast<ModelAPI_Object>(theEntity);
+  if (anObject) {
+    DocumentPtr aDoc = anObject->document();
     int& aNbFeatures = myFeatureCount[aDoc][aKind];
     aNbFeatures += 1;
 
@@ -163,7 +180,7 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity,
   }
 
   myNames[theEntity] = EntityName(aDefaultName.str(), aName, isDefaultName);
-  if (theSaveNotDumped)
+  if (isSaveNotDumped)
     myNotDumpedEntities.insert(theEntity);
 
   // store names of results
@@ -191,29 +208,16 @@ const std::string& ModelHighAPI_Dumper::parentName(const FeaturePtr& theEntity)
 void ModelHighAPI_Dumper::saveResultNames(const FeaturePtr& theFeature)
 {
   // Default name of the feature
-  const std::string& aKind = theFeature->getKind();
-  DocumentPtr aDoc = theFeature->document();
-  int aNbFeatures = myFeatureCount[aDoc][aKind];
-  std::ostringstream aNameStream;
-  aNameStream << aKind << "_" << aNbFeatures;
-  std::string aFeatureName = aNameStream.str();
+  bool isFeatureDefaultName = myNames[theFeature].myIsDefault;
 
   // Save only names of results which is not correspond to default feature name
   const std::list<ResultPtr>& aResults = theFeature->results();
   std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
-  for (int i = 1; aResIt != aResults.end(); ++aResIt, ++i) {
-    bool isUserDefined = true;
+  for (int i = 0; aResIt != aResults.end(); ++aResIt, ++i) {
+    std::string aDefaultName = ModelAPI_Tools::getDefaultName(*aResIt, i);
     std::string aResName = (*aResIt)->data()->name();
-    size_t anIndex = aResName.find(aFeatureName);
-    if (anIndex == 0) {
-      std::string aSuffix = aResName.substr(aFeatureName.length());
-      if (aSuffix.empty() && i == 1) // first result may not constain index in the name
-        isUserDefined = false;
-      else {
-        if (aSuffix[0] == '_' && std::stoi(aSuffix.substr(1)) == i)
-          isUserDefined = false;
-      }
-    }
+
+    bool isUserDefined = !(isFeatureDefaultName && aDefaultName == aResName);
 
     myNames[*aResIt] = EntityName(aResName,
         (isUserDefined ? aResName : std::string()), !isUserDefined);
@@ -223,22 +227,13 @@ void ModelHighAPI_Dumper::saveResultNames(const FeaturePtr& theFeature)
     if (aCompSolid) {
       int aNbSubs = aCompSolid->numberOfSubs();
       for (int j = 0; j < aNbSubs; ++j) {
-        isUserDefined = true;
         ResultPtr aSub = aCompSolid->subResult(j);
         std::string aSubName = aSub->data()->name();
-        size_t anIndex = aSubName.find(aResName);
-        if (anIndex == 0) {
-          std::string aSuffix = aSubName.substr(aResName.length());
-          if (aSuffix.empty() && aNbSubs == 1) // first result may not constain index in the name
-            isUserDefined = false;
-          else {
-            if (aSuffix[0] == '_' && std::stoi(aSuffix.substr(1)) == j + 1)
-              isUserDefined = false;
-          }
-        }
+        aDefaultName = ModelAPI_Tools::getDefaultName(aSub, j);
 
+        bool isUserDefinedSubName = isUserDefined || aDefaultName != aSubName;
         myNames[aSub] = EntityName(aSubName,
-            (isUserDefined ? aSubName : std::string()), !isUserDefined);
+            (isUserDefinedSubName ? aSubName : std::string()), !isUserDefinedSubName);
       }
     }
   }
@@ -259,18 +254,30 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theD
 bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc)
 {
   bool isOk = true;
-  std::list<FeaturePtr> aFeatures = theDoc->allFeatures();
-  std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
+  std::list<ObjectPtr> anObjects = theDoc->allObjects();
+  std::list<ObjectPtr>::const_iterator anObjIt = anObjects.begin();
   // firstly, dump all parameters
-  for (; aFeatIt != aFeatures.end(); ++ aFeatIt)
-    dumpParameter(*aFeatIt);
+  for (; anObjIt != anObjects.end(); ++ anObjIt) {
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIt);
+    if (aFeature)
+      dumpParameter(aFeature);
+  }
   // dump all other features
-  for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) {
-    CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
+  for (anObjIt = anObjects.begin(); anObjIt != anObjects.end(); ++anObjIt) {
+    CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*anObjIt);
     if (aCompFeat) // iteratively process composite features
       isOk = process(aCompFeat) && isOk;
-    else if (!isDumped(*aFeatIt)) // dump common feature
-      dumpFeature(*aFeatIt);
+    else if (!isDumped(EntityPtr(*anObjIt))) {
+      // dump folder
+      FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(*anObjIt);
+      if (aFolder)
+        dumpFolder(aFolder);
+      else {
+        FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIt);
+        if (aFeature) // dump common feature
+          dumpFeature(aFeature);
+      }
+    }
   }
   return isOk;
 }
@@ -281,7 +288,7 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_CompositeFeatur
   // increase composite features stack
   ++gCompositeStackDepth;
   // dump composite itself
-  if (!isDumped(theComposite) || isForce)
+  if (!isDumped(EntityPtr(theComposite)) || isForce)
     dumpFeature(FeaturePtr(theComposite), isForce);
 
   // sub-part is processed independently, because it provides separate document
@@ -331,7 +338,7 @@ bool ModelHighAPI_Dumper::processSubs(
   int aNbSubs = theComposite->numberOfSubs();
   for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
     FeaturePtr aFeature = theComposite->subFeature(anIndex);
-    if (isDumped(aFeature))
+    if (isDumped(EntityPtr(aFeature)))
       continue;
 
     isSubDumped = true;
@@ -356,9 +363,44 @@ bool ModelHighAPI_Dumper::processSubs(
   // dump "setName" for composite feature
   if (isDumpSetName)
     dumpEntitySetName();
+  // dump folders if any
+  dumpPostponed();
   return isOk;
 }
 
+void ModelHighAPI_Dumper::postpone(const EntityPtr& theEntity)
+{
+  // keep the name
+  name(theEntity, false);
+  myPostponed.push_back(theEntity);
+}
+
+void ModelHighAPI_Dumper::dumpPostponed()
+{
+  if (myDumpPostponedInProgress)
+    return;
+
+  myDumpPostponedInProgress = true;
+  // make a copy of postponed entities, because the list will be updated
+  // if some features are not able to be dumped
+  std::list<EntityPtr> aPostponedCopy = myPostponed;
+  myPostponed.clear();
+
+  // iterate over postponed entities and try to dump them
+  std::list<EntityPtr>::const_iterator anIt = aPostponedCopy.begin();
+  for (; anIt != aPostponedCopy.end(); ++anIt) {
+    FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(*anIt);
+    if (aFolder)
+      dumpFolder(aFolder);
+    else {
+      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
+      if (aFeature)
+        dumpFeature(aFeature);
+    }
+  }
+  myDumpPostponedInProgress = false;
+}
+
 void ModelHighAPI_Dumper::dumpSubFeatureNameAndColor(const std::string theSubFeatureGet,
                                                      const FeaturePtr& theSubFeature)
 {
@@ -474,6 +516,15 @@ void ModelHighAPI_Dumper::dumpEntitySetName()
         myDumpBuffer << ".setDeflection(" << aDeflectionAttr->value() << ")" << std::endl;
       }
     }
+    // set result transparency
+    if (!isDefaultTransparency(*aResIt)) {
+      AttributeDoublePtr aTransparencyAttr =
+        (*aResIt)->data()->real(ModelAPI_Result::TRANSPARENCY_ID());
+      if(aTransparencyAttr.get() && aTransparencyAttr->isInitialized()) {
+        *this << *aResIt;
+        myDumpBuffer << ".setTransparency(" << aTransparencyAttr->value() << ")" << std::endl;
+      }
+    }
   }
 
   myNames[aLastDumped.myEntity].myIsDumped = true;
@@ -484,7 +535,30 @@ bool ModelHighAPI_Dumper::isDumped(const EntityPtr& theEntity) const
 {
   EntityNameMap::const_iterator aFound = myNames.find(theEntity);
   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theEntity);
-  return aFound != myNames.end() || myFeaturesToSkip.find(aFeature) != myFeaturesToSkip.end();
+  return (aFound != myNames.end() && aFound->second.myIsDumped) ||
+         myFeaturesToSkip.find(aFeature) != myFeaturesToSkip.end();
+}
+
+bool ModelHighAPI_Dumper::isDumped(const AttributeRefAttrPtr& theRefAttr) const
+{
+  FeaturePtr aFeature;
+  if (theRefAttr->isObject())
+    aFeature = ModelAPI_Feature::feature(theRefAttr->object());
+  else
+    aFeature = ModelAPI_Feature::feature(theRefAttr->attr()->owner());
+  return aFeature && isDumped(EntityPtr(aFeature));
+}
+
+bool ModelHighAPI_Dumper::isDumped(const AttributeRefListPtr& theRefList) const
+{
+  std::list<ObjectPtr> aRefs = theRefList->list();
+  std::list<ObjectPtr>::iterator anIt = aRefs.begin();
+  for (; anIt != aRefs.end(); ++anIt) {
+    FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
+    if (aFeature && !isDumped(EntityPtr(aFeature)))
+      return false;
+  }
+  return true;
 }
 
 bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const
@@ -534,6 +608,15 @@ bool ModelHighAPI_Dumper::isDefaultDeflection(const ResultPtr& theResult) const
   return fabs(aCurrent - aDefault) < 1.e-12;
 }
 
+bool ModelHighAPI_Dumper::isDefaultTransparency(const ResultPtr& theResult) const
+{
+  AttributeDoublePtr anAttribute = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID());
+  if(!anAttribute || !anAttribute->isInitialized()) {
+    return true;
+  }
+  return fabs(anAttribute->value()) < 1.e-12;
+}
+
 ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char theChar)
 {
   myDumpBuffer << theChar;
@@ -662,6 +745,12 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
   return *this;
 }
 
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FolderPtr& theFolder)
+{
+  myDumpBuffer << name(theFolder);
+  return *this;
+}
+
 ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity)
 {
   myDumpBuffer << name(theEntity);
@@ -674,7 +763,7 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity
     std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
     for (; aResIt != aResults.end(); ++aResIt) {
       if (!myNames[*aResIt].myIsDefault || !isDefaultColor(*aResIt) ||
-          !isDefaultDeflection(*aResIt))
+          !isDefaultDeflection(*aResIt) || !isDefaultTransparency(*aResIt))
         aResultsWithNameOrColor.push_back(*aResIt);
 
       ResultCompSolidPtr aCompSolid =
@@ -684,7 +773,7 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity
         for (int i = 0; i < aNbSubs; ++i) {
           ResultPtr aCurRes = aCompSolid->subResult(i);
           if (!myNames[aCurRes].myIsDefault || !isDefaultColor(aCurRes) ||
-              !isDefaultDeflection(aCurRes))
+              !isDefaultDeflection(aCurRes) || !isDefaultTransparency(aCurRes))
             aResultsWithNameOrColor.push_back(aCurRes);
         }
       }
@@ -887,7 +976,9 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
     AttributeSelectionPtr anAttribute = theAttrSelList->value(anIndex);
     aShape = anAttribute->value();
     if(!aShape.get()) {
-      aShape = anAttribute->context()->shape();
+      ResultPtr aContext = anAttribute->context();
+      if (aContext.get())
+        aShape = aContext->shape();
     }
 
     if(!aShape.get()) {
@@ -946,7 +1037,7 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
           isCopy = aCopyAttr.get() && aCopyAttr->value();
         }
       }
-    } while (isCopy);
+    } while (isCopy && !theDumper.myEntitiesStack.empty());
   }
 
   // store all not-dumped entities first
@@ -963,18 +1054,19 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
     else {
       FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
       theDumper.dumpFeature(aFeature, true);
-      // dump all referred features for the "Copy"
+      // dump the Projection feature which produces this "Copy" entity
       AttributeBooleanPtr aCopyAttr = aFeature->boolean("Copy");
       if (aCopyAttr.get() && aCopyAttr->value())
       {
         const std::set<AttributePtr>& aRefs = aFeature->data()->refsToMe();
         std::set<AttributePtr>::iterator aRefIt = aRefs.begin();
         for (; aRefIt != aRefs.end(); ++aRefIt)
-        {
-          FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
-          if (anOwner && !theDumper.isDumped(anOwner))
-            theDumper.dumpFeature(anOwner, true);
-        }
+          if ((*aRefIt)->id() == "ProjectedFeature")
+          { // process projection only
+            FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
+            if (anOwner && !theDumper.isDumped(EntityPtr(anOwner)))
+              theDumper.dumpFeature(anOwner, true);
+          }
       }
     }
   }
@@ -986,5 +1078,8 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
   // then store currently dumped string
   theDumper.myFullDump << aBufCopy;
 
+  // now, store all postponed features
+  theDumper.dumpPostponed();
+
   return theDumper;
 }
index b9478e61c2c00321c44acf6730943678c62adde0..b287dd6ec3eb3d71748b88208e7925cdf04b5174 100644 (file)
@@ -54,12 +54,14 @@ class ModelAPI_CompositeFeature;
 class ModelAPI_Document;
 class ModelAPI_Entity;
 class ModelAPI_Feature;
+class ModelAPI_Folder;
 class ModelAPI_Object;
 class ModelAPI_Result;
 
 typedef std::shared_ptr<ModelAPI_Document> DocumentPtr;
 typedef std::shared_ptr<ModelAPI_Entity>   EntityPtr;
 typedef std::shared_ptr<ModelAPI_Feature>  FeaturePtr;
+typedef std::shared_ptr<ModelAPI_Folder>   FolderPtr;
 typedef std::shared_ptr<ModelAPI_Result>   ResultPtr;
 
 /**\class ModelHighAPI_Dumper
@@ -116,6 +118,13 @@ public:
   virtual void dumpParameter(const FeaturePtr& theFeature) = 0;
   /// Dump given feature
   virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0;
+  /// Dump folder
+  virtual void dumpFolder(const FolderPtr& theFolder) = 0;
+
+  /// Set feature postponed until all its dependencies are not dumped.
+  /// The name of the feature is stored anyway.
+  MODELHIGHAPI_EXPORT
+  void postpone(const EntityPtr& theEntity);
 
   /// Set a feature that should not be dumped anyway
   MODELHIGHAPI_EXPORT
@@ -203,6 +212,10 @@ public:
   MODELHIGHAPI_EXPORT
   ModelHighAPI_Dumper& operator<<(const FeaturePtr& theEntity);
 
+  /// Dump folder
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const FolderPtr& theFolder);
+
   /// Dump result
   MODELHIGHAPI_EXPORT
   ModelHighAPI_Dumper& operator<<(const ResultPtr& theResult);
@@ -244,6 +257,16 @@ public:
   /// clear list of not dumped entities
   MODELHIGHAPI_EXPORT void clearNotDumped();
 
+  /// Check the entity is already dumped
+  MODELHIGHAPI_EXPORT
+  bool isDumped(const EntityPtr& theEntity) const;
+  /// Check theRefAttr is already dumped
+  MODELHIGHAPI_EXPORT
+  bool isDumped(const std::shared_ptr<ModelAPI_AttributeRefAttr>& theRefAttr) const;
+  /// Check all objects in theRefList are already dumped
+  MODELHIGHAPI_EXPORT
+  bool isDumped(const std::shared_ptr<ModelAPI_AttributeRefList>& theRefList) const;
+
 protected:
   /// Dump "setName" command if last entity had user-defined name
   MODELHIGHAPI_EXPORT void dumpEntitySetName();
@@ -266,9 +289,6 @@ private:
   bool processSubs(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite,
                    bool theDumpModelDo = false);
 
-  /// Check the entity is already dumped
-  bool isDumped(const EntityPtr& theEntity) const;
-
   /// Stores names of results for the given feature
   void saveResultNames(const FeaturePtr& theFeature);
 
@@ -278,6 +298,12 @@ private:
   /// Check the result feature has default deflection
   bool isDefaultDeflection(const ResultPtr& theResult) const;
 
+  /// Check the result feature has default transparency
+  bool isDefaultTransparency(const ResultPtr& theResult) const;
+
+  /// Dump postponed entities
+  void dumpPostponed();
+
 private:
   struct EntityName {
     std::string myCurrentName; ///< default name of current feature
@@ -326,11 +352,15 @@ private:
   /// features which should not be dumped (like coincidence and tangency created by tangent arc)
   std::set<FeaturePtr> myFeaturesToSkip;
 
+  std::list<EntityPtr> myPostponed; ///< list of postponed entities (sketch constraints or folders)
+  bool myDumpPostponedInProgress; ///< processing postponed is in progress
+
 protected:
-   /// list of entities, used by other features but not dumped yet
+  /// list of entities, used by other features but not dumped yet
   std::set<EntityPtr> myNotDumpedEntities;
 
   friend class SketchAPI_Sketch;
+  friend class ModelHighAPI_Folder;
 };
 
 #endif
index 97f65b4777012ade15dbb4499fd0e116e2667b39..995cb344f47ea8d4cd6c9fef688a929d0ac63bec 100644 (file)
 #define PRECISION 6
 #define TOLERANCE (1.e-7)
 
-ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(FeaturePtr theFeature) {
-  storeData(theFeature->data(), myAttrs);
-  // iterate results to store
-  std::list<ResultPtr> allResults;
-  ModelAPI_Tools::allResults(theFeature, allResults);
-  std::list<ResultPtr>::iterator aRes = allResults.begin();
-  for(; aRes != allResults.end(); aRes++) {
-    std::map<std::string, std::string> aResDump;
-    storeData((*aRes)->data(), aResDump);
-    myRes.push_back(aResDump);
+ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(ObjectPtr theObject) {
+  storeData(theObject->data(), myAttrs);
+
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+  if (aFeature) {
+    // iterate results to store
+    std::list<ResultPtr> allResults;
+    ModelAPI_Tools::allResults(aFeature, allResults);
+    std::list<ResultPtr>::iterator aRes = allResults.begin();
+    for(; aRes != allResults.end(); aRes++) {
+      std::map<std::string, std::string> aResDump;
+      storeData((*aRes)->data(), aResDump);
+      myRes.push_back(aResDump);
+    }
   }
 }
 
-std::string ModelHighAPI_FeatureStore::compare(FeaturePtr theFeature) {
-  std::string anError = compareData(theFeature->data(), myAttrs);
+std::string ModelHighAPI_FeatureStore::compare(ObjectPtr theObject) {
+  std::string anError = compareData(theObject->data(), myAttrs);
   if (!anError.empty()) {
-    return "Features '" + theFeature->name() + "' differ:" + anError;
-  }
-  std::list<ResultPtr> allResults;
-  ModelAPI_Tools::allResults(theFeature, allResults);
-  std::list<ResultPtr>::iterator aRes = allResults.begin();
-  std::list<std::map<std::string, std::string> >::iterator aResIter = myRes.begin();
-  for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) {
-    anError = compareData((*aRes)->data(), *aResIter);
-    if (!anError.empty())
-      return "Results of feature '" + theFeature->name() + "' '" + (*aRes)->data()->name() +
-      "' differ:" + anError;
-  }
-  if (aRes != allResults.end()) {
-    return "Current model has more results '" + (*aRes)->data()->name() + "'";
+    return "Features '" + theObject->data()->name() + "' differ:" + anError;
   }
-  if (aResIter != myRes.end()) {
-    return "Original model had more results '" + (*aResIter)["__name__"] + "'";
+
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+  if (aFeature) {
+    std::list<ResultPtr> allResults;
+    ModelAPI_Tools::allResults(aFeature, allResults);
+    std::list<ResultPtr>::iterator aRes = allResults.begin();
+    std::list<std::map<std::string, std::string> >::iterator aResIter = myRes.begin();
+    for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) {
+      anError = compareData((*aRes)->data(), *aResIter);
+      if (!anError.empty())
+        return "Results of feature '" + aFeature->name() + "' '" + (*aRes)->data()->name() +
+        "' differ:" + anError;
+    }
+    if (aRes != allResults.end()) {
+      return "Current model has more results '" + (*aRes)->data()->name() + "'";
+    }
+    if (aResIter != myRes.end()) {
+      return "Original model had more results '" + (*aResIter)["__name__"] + "'";
+    }
   }
   return ""; // ok
 }
index 7970b179984db722d38c75effb7ce89f7edd3d6d..32bea8a3bcb5553f6bb49913ad5de3f190f82311 100644 (file)
 #include <string>
 #include <memory>
 
-class ModelAPI_Feature;
+class ModelAPI_Object;
 class ModelAPI_Data;
 class GeomAPI_Shape;
 class ModelAPI_Attribute;
 
-typedef std::shared_ptr<ModelAPI_Feature>  FeaturePtr;
-typedef std::shared_ptr<ModelAPI_Attribute>  AttributePtr;
+typedef std::shared_ptr<ModelAPI_Object>    ObjectPtr;
+typedef std::shared_ptr<ModelAPI_Attribute> AttributePtr;
 
 /**\class ModelHighAPI_FeatureStore
  * \ingroup CPPHighAPI
@@ -49,9 +49,9 @@ public:
   // unused constructor for the map container needs
   ModelHighAPI_FeatureStore() {}
   // constructor that initializes this object by feature to store
-  ModelHighAPI_FeatureStore(FeaturePtr theFeature);
+  ModelHighAPI_FeatureStore(ObjectPtr theObject);
   // compares the stored feature information with the given feature
-  std::string compare(FeaturePtr theFeature);
+  std::string compare(ObjectPtr theObject);
 
 private:
   /// stores the information about all attributes of data in map
diff --git a/src/ModelHighAPI/ModelHighAPI_Folder.cpp b/src/ModelHighAPI/ModelHighAPI_Folder.cpp
new file mode 100644 (file)
index 0000000..16c3b6d
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModelHighAPI_Folder.h"
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Reference.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_Document.h>
+
+//--------------------------------------------------------------------------------------
+
+ModelHighAPI_Folder::ModelHighAPI_Folder(const std::shared_ptr<ModelAPI_Folder> & theFolder)
+  : ModelHighAPI_Interface(FeaturePtr()),
+    myFolder(theFolder)
+{
+  initialize();
+}
+
+ModelHighAPI_Folder::~ModelHighAPI_Folder()
+{
+}
+
+bool ModelHighAPI_Folder::initialize()
+{
+  if (!myFolder) {
+    throwException(ID() + " exception: The folder is NULL.");
+    return false;
+  }
+
+  myFirstFeature = myFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  if (!myFirstFeature)
+    return false;
+  myAttrGetter[ModelAPI_Folder::FIRST_FEATURE_ID()] = "firstFeature";
+
+  myLastFeature = myFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+  if (!myLastFeature)
+    return false;
+  myAttrGetter[ModelAPI_Folder::LAST_FEATURE_ID()] = "lastFeature";
+
+  return true;
+}
+
+void ModelHighAPI_Folder::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  const std::string& aDocName = theDumper.name(myFolder->document());
+
+  AttributeReferencePtr aStartRef = myFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  AttributeReferencePtr aEndRef   = myFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+
+  // Dump folder if it is empty or when its features have been already dumped.
+  // Otherwise, store the folder postponed.
+  if (!aEndRef->value())
+    theDumper << myFolder << " = model.addFolder(" << aDocName << ")" << std::endl;
+  else if (theDumper.isDumped(EntityPtr(aEndRef->value())))
+    theDumper << myFolder << " = model.addFolder(" << aDocName << ", "
+              << aStartRef << ", " << aEndRef << ")" << std::endl;
+  else
+    theDumper.postpone(myFolder);
+}
+
+//--------------------------------------------------------------------------------------
+
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc)
+{
+  std::shared_ptr<ModelAPI_Folder> aFolder = theDoc->addFolder();
+  return std::shared_ptr<ModelHighAPI_Folder>(new ModelHighAPI_Folder(aFolder));
+}
+
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc,
+                                               const ModelHighAPI_Reference& theFirstFeature,
+                                               const ModelHighAPI_Reference& theLastFeature)
+{
+  std::shared_ptr<ModelAPI_Folder> aFolder = theDoc->addFolder(theFirstFeature.feature());
+
+  AttributeReferencePtr aFirstFeatAttr = aFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  fillAttribute(theFirstFeature.feature(), aFirstFeatAttr);
+
+  AttributeReferencePtr aLastFeatAttr = aFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+  fillAttribute(theLastFeature.feature(), aLastFeatAttr);
+
+  return std::shared_ptr<ModelHighAPI_Folder>(new ModelHighAPI_Folder(aFolder));
+}
diff --git a/src/ModelHighAPI/ModelHighAPI_Folder.h b/src/ModelHighAPI/ModelHighAPI_Folder.h
new file mode 100644 (file)
index 0000000..8128df0
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_
+#define SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_
+
+//--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Interface.h>
+
+#include <ModelAPI_Folder.h>
+
+#include <memory>
+//--------------------------------------------------------------------------------------
+class ModelAPI_AttributeReference;
+class ModelAPI_Document;
+class ModelHighAPI_Reference;
+//--------------------------------------------------------------------------------------
+/**\class ModelHighAPI_Folder
+ * \ingroup CPPHighAPI
+ * \brief Class for filling ModelAPI_Folder
+ */
+class ModelHighAPI_Folder : public ModelHighAPI_Interface
+{
+public:
+  /// Constructor for a folder
+  MODELHIGHAPI_EXPORT
+  explicit ModelHighAPI_Folder(const std::shared_ptr<ModelAPI_Folder>& theFolder);
+  /// Destructor
+  MODELHIGHAPI_EXPORT virtual ~ModelHighAPI_Folder();
+
+  static std::string ID() { return ModelAPI_Folder::ID(); }
+  virtual std::string getID() { return ID(); }
+
+  /// First feature reference
+  std::shared_ptr<ModelAPI_AttributeReference> firstFeature() const
+  { return myFirstFeature; }
+
+  /// Last feature reference
+  std::shared_ptr<ModelAPI_AttributeReference> lastFeature() const
+  { return myLastFeature; }
+
+  /// Dump wrapped feature
+  MODELHIGHAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+protected:
+  bool initialize();
+
+private:
+  std::shared_ptr<ModelAPI_Folder> myFolder;
+
+  std::shared_ptr<ModelAPI_AttributeReference> myFirstFeature;
+  std::shared_ptr<ModelAPI_AttributeReference> myLastFeature;
+};
+
+//--------------------------------------------------------------------------------------
+/**\ingroup CPPHighAPI
+ * \brief Create empty Folder feature
+ */
+MODELHIGHAPI_EXPORT
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc);
+
+/**\ingroup CPPHighAPI
+ * \brief Create Folder feature
+ */
+MODELHIGHAPI_EXPORT
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc,
+                                               const ModelHighAPI_Reference& theFirstFeature,
+                                               const ModelHighAPI_Reference& theLastFeature);
+//--------------------------------------------------------------------------------------
+#endif /* SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_ */
index 0a691d2be2acf168ed55d86bb77cdd42fa18b5e0..d5b6332a3edac800c39907303082f5b461df9548 100644 (file)
@@ -91,6 +91,11 @@ void ModelHighAPI_Interface::setName(const std::string& theName)
   feature()->data()->setName(theName);
 }
 
+std::string ModelHighAPI_Interface::name() const
+{
+  return feature()->data()->name();
+}
+
 ModelHighAPI_Selection ModelHighAPI_Interface::result() const
 {
   const_cast<ModelHighAPI_Interface*>(this)->execute();
index 054dd1c36ec8cd655b285d0e14ffd664ca84c519..729d84a23997ae5bdb9276ba99bb39ffafe03973 100644 (file)
@@ -71,6 +71,10 @@ public:
   MODELHIGHAPI_EXPORT
   void setName(const std::string& theName);
 
+  /// Shortcut for feature()->data()->name()
+  MODELHIGHAPI_EXPORT
+  std::string name() const;
+
   /// Return firts object of the feature
   MODELHIGHAPI_EXPORT
   virtual ModelHighAPI_Selection result() const;
index 60017e8cc972e35af3e319f019f6d01744058b4b..ec6201600f530f5f3ef4a4c4071115b15af0e8cf 100644 (file)
@@ -131,6 +131,16 @@ void ModelHighAPI_Selection::setName(const std::string& theName)
   }
 }
 
+std::string ModelHighAPI_Selection::name() const
+{
+  if (myVariantType == VT_ResultSubShapePair) {
+    std::shared_ptr<ModelAPI_Result> aResult = myResultSubShapePair.first;
+    if (aResult.get())
+      return aResult->data()->name();
+  }
+  return std::string();
+}
+
 void ModelHighAPI_Selection::setColor(int theRed, int theGreen, int theBlue)
 {
   if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get())
@@ -155,6 +165,17 @@ void ModelHighAPI_Selection::setDeflection(double theValue)
   aDeflectionAttr->setValue(theValue);
 }
 
+void ModelHighAPI_Selection::setTransparency(double theValue)
+{
+  if (myVariantType != VT_ResultSubShapePair)
+    return;
+
+  AttributeDoublePtr aTransparencyAttr =
+    myResultSubShapePair.first->data()->real(ModelAPI_Result::TRANSPARENCY_ID());
+
+  aTransparencyAttr->setValue(theValue);
+}
+
 int ModelHighAPI_Selection::numberOfSubs() const
 {
   if (myVariantType != VT_ResultSubShapePair)
index c89b414fb8fe56c33cf750c97c596bbba6806c12..21da1cdfe188790a4c1f30c6876c21c378f9472d 100644 (file)
@@ -96,6 +96,10 @@ public:
   MODELHIGHAPI_EXPORT
   void setName(const std::string& theName);
 
+  /// Shortcut for result()->data()->name()
+  MODELHIGHAPI_EXPORT
+  std::string name() const;
+
   /// Change result's color
   MODELHIGHAPI_EXPORT
   void setColor(int theRed, int theGreen, int theBlue);
@@ -104,6 +108,10 @@ public:
   MODELHIGHAPI_EXPORT
   void setDeflection(double theValue);
 
+  /// Change result's transparency
+  MODELHIGHAPI_EXPORT
+  void setTransparency(double theValue);
+
   /// Returns the number of sub-elements.
   MODELHIGHAPI_EXPORT
   int numberOfSubs() const;
index d03130b59b2f0b01c2b934f22457d97eb10ea545..b8415681e9ae09efc9b040f3be52023a74e8b32c 100644 (file)
@@ -338,47 +338,54 @@ std::string storeFeatures(const std::string& theDocName, DocumentPtr theDoc,
      }
   }
   // store the model features information: iterate all features
-  int aFeaturesCount = 0; // stores the number of compared features for this document to compate
+  int anObjectsCount = 0; // stores the number of compared features for this document to compate
   std::set<std::string> aProcessed; // processed features names (that are in the current document)
-  std::list<FeaturePtr> allFeatures = theDoc->allFeatures();
-  std::list<FeaturePtr>::iterator allIter = allFeatures.begin();
-  for(; allIter != allFeatures.end(); allIter++) {
-    FeaturePtr aFeat = *allIter;
+
+  // process all objects (features and folders)
+  std::list<ObjectPtr> allObjects = theDoc->allObjects();
+  std::list<ObjectPtr>::iterator allIter = allObjects.begin();
+  for(; allIter != allObjects.end(); allIter++) {
+    ObjectPtr anObject = *allIter;
     if (theCompare) {
       std::map<std::string, ModelHighAPI_FeatureStore>::iterator
-        aFeatFind = aDocFind->second.find(aFeat->name());
-      if (aFeatFind == aDocFind->second.end()) {
-        return "Document '" + theDocName + "' feature '" + aFeat->name() + "' not found";
+        anObjFind = aDocFind->second.find(anObject->data()->name());
+      if (anObjFind == aDocFind->second.end()) {
+        return "Document '" + theDocName + "' feature '" + anObject->data()->name() + "' not found";
       }
-      std::string anError = aFeatFind->second.compare(aFeat);
+      std::string anError = anObjFind->second.compare(anObject);
       if (!anError.empty()) {
         anError = "Document " + theDocName + " " + anError;
         return anError;
       }
-      aFeaturesCount++;
-      aProcessed.insert(aFeat->name());
+      anObjectsCount++;
+      aProcessed.insert(anObject->data()->name());
     } else {
-      theStore[theDocName][aFeat->name()] = ModelHighAPI_FeatureStore(aFeat);
+      theStore[theDocName][anObject->data()->name()] = ModelHighAPI_FeatureStore(anObject);
     }
-    // iterate all results of this feature
-    std::list<ResultPtr> allResults;
-    ModelAPI_Tools::allResults(aFeat, allResults);
-    std::list<ResultPtr>::iterator aRes = allResults.begin();
-    for(; aRes != allResults.end(); aRes++) {
-      // recoursively store features of sub-documents
-      if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) {
-        DocumentPtr aDoc = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes)->partDoc();
-        if (aDoc.get()) {
-          std::string anError = storeFeatures((*aRes)->data()->name(), aDoc, theStore, theCompare);
-          if (!anError.empty())
-            return anError;
+
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+    if (aFeature) {
+      // iterate all results of this feature
+      std::list<ResultPtr> allResults;
+      ModelAPI_Tools::allResults(aFeature, allResults);
+      std::list<ResultPtr>::iterator aRes = allResults.begin();
+      for(; aRes != allResults.end(); aRes++) {
+        // recoursively store features of sub-documents
+        if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) {
+          DocumentPtr aDoc = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes)->partDoc();
+          if (aDoc.get()) {
+            std::string anError =
+                storeFeatures((*aRes)->data()->name(), aDoc, theStore, theCompare);
+            if (!anError.empty())
+              return anError;
+          }
         }
       }
     }
   }
   // checks the number of compared features
   if (theCompare) {
-    if (aDocFind->second.size() != aFeaturesCount) {
+    if (aDocFind->second.size() != anObjectsCount) {
       // search for disappeared feature
       std::string aLostName;
       std::map<std::string, ModelHighAPI_FeatureStore>::iterator aLostIter;
index 4a0bf71da8fb2f312f8107b8bcea6aeb054911fb..fb7b26c8fda35d6e85f860929692cdbf2cd54cf9 100644 (file)
@@ -28,6 +28,7 @@
   #include "ModelHighAPI.h"
   #include "ModelHighAPI_Double.h"
   #include "ModelHighAPI_Dumper.h"
+  #include "ModelHighAPI_Folder.h"
   #include "ModelHighAPI_Integer.h"
   #include "ModelHighAPI_Interface.h"
   #include "ModelHighAPI_Macro.h"
index 48070d0ad2c2ea75c2af87d0cd1c717286d4bcca..cb40f7222e31aa572d7f5efde477570c881dae8a 100644 (file)
@@ -32,6 +32,7 @@ ADD_DEFINITIONS(${QT_DEFINITIONS})
 SET(PROJECT_HEADERS
   ModuleBase.h
   ModuleBase_ActionInfo.h
+  ModuleBase_ActionType.h
   ModuleBase_Definitions.h
   ModuleBase_DoubleSpinBox.h
   ModuleBase_Events.h
diff --git a/src/ModuleBase/ModuleBase_ActionType.h b/src/ModuleBase/ModuleBase_ActionType.h
new file mode 100644 (file)
index 0000000..864c5e6
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ActionType_H_
+#define ModuleBase_ActionType_H_
+
+#include <ModuleBase.h>
+
+/*!
+ * Structure to describe widget processed types of actions.
+ */
+enum MODULEBASE_EXPORT ModuleBase_ActionType
+{
+  ActionEnter,
+  ActionEscape,
+  ActionDelete,
+  ActionUndo,
+  ActionRedo
+};
+
+#endif /* ModuleBase_ActionType_H_ */
index 2a085250e1fe03947b6a83769e476aa9195e1bb9..fbe2646a072ac27f1027cf3ae15bc871fe83c35c 100644 (file)
@@ -283,7 +283,6 @@ void ModuleBase_IModule::onFeatureTriggered()
       launchModal(aCmdId);
     } else {
       launchOperation(aCmdId, false);
-      emit operationLaunched();
     }
   }
 }
index 995e21fe825269abddeb9dc26dd58b3356d839d3..927cfdc26906686bf0d2782e51384ba8639c06b8 100755 (executable)
@@ -366,9 +366,6 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
                             std::string& theDescription);
 
 signals:
-  /// Signal which is emitted when operation is launched
-  void operationLaunched();
-
   /// Segnal emitted when an operation is resumed
   /// \param theOp a resumed operation
   void resumed(ModuleBase_Operation* theOp);
index 067ef6ea5ca5662a15ee84a353cc02d8cc47e102..a691efd3242079f656ea640db9d3df7c32e8a379 100644 (file)
@@ -62,10 +62,9 @@ QPixmap ModuleBase_IconFactory::loadPixmap(const QString& theValue)
   QPixmap aPixmap(theValue);
 
   if (aPixmap.isNull()) {
-    std::string aPluginPath = Config_XMLReader::pluginConfigFile();
-    QString aPath = QString::fromStdString(aPluginPath) + QDir::separator() + theValue;
-    if (QFile::exists(aPath))
-      aPixmap = QPixmap(aPath);
+    std::string aPath = Config_XMLReader::findConfigFile(theValue.toStdString());
+    if (!aPath.empty())
+      aPixmap = QPixmap(QString::fromStdString(aPath));
   }
   return aPixmap;
 }
@@ -75,10 +74,9 @@ QImage ModuleBase_IconFactory::loadImage(const QString& theValue)
   QImage anImage(theValue);
 
   if (anImage.isNull()) {
-    std::string aPluginPath = Config_XMLReader::pluginConfigFile();
-    QString aPath = QString::fromStdString(aPluginPath) + QDir::separator() + theValue;
-    if (QFile::exists(aPath))
-      anImage = QImage(aPath);
+    std::string aPath = Config_XMLReader::findConfigFile(theValue.toStdString());
+    if (!aPath.empty())
+      anImage = QImage(QString::fromStdString(aPath));
   }
   return anImage;
 }
index 3fa0b14d0930a8df3d649c640d6a5f51b996feef..ff4f88a9dc1b875f95a3f3ce23a1505da7afa2b2 100644 (file)
@@ -406,6 +406,37 @@ void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)
   }
 }
 
+bool ModuleBase_ModelWidget::canProcessAction(ModuleBase_ActionType theActionType,
+                                              bool& isActionEnabled)
+{
+  isActionEnabled = false;
+  switch (theActionType) {
+    case ActionEnter: return false;
+    case ActionEscape: return false;
+    case ActionDelete: return true;
+    case ActionUndo:
+    case ActionRedo:
+    default:
+      return false;
+  }
+}
+
+bool ModuleBase_ModelWidget::processAction(ModuleBase_ActionType theActionType)
+{
+  switch (theActionType) {
+    case ActionEnter:
+      return processEnter();
+    case ActionEscape:
+      return processEscape();
+    case ActionDelete:
+      return processDelete();
+    case ActionUndo:
+    case ActionRedo:
+    default:
+      return false;
+  }
+}
+
 bool ModuleBase_ModelWidget::processEnter()
 {
   return false;
index fbd0d6e11ce1d20dd76ad564e75f05244d4382d1..4882e290317761c872cc6d83df7e62b6eccece0b 100644 (file)
@@ -22,6 +22,7 @@
 #define MODULEBASE_MODELWIDGET_H
 
 #include <ModuleBase.h>
+#include <ModuleBase_ActionType.h>
 #include <ModuleBase_OperationFeature.h>
 #include <ModelAPI_Feature.h>
 
@@ -240,14 +241,13 @@ Q_OBJECT
   /// \return Current Editing mode
   bool isEditingMode() const { return myIsEditing; }
 
-  /// Returns true if the event is processed. The default implementation is empty, returns false.
-  virtual bool processEnter();
-
-  /// Returns true if the event is processed. The default implementation is empty, returns false.
-  virtual bool processEscape();
+  /// Returns true if the action can be processed. By default it is empty and returns false.
+  /// \param theActionType an action type
+  /// \param isActionEnabled if true, the enable state of the action
+  virtual bool canProcessAction(ModuleBase_ActionType theActionType, bool& isActionEnabled);
 
   /// Returns true if the event is processed. The default implementation is empty, returns false.
-  virtual bool processDelete();
+  virtual bool processAction(ModuleBase_ActionType theActionType);
 
   /// Sends Update and Redisplay for the given object
   /// \param theObj is updating object
@@ -343,6 +343,15 @@ protected:
   /// The method called when widget is activated
   virtual void activateCustom() {};
 
+    //// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processEnter();
+
+  //// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processEscape();
+
+  //// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processDelete();
+
 protected slots:
   /// Processing of values changed in model widget by store the current value to the feature
   void onWidgetValuesChanged();
index 55abd049722066ca4ce7d5f461121ced65a16f69..27197a7edeb54d3c5474c4a9d0fb1960d54eff74 100644 (file)
@@ -72,8 +72,12 @@ void ModuleBase_ToolBox::addItem(QWidget* thePage, const QString& theName, const
   QToolButton* aButton = new QToolButton(myButtonsFrame);
   aButton->setFocusPolicy(Qt::StrongFocus);
   aButton->setCheckable(true);
-  aButton->setIcon(theIcon);
-  aButton->setIconSize(theIcon.size());
+  if (theIcon.isNull())
+    aButton->setText(theName);
+  else {
+    aButton->setIcon(theIcon);
+    aButton->setIconSize(theIcon.size());
+  }
   aButton->setToolTip(theName);
   aButton->setObjectName(theName);
   myButtonsGroup->addButton(aButton, anOldCount);
index 108ad1681f51bbbddf5d8a659bcbe9718c1ef3d7..32d61570b082efd575f8e1afc995cec6c33cb87d 100755 (executable)
@@ -46,6 +46,7 @@
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Events.h>
+#include <ModelAPI_Folder.h>
 
 #include <ModelGeomAlgo_Point2D.h>
 
@@ -372,20 +373,24 @@ int shapeType(const QString& theType)
 }
 
 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
-                  bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory)
+                  bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
+                  bool& hasFolder)
 {
   hasResult = false;
   hasFeature = false;
   hasParameter = false;
   hasCompositeOwner = false;
   hasResultInHistory = false;
+  hasFolder = false;
   foreach(ObjectPtr aObj, theObjects) {
     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+    FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
     ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
 
     hasResult |= (aResult.get() != NULL);
     hasFeature |= (aFeature.get() != NULL);
+    hasFolder |= (aFolder.get() != NULL);
     hasParameter |= (aConstruction.get() != NULL);
     if (hasFeature)
       hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
@@ -395,7 +400,7 @@ void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFe
       hasResultInHistory = aFeature.get() && aFeature->isInHistory();
     }
 
-    if (hasFeature && hasResult  && hasParameter && hasCompositeOwner)
+    if (hasFeature && hasResult  && hasParameter && hasCompositeOwner && hasFeature)
       break;
   }
 }
@@ -1039,10 +1044,26 @@ void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& t
     if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
       aFeature = ModelAPI_Feature::feature(anObject);
     }
-    theFeatures.insert(aFeature);
+    if (aFeature.get())
+      theFeatures.insert(aFeature);
+  }
+}
+
+//**************************************************************
+void convertToFolders(const QObjectPtrList& theObjects,
+                                         std::set<FolderPtr>& theFolders)
+{
+  QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
+  for(; anIt != aLast; anIt++) {
+    ObjectPtr anObject = *anIt;
+    FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
+    if (aFeature.get())
+      theFolders.insert(aFeature);
   }
 }
 
+
+//**************************************************************
 QString translate(const Events_InfoMessage& theMessage)
 {
   QString aMessage;
@@ -1103,6 +1124,9 @@ void setPointBallHighlighting(AIS_Shape* theAIS)
 
   Handle(Graphic3d_AspectMarker3d) anAspect;
   Handle(Prs3d_Drawer) aDrawer = theAIS->HilightAttributes();
+#ifdef USE_OCCT_720
+  // to do: implement ball highlighting, in 7.2.0 this drawer is NULL
+#else
   if(aDrawer->HasOwnPointAspect()) {
     Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
     if(aPixMap->IsEmpty()) {
@@ -1120,6 +1144,7 @@ void setPointBallHighlighting(AIS_Shape* theAIS)
     aDrawer->SetPointAspect(aPntAspect);
     theAIS->SetHilightAttributes(aDrawer);
   }
+#endif
 }
 
 } // namespace ModuleBase_Tools
index 0c46f52dcea7bd3ea01ae2ca95829d1571146226..8a179c25adf1bc17ca09c83cd33f9a8590b34041 100755 (executable)
@@ -26,6 +26,7 @@
 
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
 
 #include <TopAbs_ShapeEnum.hxx>
 #include <TopoDS_Shape.hxx>
@@ -176,9 +177,10 @@ MODULEBASE_EXPORT bool isSubResult(ObjectPtr theObject);
 /// \param hasParameter will be set to true if list contains Parameter objects
 /// \param hasCompositeOwner will be set to true if list contains Sub-Feature objects
 /// \param hasResultInHistory will be set to true if one of result is in history
+/// \param hasFolder will be set to true if one of folder is in the list
 MODULEBASE_EXPORT void checkObjects(const QObjectPtrList& theObjects, bool& hasResult,
                            bool& hasFeature, bool& hasParameter, bool& hasCompositeOwner,
-                           bool& hasResultInHistory);
+                           bool& hasResultInHistory, bool& hasFolder);
 
 /// Sets the default coeffient into the driver calculated accordingly the shape type.
 /// It provides 1.e-4 for results of construction type
@@ -331,6 +333,13 @@ void MODULEBASE_EXPORT convertToFeatures(const QObjectPtrList& theObjects,
                                          std::set<FeaturePtr>& theFeatures);
 
 
+/// Converts a list of objects to set of folders.
+/// \param theObjects a list of objects
+/// \param theFeatures an out conteiner of features
+void MODULEBASE_EXPORT convertToFolders(const QObjectPtrList& theObjects,
+                                         std::set<FolderPtr>& theFolders);
+
+
 /// Returns translation from the given data.
 /// If translation is not exists then it returns a string
 /// from the info data without translation
index 0686c1d7bffa6950acd0d5deba83faefd3b7d764..3f7b3a3ad5fc853519475e166c67e8d0d0580151 100644 (file)
@@ -156,6 +156,12 @@ Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(
             const Prs3d_DatumParts& aPart = aTrOwner->DatumPart();
             if (aPart >= Prs3d_DP_XAxis && aPart <= Prs3d_DP_ZAxis)
             {
+#ifdef USE_OCCT_720
+              gp_Ax2 anAxis = aTrihedron->Component()->Ax2();
+              gp_Dir aDir = anAxis.XDirection();
+              gp_Lin aLine(aTrihedron->Component()->Location(), aDir);
+              return aPlane.Contains(aLine, Precision::Confusion(), Precision::Angular());
+#else
               Handle(Prs3d_Drawer) aDrawer = aTrihedron->Attributes();
               Handle(Prs3d_DatumAspect) aDatumAspect = aDrawer->DatumAspect();
               Handle(Graphic3d_ArrayOfPrimitives) aPrimitives =
@@ -167,6 +173,7 @@ Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(
               gp_Pnt aPnt2(aX2, anY2, aZ2);
               gp_Lin aLine(aPnt1, gp_Dir(gp_Vec(aPnt1, aPnt2)));
               return aPlane.Contains(aLine, Precision::Confusion(), Precision::Angular());
+#endif
             }
           }
         }
index 1bc6987e13ca85abce3a4453421d18871d0226da..7ef0cfb540f37b5c824e455c2b53eafe3da49fef 100644 (file)
 #include "ModuleBase_IconFactory.h"
 
 #include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeStringArray.h>
 #include <ModelAPI_Data.h>
 #include <Config_WidgetAPI.h>
+#include <Config_PropManager.h>
 
 #include <QWidget>
 #include <QLayout>
@@ -35,7 +37,6 @@
 #include <QRadioButton>
 #include <QToolButton>
 
-
 ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
                                                  const Config_WidgetAPI* theData)
 : ModuleBase_ModelWidget(theParent, theData), myCombo(0), myButtons(0)
@@ -51,7 +52,11 @@ ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
   foreach(QString aType, QString(aTypes.c_str()).split(' ')) {
     aList.append(translate(aType.toStdString()));
   }
-
+  if (aTypes.empty()) {
+    myStringListAttribute = theData->getProperty("string_list_attribute");
+    if (!myStringListAttribute.empty())
+      aList.clear();
+  }
   if (theData->getBooleanAttribute("use_in_title", false))
     myButtonTitles = aList;
 
@@ -150,6 +155,14 @@ bool ModuleBase_WidgetChoice::restoreValueCustom()
   if (aIntAttr->value() != -1) {
     if (myCombo) {
       bool isBlocked = myCombo->blockSignals(true);
+      if (myCombo->count() == 0 && !myStringListAttribute.empty()) {
+        AttributeStringArrayPtr aStrAttr = aData->stringArray(myStringListAttribute);
+        if (aStrAttr) {
+          for (int i = 0; i < aStrAttr->size(); i++) {
+            myCombo->insertItem(i, aStrAttr->value(i).c_str());
+          }
+        }
+      }
       myCombo->setCurrentIndex(aIntAttr->value());
       myCombo->blockSignals(isBlocked);
     } else {
index cd0fa9521b1848d7b68b96f0164811d9bd31c8a9..a6ac35cfcf3eb5aa6205a21de6791d44ff202342 100644 (file)
@@ -100,6 +100,7 @@ private:
 
   // XML definition of titles
   QStringList myButtonTitles;
+  std::string myStringListAttribute;
 };
 
 #endif
index 07a22802d59fbcf19f28c364d2aa46f78df5326d..347f3ca99700be165d63dccdbc6ddda2602ae558 100644 (file)
@@ -59,15 +59,15 @@ Q_OBJECT
   /// \return a control list
   virtual QList<QWidget*> getControls() const;
 
-  /// Returns true if the event is processed.
-  virtual bool processEnter();
-
  public slots:
  // Delayed value chnged: when user starts typing something,
  // it gives him a 0,5 second to finish typing, when sends valueChnaged() signal
 //  void onValueChanged();
 
 protected:
+  /// Returns true if the event is processed.
+  virtual bool processEnter();
+
   /// Saves the internal parameters to the given feature
   /// \return True in success
   virtual bool storeValueCustom();
index 757165744253c45657caa6f25a7e2b52ccdc92ba..4c485d19974c8543045c5be5a6c38d22b5fecb19 100644 (file)
@@ -68,6 +68,7 @@ Q_OBJECT
   /// \param theY the Y coordinate
   void setCursorPosition(const int theX, const int theY);
 
+protected:
   /// Returns true if the event is processed.
   virtual bool processEnter();
 
index 8099dd0262e0a26ea640cab0225b6503ca825de4..310021975840233f1702942a2edbd228b0aeeb44 100644 (file)
@@ -123,14 +123,14 @@ class MODULEBASE_EXPORT ModuleBase_WidgetExprEditor : public ModuleBase_ModelWid
   /// Redefinition of virtual method
   virtual QList<QWidget*> getControls() const;
 
-  /// Returns true if the event is processed.
-  virtual bool processEnter();
-
 protected slots:
   /// A slot for processing text changed event
   void onTextChanged();
 
 protected:
+  /// Returns true if the event is processed.
+  virtual bool processEnter();
+
   /// Do not initialize value on the widget activation
   virtual void initializeValueByActivate();
 
index 57db592c3cf6fe3cf48906ac00119df2a133bcd2..ca7ee5de1a7f29e16f59b81e3aa547fa9183d16e 100644 (file)
@@ -26,6 +26,7 @@
 #include <ModuleBase_WidgetFileSelector.h>
 #include <ModuleBase_Tools.h>
 
+#include <Config_PropManager.h>
 #include <Config_WidgetAPI.h>
 
 #include <QFileDialog>
 
 ModuleBase_WidgetFileSelector::ModuleBase_WidgetFileSelector(QWidget* theParent,
                                                              const Config_WidgetAPI* theData)
-: ModuleBase_ModelWidget(theParent, theData)
+: ModuleBase_ModelWidget(theParent, theData), myFileDialog(0)
 {
   myTitle = translate(theData->getProperty("title"));
   myType = (theData->getProperty("type") == "save") ? WFS_SAVE : WFS_OPEN;
   myDefaultPath = QString::fromStdString(theData->getProperty("path"));
 
+  if (myDefaultPath.isEmpty())
+    myDefaultPath = Config_PropManager::string("Plugins", "import_initial_path").c_str();
+
   QGridLayout* aMainLay = new QGridLayout(this);
   ModuleBase_Tools::adjustMargins(aMainLay);
   QLabel* aTitleLabel = new QLabel(myTitle, this);
@@ -119,6 +123,16 @@ bool ModuleBase_WidgetFileSelector::isCurrentPathValid()
   return aFile.exists();
 }
 
+bool ModuleBase_WidgetFileSelector::processEscape()
+{
+  if (myFileDialog) {
+    myFileDialog->reject();
+    return true;
+  }
+  return ModuleBase_ModelWidget::processEscape();
+}
+
+
 void ModuleBase_WidgetFileSelector::onPathSelectionBtn()
 {
   QString aDefaultPath = myPathField->text().isEmpty()
@@ -127,17 +141,26 @@ void ModuleBase_WidgetFileSelector::onPathSelectionBtn()
   QString aFilter = filterString();
   // use Option prohibited native dialog using to have both lower/upper extensions of files
   // satisfied to dialog filter on Linux(Calibre) Issue #2055
-  QString aFileName = (myType == WFS_SAVE)
-      ? QFileDialog::getSaveFileName(this, myTitle, aDefaultPath, aFilter, &mySelectedFilter,
-                                     QFileDialog::DontUseNativeDialog)
-      : QFileDialog::getOpenFileName(this, myTitle, aDefaultPath, aFilter, &mySelectedFilter,
-                                     QFileDialog::DontUseNativeDialog);
-  if (!aFileName.isEmpty()) {
-    if (myType == WFS_SAVE)
-      aFileName = applyExtension(aFileName, mySelectedFilter);
-    myPathField->setText(aFileName);
-    emit focusOutWidget(this);
+  myFileDialog = new QFileDialog(this, myTitle, aDefaultPath, aFilter);
+  myFileDialog->setNameFilter(aFilter);
+  myFileDialog->setOptions(QFileDialog::DontUseNativeDialog);
+  myFileDialog->setAcceptMode(myType == WFS_SAVE ? QFileDialog::AcceptSave
+                                                 : QFileDialog::AcceptOpen);
+  if (myFileDialog->exec() == QDialog::Accepted)
+  {
+    mySelectedFilter = myFileDialog->selectedNameFilter();
+    QStringList aFileNames = myFileDialog->selectedFiles();
+    if (!aFileNames.empty()) {
+      QString aFileName = aFileNames.first();
+      if (!aFileName.isEmpty()) {
+        if (myType == WFS_SAVE)
+          aFileName = applyExtension(aFileName, mySelectedFilter);
+        myPathField->setText(aFileName);
+        emit focusOutWidget(this);
+      }
+    }
   }
+  myFileDialog = 0;
 }
 
 void ModuleBase_WidgetFileSelector::onPathChanged()
index 8cfbe91ff2769acf45e2a47dadfda0c8805a7936..e337845e94de3c38ebdb99b38892066cd7b4e59a 100644 (file)
@@ -28,8 +28,9 @@
 #include <QString>
 #include <QStringList>
 
-class QWidget;
+class QFileDialog;
 class QLineEdit;
+class QWidget;
 
 /**
 * \ingroup GUI
@@ -65,7 +66,7 @@ class MODULEBASE_EXPORT ModuleBase_WidgetFileSelector : public ModuleBase_ModelW
   /// exists and has supported format
   bool isCurrentPathValid();
 
- public slots:
+public slots:
    /// Processing of path selection button press
   void onPathSelectionBtn();
 
@@ -73,6 +74,9 @@ class MODULEBASE_EXPORT ModuleBase_WidgetFileSelector : public ModuleBase_ModelW
   void onPathChanged();
 
 protected:
+  /// Reject the current editor dialog if it is shown and returns true.
+  virtual bool processEscape();
+
   /// Saves the internal parameters to the given feature
   /// \return True in success
   virtual bool storeValueCustom();
@@ -104,6 +108,7 @@ protected:
 protected:
    /// A control for path input
   QLineEdit* myPathField;
+  QFileDialog* myFileDialog; ///< started dialog
 
   /// A title of open file dialog box
   QString myTitle;
index 4a13ed44254e28b69a56c588e715d916694203f6..0394458c98641ae2b6f823607523651330216679 100644 (file)
@@ -56,10 +56,10 @@ Q_OBJECT
   /// \return a control list
   virtual QList<QWidget*> getControls() const;
 
+protected:
   /// Returns true if the event is processed.
   virtual bool processEnter();
 
-protected:
   /// Saves the internal parameters to the given feature
   /// \return True in success
   virtual bool storeValueCustom();
index ac67b871378f4914be06bdba58a449fe442e35ab..aee98f9f418735dec8293e96aacafc87091852fd 100644 (file)
@@ -52,10 +52,10 @@ class MODULEBASE_EXPORT ModuleBase_WidgetLineEdit : public ModuleBase_ModelWidge
   /// Redefinition of virtual method
   virtual QList<QWidget*> getControls() const;
 
+protected:
   /// Returns true if the event is processed.
   virtual bool processEnter();
 
-protected:
   /// Saves the internal parameters to the given feature
   /// \return True in success
   virtual bool storeValueCustom();
index d144f33821c377a605e3bed8e80daee5059919a8..973b9b6ec5aeaa7d02d27de41f478b5d5fac19bc 100755 (executable)
@@ -58,6 +58,8 @@
 
 const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1;
 
+//#define DEBUG_UNDO_REDO
+
 /**
 * Customization of a List Widget to make it to be placed on full width of container
 */
@@ -99,11 +101,27 @@ protected:
 #endif
 };
 
+#ifdef DEBUG_UNDO_REDO
+void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex,
+  QList<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > theSelectedHistoryValues)
+{
+  QStringList aSizes;
+  for (int i = 0; i < theSelectedHistoryValues.size(); i++)
+    aSizes.append(QString::number(theSelectedHistoryValues[i].size()));
+
+  std::cout << theMethodName.toStdString()
+            << "  current = " << theCurrentHistoryIndex
+            << " size(history) =  " << theSelectedHistoryValues.size()
+            << " (" << aSizes.join(", ").toStdString() << ")"
+            << std::endl;
+}
+#endif
+
 ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent,
                                                                ModuleBase_IWorkshop* theWorkshop,
                                                                const Config_WidgetAPI* theData)
 : ModuleBase_WidgetSelector(theParent, theWorkshop, theData),
-  myIsSetSelectionBlocked(false)
+  myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1)
 {
   QGridLayout* aMainLay = new QGridLayout(this);
   ModuleBase_Tools::adjustMargins(aMainLay);
@@ -186,6 +204,8 @@ void ModuleBase_WidgetMultiSelector::activateCustom()
 
   myWorkshop->module()->activateCustomPrs(myFeature,
                             ModuleBase_IModule::CustomizeHighlightedObjects, true);
+  clearSelectedHistory();
+  myWorkshop->updateCommandStatus();
 }
 
 //********************************************************************
@@ -194,6 +214,8 @@ void ModuleBase_WidgetMultiSelector::deactivate()
   ModuleBase_WidgetSelector::deactivate();
 
   myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true);
+  clearSelectedHistory();
+  myWorkshop->updateCommandStatus();
 }
 
 //********************************************************************
@@ -309,6 +331,63 @@ void ModuleBase_WidgetMultiSelector::getHighlighted(QList<ModuleBase_ViewerPrsPt
     convertIndicesToViewerSelection(anAttributeIds, theValues);
 }
 
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::canProcessAction(ModuleBase_ActionType theActionType,
+                                                      bool& isActionEnabled)
+{
+  isActionEnabled = false;
+  bool aCanProcess = false;
+  switch (theActionType) {
+    case ActionUndo:
+    case ActionRedo: {
+      aCanProcess = true;
+      isActionEnabled = theActionType == ActionUndo ? myCurrentHistoryIndex > 0
+          : (mySelectedHistoryValues.size() > 0 &&
+             myCurrentHistoryIndex < mySelectedHistoryValues.size() - 1);
+    }
+    break;
+    default:
+    break;
+  }
+  return aCanProcess;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActionType)
+{
+  switch (theActionType) {
+    case ActionUndo:
+    case ActionRedo: {
+      if (theActionType == ActionUndo)
+        myCurrentHistoryIndex--;
+      else
+        myCurrentHistoryIndex++;
+      QList<ModuleBase_ViewerPrsPtr> aSelected = mySelectedHistoryValues[myCurrentHistoryIndex];
+      // equal vertices should not be used here
+      ModuleBase_ISelection::filterSelectionOnEqualPoints(aSelected);
+      bool isDone = setSelection(aSelected,
+                                 false /*need not validate because values already was in list*/);
+      updateOnSelectionChanged(isDone);
+
+      myWorkshop->updateCommandStatus();
+#ifdef DEBUG_UNDO_REDO
+      printHistoryInfo(QString("processAction %1").arg(theActionType == ActionUndo ? "Undo"
+        : "Redo"), myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
+      return true;
+    }
+    default:
+      return ModuleBase_ModelWidget::processAction(theActionType);
+  }
+}
+
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::activateSelectionAndFilters(bool toActivate)
+{
+  myWorkshop->updateCommandStatus(); // update enable state of Undo/Redo application actions
+  return ModuleBase_WidgetSelector::activateSelectionAndFilters(toActivate);
+}
+
 //********************************************************************
 bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
 {
@@ -340,6 +419,8 @@ bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_Vie
 //********************************************************************
 bool ModuleBase_WidgetMultiSelector::processDelete()
 {
+  appendFirstSelectionInHistory();
+
   // find attribute indices to delete
   std::set<int> anAttributeIds;
   getSelectedAttributeIndices(anAttributeIds);
@@ -392,6 +473,7 @@ bool ModuleBase_WidgetMultiSelector::processDelete()
       }
     }
   }
+  appendSelectionInHistory();
   return aDone;
 }
 
@@ -443,6 +525,8 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
   // may be the feature's result is not displayed, but attributes should be
   myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeArguments,
                             true); /// hope that something is redisplayed by object updated
+  // clear history should follow after set selected to do not increase history by setSelected
+  clearSelectedHistory();
 }
 
 //********************************************************************
@@ -462,7 +546,47 @@ void ModuleBase_WidgetMultiSelector::onSelectionChanged()
       }
     }
   }
+  appendFirstSelectionInHistory();
   ModuleBase_WidgetSelector::onSelectionChanged();
+  appendSelectionInHistory();
+}
+
+void ModuleBase_WidgetMultiSelector::appendFirstSelectionInHistory()
+{
+  if (mySelectedHistoryValues.empty()) {
+    myCurrentHistoryIndex++;
+    mySelectedHistoryValues.append(getAttributeSelection());
+
+#ifdef DEBUG_UNDO_REDO
+    printHistoryInfo("appendSelectionInHistory", myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
+  }
+}
+
+void ModuleBase_WidgetMultiSelector::appendSelectionInHistory()
+{
+  while (myCurrentHistoryIndex != mySelectedHistoryValues.count() - 1)
+    mySelectedHistoryValues.removeLast();
+
+  QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
+  myCurrentHistoryIndex++;
+  mySelectedHistoryValues.append(aSelected);
+  myWorkshop->updateCommandStatus();
+
+#ifdef DEBUG_UNDO_REDO
+  printHistoryInfo("appendSelectionInHistory", myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
+}
+
+void ModuleBase_WidgetMultiSelector::clearSelectedHistory()
+{
+  mySelectedHistoryValues.clear();
+  myCurrentHistoryIndex = -1;
+  myWorkshop->updateCommandStatus();
+
+#ifdef DEBUG_UNDO_REDO
+  printHistoryInfo("clearSelectedHistory", myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
 }
 
 void ModuleBase_WidgetMultiSelector::updateFocus()
index 2e43e575d1f93c0f9382e81a342c513cfb0325c4..74b0ff510ea36567495b8204b91dbfb30d0653ae 100755 (executable)
@@ -88,14 +88,23 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Widge
   /// \param theValues a list of presentations
   virtual void getHighlighted(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues);
 
+  /// Returns true if the action can be processed. By default it is empty and returns false.
+  /// \param theActionType an action type
+  /// \param isActionEnabled if true, the enable state of the action
+  virtual bool canProcessAction(ModuleBase_ActionType theActionType, bool& isActionEnabled);
+
+  /// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processAction(ModuleBase_ActionType theActionType);
+
+  /// Activate or deactivate selection and selection filters
+  /// \return true if the selection filter of the widget is activated in viewer context
+  virtual bool activateSelectionAndFilters(bool toActivate);
+
   /// Checks the widget validity. By default, it returns true.
   /// \param thePrs a selected presentation in the view
   /// \return a boolean value
   virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
 
-  /// Returns true if the event is processed. The default implementation is empty, returns false.
-  virtual bool processDelete();
-
 public slots:
   /// Slot is called on selection type changed
   void onSelectionTypeChanged();
@@ -115,6 +124,9 @@ protected slots:
   void onListSelection();
 
 protected:
+  /// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processDelete();
+
   /// The methiod called when widget is activated
   virtual void activateCustom();
 
@@ -122,8 +134,19 @@ protected:
   /// \return True in success
   virtual bool storeValueCustom();
 
+  /// restire type of selection by feature attribute
   virtual bool restoreValueCustom();
 
+  /// Creates an element of the attribute current selection if history is empty
+  virtual void appendFirstSelectionInHistory();
+
+  /// Create an element in the history that stores the current selection,
+  /// position in the history is incremented
+  void appendSelectionInHistory();
+
+  /// Clear list of stored selected items, reset current position into '-1'
+  void clearSelectedHistory();
+
   /// Set the focus on the last item in  the list
   virtual void updateFocus();
 
@@ -215,6 +238,11 @@ protected:
 
   /// A flag to block set selection perform if the method is in process
   bool myIsSetSelectionBlocked;
+
+  /// A container of selected objects
+  QList<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > mySelectedHistoryValues;
+  /// Position in a container of selected values
+  int myCurrentHistoryIndex;
 };
 
 #endif /* MODULEBASE_WIDGETFILESELECTOR_H_ */
index 065c7971cae650daa565e2e0bfa78f772cec1d26..cc2ad4b0f090eead63aa3bc8e3837ef7f4bb804c 100644 (file)
 
 #include "PartSet_CenterPrs.h"
 
+#include <ModuleBase_Tools.h>
 #include <Geom_CartesianPoint.hxx>
+#include <Prs3d_PointAspect.hxx>
+#include <Graphic3d_AspectMarker3d.hxx>
+#include <Prs3d_Root.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
+#include <AIS_InteractiveContext.hxx>
 
 
 IMPLEMENT_STANDARD_RTTIEXT(PartSet_CenterPrs, AIS_Point)
 
+
 PartSet_CenterPrs::PartSet_CenterPrs(const ObjectPtr& theObject,
                                      const GeomEdgePtr& theEdge,
                                      const gp_Pnt& theCenter,
@@ -38,4 +45,61 @@ PartSet_CenterPrs::PartSet_CenterPrs(const ObjectPtr& theObject,
   myEdge(theEdge),
   myCenterType(theType)
 {
-}
\ No newline at end of file
+  SetAutoHilight(Standard_False);
+}
+
+void PartSet_CenterPrs::drawPoint(const Handle(Prs3d_Presentation)& thePrs,
+                                  Quantity_Color theColor)
+{
+  Handle(Prs3d_Drawer) aDrawer = HilightAttributes();
+
+  Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
+
+  Handle(Graphic3d_AspectMarker3d) PtA = aPntAspect->Aspect();
+  PtA->SetType(Aspect_TOM_RING1);
+  PtA->SetColor(theColor);
+
+  Handle(Geom_Point) aPnt = Component();
+  Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(thePrs);
+  TheGroup->SetPrimitivesAspect(PtA);
+
+  Handle(Graphic3d_ArrayOfPoints) aPoint = new Graphic3d_ArrayOfPoints (1);
+  aPoint->AddVertex(aPnt->X(),aPnt->Y(),aPnt->Z());
+  TheGroup->AddPrimitiveArray(aPoint);
+
+  PtA = new Graphic3d_AspectMarker3d();
+  PtA->SetType(Aspect_TOM_POINT);
+  PtA->SetScale(5.);
+  PtA->SetColor(theColor);
+  TheGroup->SetPrimitivesAspect(PtA);
+  TheGroup->AddPrimitiveArray (aPoint);
+}
+
+void PartSet_CenterPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& PM,
+                                        const SelectMgr_SequenceOfOwner& Seq)
+{
+  Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( PM );
+  aSelectionPrs->Clear();
+
+  drawPoint(aSelectionPrs, GetContext()->SelectionStyle()->Color());
+
+  aSelectionPrs->SetDisplayPriority(9);
+  aSelectionPrs->Display();
+  PM->Color(this, GetContext()->SelectionStyle());
+}
+
+void PartSet_CenterPrs::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                              const Handle(Graphic3d_HighlightStyle)& theStyle,
+                                              const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+  Handle( Prs3d_Presentation ) aHilightPrs = GetHilightPresentation( thePM );
+  aHilightPrs->Clear();
+
+  thePM->Color(this, theStyle);
+  drawPoint(aHilightPrs, theStyle->Color());
+
+  aHilightPrs->SetZLayer(Graphic3d_ZLayerId_Topmost);
+
+  if (thePM->IsImmediateModeOn())
+    thePM->AddToImmediateList(aHilightPrs);
+}
index 86e54b24f345f62e11fd06baa0f12a7c41760d06..8d60f6466880d2109e953892b368e5ec87c7d6bc 100644 (file)
@@ -32,6 +32,7 @@
 #include <AIS_Point.hxx>
 #include <Standard_DefineHandle.hxx>
 #include <gp_Pnt.hxx>
+#include <Geom_Point.hxx>
 
 DEFINE_STANDARD_HANDLE(PartSet_CenterPrs, AIS_Point)
 
@@ -61,9 +62,17 @@ public:
   /// Returns type of the center
   ModelAPI_AttributeSelection::CenterType centerType() const { return myCenterType; }
 
+  virtual void HilightSelected(const Handle(PrsMgr_PresentationManager3d)& PM,
+                               const SelectMgr_SequenceOfOwner& Seq);
+  virtual void HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)&,
+                                      const Handle(Graphic3d_HighlightStyle)&,
+                                      const Handle(SelectMgr_EntityOwner)&);
+
   DEFINE_STANDARD_RTTIEXT(PartSet_CenterPrs, AIS_Point)
 
 private:
+  void drawPoint(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor);
+
   ObjectPtr myObject;
   GeomEdgePtr myEdge;
   ModelAPI_AttributeSelection::CenterType myCenterType;
index a33d6c39168c31af1885e267f36d7d9930e9ef39..793940ccab1e13b733d4cef8ba3c6ab6a40a1d2d 100755 (executable)
@@ -77,7 +77,7 @@ ObjectPtr PartSet_ExternalObjectsMgr::externalObject(const ObjectPtr& theSelecte
     FeaturePtr aCreatedFeature;
     aSelectedObject = PartSet_Tools::createFixedObjectByExternal(theShape,
       theSelectedObject, theSketch, theTemporary, aCreatedFeature);
-    if (aSelectedObject.get() && theTemporary)
+    if (aCreatedFeature.get() && theTemporary)
         myExternalObjectValidated = aCreatedFeature;
   }
   return aSelectedObject;
index 2851ea877dc2fac100e4d03b987cd42eceebc1a7..afe4fbbda47d0090db276282818800f086cda5f5 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_ResultPart.h>
+#include <ModelAPI_ResultGroup.h>
 #include <ModelAPI_Session.h>
 
 #include <AIS_InteractiveObject.hxx>
@@ -57,11 +58,17 @@ Standard_Boolean PartSet_GlobalFilter::IsOk(const Handle(SelectMgr_EntityOwner)&
         ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
         // result of parts belongs to PartSet document and can be selected only when PartSet
         //  is active in order to do not select the result of the active part.
-        if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group()) {
-          SessionPtr aMgr = ModelAPI_Session::get();
-          aValid = aMgr->activeDocument() == aMgr->moduleDocument();
+        if (aResult.get()) {
+          if (aResult->groupName() == ModelAPI_ResultPart::group()) {
+            SessionPtr aMgr = ModelAPI_Session::get();
+            aValid = aMgr->activeDocument() == aMgr->moduleDocument();
+          } else if (aResult->groupName() == ModelAPI_ResultGroup::group()) {
+            aValid = Standard_False;
+          } else
+            aValid = Standard_True;
         }
-        else {
+        else { // possibly this code is obsolete, as a feature object can be selected in recovery
+          // only and there can not be Group feature
           FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
           if (aFeature) {
             aValid = aFeature->getKind() != "Group";
index 8ae275c83eb766e8747a46e86ee18a4d517d40c6..f6131c3fe37b61a13c8aa19504a8b202efcfa33f 100755 (executable)
 #include <XGUI_SelectionMgr.h>
 #include <XGUI_ActionsMgr.h>
 
-#include <SketchPlugin_Feature.h>
-#include <SketchPlugin_Sketch.h>
 #include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintLength.h>
 #include <SketchPlugin_ConstraintDistance.h>
 #include <SketchPlugin_ConstraintParallel.h>
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintRadius.h>
+#include <SketchPlugin_Feature.h>
+#include <SketchPlugin_Projection.h>
+#include <SketchPlugin_Sketch.h>
 
 #include <SketcherPrs_SymbolPrs.h>
 #include <SketcherPrs_Coincident.h>
@@ -624,7 +625,6 @@ bool PartSet_Module::isSketchNeutralPointActivated() const
 void PartSet_Module::closeDocument()
 {
   myActivePartIndex = QModelIndex();
-  clearViewer();
 }
 
 void PartSet_Module::clearViewer()
@@ -935,15 +935,21 @@ void PartSet_Module::onObjectDisplayed(ObjectPtr theObject, AISObjectPtr theAIS)
 {
   Handle(AIS_InteractiveObject) anAIS = theAIS->impl<Handle(AIS_InteractiveObject)>();
   if (!anAIS.IsNull()) {
+    bool aToUseZLayer = false;
+    FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+    if (aFeature.get() && PartSet_Tools::findRefsToMeFeature(aFeature,
+                                                        SketchPlugin_Projection::ID()))
+      aToUseZLayer = true;
     Handle(AIS_InteractiveContext) aCtx = anAIS->GetContext();
     Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAIS);
     if (!aDim.IsNull()) {
-      aCtx->SetZLayer(aDim, myVisualLayerId);
+      aToUseZLayer = true;
     } else {
       Handle(SketcherPrs_SymbolPrs) aCons = Handle(SketcherPrs_SymbolPrs)::DownCast(anAIS);
       if (!aCons.IsNull())
-        aCtx->SetZLayer(aCons, myVisualLayerId);
+      aToUseZLayer = true;
     }
+    aCtx->SetZLayer(anAIS, myVisualLayerId);
   }
 }
 
@@ -998,8 +1004,6 @@ void PartSet_Module::onViewTransformed(int theTrsfType)
     SketcherPrs_Tools::setArrowSize(aLen);
     const double aCurScale = aViewer->activeView()->Camera()->Scale();
     aViewer->SetScale(aViewer->activeView(), aCurScale);
-    double aTextHeight = SketcherPrs_Tools::getConfigTextHeight();
-    SketcherPrs_Tools::setTextHeight (aTextHeight);
     bool isModified = false;
     QList<AISObjectPtr> aPrsList = aDisplayer->displayedPresentations();
     foreach (AISObjectPtr aAIS, aPrsList) {
@@ -1008,7 +1012,6 @@ void PartSet_Module::onViewTransformed(int theTrsfType)
       Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(aAisObj);
       if (!aDim.IsNull()) {
         aDim->DimensionAspect()->ArrowAspect()->SetLength(aLen);
-        aDim->DimensionAspect()->TextAspect()->SetHeight(aTextHeight);
         aContext->Redisplay(aDim, false);
         isModified = true;
       }
@@ -1195,8 +1198,9 @@ void PartSet_Module::addObjectBrowserMenu(QMenu* theMenu) const
   bool hasParameter = false;
   bool hasCompositeOwner = false;
   bool hasResultInHistory = false;
+  bool hasFolder = false;
   ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter,
-                                  hasCompositeOwner, hasResultInHistory);
+                                  hasCompositeOwner, hasResultInHistory, hasFolder);
 
   ModuleBase_Operation* aCurrentOp = myWorkshop->currentOperation();
   if (aSelected == 1) {
index 6de85edc74977390ffd94ea3f4230979c65ea3b8..f0f614bb0f4ec9d7dccc2037b878fa7b1f784433 100644 (file)
@@ -41,7 +41,7 @@
 #include <SketchPlugin_SketchEntity.h>
 
 PartSet_PreviewSketchPlane::PartSet_PreviewSketchPlane()
- : myPreviewIsDisplayed(false)
+ : myPreviewIsDisplayed(false), mySizeOfView(0), myIsUseSizeOfView(false)
 {
 }
 
@@ -75,17 +75,23 @@ void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& th
     // selected linear face parameters
     AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
       (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
-    if (aSelAttr)
+    if (aSelAttr) {
       myShape = aSelAttr->value();
-
+      // this case is needed by constructing sketch on a plane, where result shape is equal
+      // to context result, therefore value() returns NULL and we should use shape of context.
+      if (!myShape.get() && aSelAttr->context().get())
+        myShape = aSelAttr->context()->shape();
+    }
     if (!myShape.get()) {
       // Create Preview for default planes
       std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
           theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
       std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
           theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-      myShape = GeomAlgoAPI_FaceBuilder::squareFace(anOrigin->pnt(), aNormal->dir(),
-        Config_PropManager::integer(SKETCH_TAB_NAME, "planes_size"));
+
+      double aFaceSize = myIsUseSizeOfView ? mySizeOfView
+        : Config_PropManager::integer(SKETCH_TAB_NAME, "planes_size");
+      myShape = GeomAlgoAPI_FaceBuilder::squareFace(anOrigin->pnt(), aNormal->dir(), aFaceSize);
     }
     myPlane = createPreviewPlane();
   }
@@ -95,6 +101,12 @@ void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& th
   myPreviewIsDisplayed = true;
 }
 
+void PartSet_PreviewSketchPlane::setSizeOfView(double theSizeOfView, bool isUseSizeOfView)
+{
+  mySizeOfView = theSizeOfView;
+  myIsUseSizeOfView = isUseSizeOfView;
+}
+
 AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane()
 {
   if (myPlane.get()) {
index 11eabebd69e25b4f1cc49d5615e386120a56ad4e..b797b2dd4fbc04c13c2460aa40c8e80f31105c71 100644 (file)
@@ -53,6 +53,15 @@ public:
   void createSketchPlane(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
                          ModuleBase_IWorkshop* theWorkshop);
 
+  /// Returns whether custom size of view is set
+  /// \return boolean value
+  bool isUseSizeOfView() const { return myIsUseSizeOfView; }
+
+  /// Sets the size of default created face
+  /// \param theSizeOfView value
+  /// \param isUseSizeOfView state whether the size should be used
+  void setSizeOfView(double theSizeOfView, bool isUseSizeOfView);
+
 private:
   /// Create a square face by parameters
   std::shared_ptr<GeomAPI_AISObject> createPreviewPlane();
@@ -61,6 +70,9 @@ private:
   bool myPreviewIsDisplayed;
   std::shared_ptr<GeomAPI_AISObject> myPlane; //! visualized presentation
   std::shared_ptr<GeomAPI_Shape> myShape; //! current shape to be displayed
+
+  double mySizeOfView; //! size that should be used by creating a default face
+  bool myIsUseSizeOfView; //! state if the size is custom or from preferences
 };
 
 #endif
\ No newline at end of file
index d7c4812d02a6325b3b57d505225b89c74c6647bb..dac76b8e98286ecada62e6c7adf612516a757e53 100755 (executable)
@@ -90,6 +90,7 @@
 #include <AIS_InteractiveObject.hxx>
 #include <StdSelect_BRepOwner.hxx>
 #include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <V3d_Coordinate.hxx>
 
 #include <QMouseEvent>
 
index 486d361e01cdb6d30461f5fd587858973c176306..1a8beb6703ecde71c7df961411e7d564707e934b 100755 (executable)
@@ -256,7 +256,7 @@ public:
     std::set<AttributePtr>::const_iterator anIt;
     for (anIt = aRefsList.cbegin(); anIt != aRefsList.cend(); ++anIt) {
       FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*anIt)->owner());
-      if (aRefFeature->getKind() == theFeatureId)
+      if (aRefFeature && aRefFeature->getKind() == theFeatureId)
         return aRefFeature;
     }
     return FeaturePtr();
index a1bd76150cb8264ed0ab1597a6a0ef2aef8833f0..f31198234f3d9be6d5d423019c3021f3522d811f 100644 (file)
@@ -195,6 +195,10 @@ bool PartSet_WidgetSketchCreator::isValidSelectionCustom(const ModuleBase_Viewer
 
 void PartSet_WidgetSketchCreator::activateSelectionControl()
 {
+  // reset previously set size of view needed on restart extrusion after Sketch
+  if (myModule->sketchMgr()->previewSketchPlane()->isUseSizeOfView())
+    myModule->sketchMgr()->previewSketchPlane()->setSizeOfView(0, false);
+
   // we need to call activate here as the widget has no focus accepted controls
   // if these controls are added here, activate will happens automatically after focusIn()
   XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
@@ -359,20 +363,18 @@ bool PartSet_WidgetSketchCreator::startSketchOperation(
   // Set View size if a plane is selected
   if (myPreviewPlanes->isPreviewDisplayed() &&
       myPreviewPlanes->isPreviewShape(aValue->shape())) {
+    // set default plane size
+    bool isSetSizeOfView = false;
+    double aSizeOfView = 0;
     QString aSizeOfViewStr = mySizeOfView->text();
     if (!aSizeOfViewStr.isEmpty()) {
-      bool isOk;
-      double aSizeOfView = aSizeOfViewStr.toDouble(&isOk);
-      if (isOk && aSizeOfView > 0) {
-        Handle(V3d_View) aView3d = myWorkshop->viewer()->activeView();
-        if (!aView3d.IsNull()) {
-          Bnd_Box aBndBox;
-          double aHalfSize = aSizeOfView/2.0;
-          aBndBox.Update(-aHalfSize, -aHalfSize, -aHalfSize, aHalfSize, aHalfSize, aHalfSize);
-          aView3d->FitAll(aBndBox, 0.01, false);
-        }
+      aSizeOfView = aSizeOfViewStr.toDouble(&isSetSizeOfView);
+      if (isSetSizeOfView && aSizeOfView <= 0) {
+        isSetSizeOfView = false;
       }
     }
+    if (isSetSizeOfView)
+      myModule->sketchMgr()->previewSketchPlane()->setSizeOfView(aSizeOfView, true);
   }
   // manually deactivation because the widget was not activated as has no focus acceptin controls
   deactivate();
index d3908d81e0e350937d88b90f512c7156dd2fe35d..63cd3927ee2a66112b1837dd45677cc43786346a 100644 (file)
@@ -278,7 +278,20 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs
   PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
   if (aModule) {
     CompositeFeaturePtr aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+    bool isSetSizeOfView = false;
+    double aSizeOfView = 0;
+    QString aSizeOfViewStr = mySizeOfView->text();
+    if (!aSizeOfViewStr.isEmpty()) {
+      aSizeOfView = aSizeOfViewStr.toDouble(&isSetSizeOfView);
+      if (isSetSizeOfView && aSizeOfView <= 0) {
+        isSetSizeOfView = false;
+      }
+    }
+    if (isSetSizeOfView)
+      aModule->sketchMgr()->previewSketchPlane()->setSizeOfView(aSizeOfView, true);
     aModule->sketchMgr()->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
+    if (isSetSizeOfView)
+      aModule->sketchMgr()->previewSketchPlane()->setSizeOfView(aSizeOfView, false);
   }
   // 2. if the planes were displayed, change the view projection
   const GeomShapePtr& aShape = thePrs->shape();
@@ -334,20 +347,6 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs
     if (aRotate) {
       myWorkshop->viewer()->setViewProjection(aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aTwist);
     }
-    QString aSizeOfViewStr = mySizeOfView->text();
-    if (!aSizeOfViewStr.isEmpty()) {
-      bool isOk;
-      double aSizeOfView = aSizeOfViewStr.toDouble(&isOk);
-      if (isOk && aSizeOfView > 0) {
-        Handle(V3d_View) aView3d = myWorkshop->viewer()->activeView();
-        if (!aView3d.IsNull()) {
-          Bnd_Box aBndBox;
-          double aHalfSize = aSizeOfView/2.0;
-          aBndBox.Update(-aHalfSize, -aHalfSize, -aHalfSize, aHalfSize, aHalfSize, aHalfSize);
-          aView3d->FitAll(aBndBox, 0.01, false);
-        }
-      }
-    }
     PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
     if (aModule)
       aModule->onViewTransformed();
index 7588c6be1c4629d9b0a3f3e8d430c2d491adf466..800ce0e05fbec009dcfc5543ffc70186ca71dc30 100644 (file)
@@ -132,7 +132,7 @@ def bottom_body():
 
 def body_3():
     # Create XOZ sketch
-    sketch = model.addSketch(part, "Boolean_1_1/Modified_2")
+    sketch = model.addSketch(part, "Boolean_1_1/Modified_3")
 
     # Create base polygon
     H, L, l, r = 28, 40, 8, 12
@@ -170,7 +170,7 @@ def body_3():
     sketch.setRadius(arc, r)
 
     # Binding
-    bottom_e = sketch.addLine("Boolean_1_1/Modified_7&Boolean_1_1/Modified_5")
+    bottom_e = sketch.addLine("Boolean_1_1/Modified_8&Boolean_1_1/Modified_5")
     sketch.setCoincident(bottom_e, bottom.startPoint())
     sketch.setCoincident(bottom_e.startPoint(), bottom.endPoint())
 
@@ -196,7 +196,7 @@ def body_4():
     sketch.setCoincident(bottom_e.endPoint(), bottom.startPoint())
     sketch.setCoincident(bottom_e.startPoint(), left.startPoint())
 
-    left_e = sketch.addLine("Boolean_2_1/Modified_6&Boolean_2_1/Modified_8")
+    left_e = sketch.addLine("Boolean_2_1/Modified_6&Boolean_2_1/Modified_7")
     sketch.setCoincident(left_e.startPoint(), left.endPoint())
 
     model.do()  #!!!
@@ -211,11 +211,13 @@ b1 = vertical_body()
 b2 = bottom_body()
 
 boolean = model.addFuse(part, b1.results() + b2.results())
+boolean.result().setName("Boolean_1_1")
 model.do()
 
 b3 = body_3()
 
 boolean = model.addFuse(part, boolean.results() + b3.results())
+boolean.result().setName("Boolean_2_1")
 model.do()
 
 # START DEBUG PURPOSES
index 680ae82f43c2da6828e4e7fa52aed7d84eb0772a..5cb8cd081073ef6cbde2bd33ef13cf4d6015f446 100644 (file)
@@ -73,6 +73,11 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
             # In case of theFeature is not a constraint, it will not be dumped.
             self.myFeatures[SketchAPI.SketchAPI_Constraint.ID()](theFeature).dump(self)
 
+    ## Create wrapper for a folder and dump it
+    def dumpFolder(self, theFolder):
+        if theFolder.ID() in self.myFeatures:
+            self.myFeatures[theFolder.ID()](theFolder).dump(self)
+
     ## Dump all parameters
     def dumpParameter(self, theFeature):
         aFeatureKind = theFeature.getKind()
index a69fea2d010d28f9cb992ecfdaef9b1f10b2e4c9..0347b26b273484f14c39702e969245bb5e132788 100644 (file)
@@ -9,3 +9,4 @@ from FeaturesAPI import addPipe
 from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addFill
 from FeaturesAPI import addIntersection, addPartition, addUnion, addRemoveSubShapes
 from FeaturesAPI import addRecover
+from FeaturesAPI import addFillet
index 428c1be61cfbd88b60827eb40411921325513105..ffc05033b93a12be9e36491e7cdb915bc2bb5ba2 100644 (file)
@@ -1,5 +1,5 @@
 """Package for GDML plugin for the Parametric Geometry API of the Modeler.
 """
 
-from GDMLAPI import addConeSegment
+from GDMLAPI import addConeSegment, addEllipsoid
 
index 8c15e89ecaf19521c50982e8cf42c9c133bbacd0..db5279d84ec6c7995b930b2522c2602f434b5636 100644 (file)
@@ -8,5 +8,6 @@ from ModelHighAPI import apply as do
 from ModelHighAPI import updateFeatures
 from ModelHighAPI import undo, redo
 from ModelHighAPI import reset
+from ModelHighAPI import addFolder
 from ModelHighAPI import ModelHighAPI_Selection as selection
 from ModelHighAPI import checkPythonDump as checkPythonDump
index ce6c3933288a6944447620e92cdccd649407128d..0b49118b289a8eef36e4d72ecc3c90c74508489f 100644 (file)
@@ -166,7 +166,7 @@ def testHaveNamingFaces(theFeature, theModel, thePartDoc) :
     assert(name != ""), "String empty"
 
 def testHaveNamingEdges(theFeature, theModel, thePartDoc) :
-  """ Tests if all faces of result have a name
+  """ Tests if all edges of result have a name
   :param theFeature: feature to test.
   """
   # Get feature result/sub-result
@@ -198,6 +198,49 @@ def testHaveNamingEdges(theFeature, theModel, thePartDoc) :
     assert(shape.isEdge())
     assert(name != ""), "String empty"
 
+def testHaveNamingVertices(theFeature, theModel, thePartDoc) :
+  """ Tests if all vertices of result have a unique 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.VERTEX)
+  # Create list, and store selections in it
+  selectionList = []
+  shapesList = [] # to append only unique shapes (not isSame)
+  while shapeExplorer.more():
+    aDuplicate = False
+    for alreadyThere in shapesList:
+      if alreadyThere.isSame(shapeExplorer.current()):
+        aDuplicate = True
+    if aDuplicate:
+      shapeExplorer.next()
+      continue
+    shapesList.append(shapeExplorer.current())
+    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()
+
+  # Check that all selected shapes in group have right shape type and unique name.
+  groupFeature = Group_1.feature()
+  groupSelectionList = groupFeature.selectionList("group_list")
+  assert(groupSelectionList.size() == len(selectionList))
+  presented_names = set()
+  for index in range(0, groupSelectionList.size()):
+    attrSelection = groupSelectionList.value(index)
+    shape = attrSelection.value()
+    name = attrSelection.namingName()
+    assert(shape.isVertex())
+    assert(name != ""), "String empty"
+    presented_names.add(name)
+  assert(len(presented_names) == groupSelectionList.size()), "Some names are not unique"
+
 
 def testNbSubFeatures(theComposite, theKindOfSub, theExpectedCount):
   """ Tests number of sub-features of the given type
@@ -223,3 +266,13 @@ def assertSketchArc(theArcFeature):
   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)
+
+def checkBooleansResult(theFeature,theModel,NbRes,NbSubRes,NbSolid,NbFace,NbEdge,NbVertex):
+  """ Tests numbers of sub-shapes in results (used in Boolean operations tests)
+  """
+  theModel.testNbResults(theFeature, NbRes)
+  theModel.testNbSubResults(theFeature,NbSubRes)
+  theModel.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid )
+  theModel.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, NbFace)
+  theModel.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, NbEdge)
+  theModel.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, NbVertex)
index c5a75fef3a135a6dacc4f8feaee90d7a74007f61..5098ce99f5b6896b7e8d9f62ac3c5ffb7d4a1c89 100644 (file)
@@ -169,6 +169,18 @@ void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const
       return;
   }
 
+  // Check all attributes are already dumped. If not, store the constraint as postponed.
+  bool areAttributesDumped = true;
+  for (int i = 0; i < CONSTRAINT_ATTR_SIZE && areAttributesDumped; ++i) {
+    AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+    if (aRefAttr && aRefAttr->isInitialized())
+      areAttributesDumped = theDumper.isDumped(aRefAttr);
+  }
+  if (!areAttributesDumped) {
+    theDumper.postpone(aBase);
+    return;
+  }
+
   bool isAngle = aBase->getKind() == SketchPlugin_ConstraintAngle::ID();
   std::string aSetterSuffix;
   if (isAngle)
index b13e94f03abc6cc5a233985f818d0e65fe86db20..73f13635d9f67e51c5193374021b197da88b3723 100644 (file)
@@ -70,8 +70,16 @@ void SketchAPI_Mirror::dump(ModelHighAPI_Dumper& theDumper) const
   FeaturePtr aBase = feature();
   const std::string& aSketchName = theDumper.parentName(aBase);
 
+
   AttributeRefAttrPtr aMirrorLine = mirrorLine();
   AttributeRefListPtr aMirrorObjects = mirrorList();
+
+  // Check all attributes are already dumped. If not, store the constraint as postponed.
+  if (!theDumper.isDumped(aMirrorLine) || !theDumper.isDumped(aMirrorObjects)) {
+    theDumper.postpone(aBase);
+    return;
+  }
+
   theDumper << aBase << " = " << aSketchName << ".addMirror(" << aMirrorLine << ", "
             << aMirrorObjects << ")" << std::endl;
 
index b217ad0b3ef4affa412db57e9b5ddecd4e4c1bab..a736df25b8f759e1d19d9de19d71d93a24de1698 100644 (file)
@@ -86,6 +86,12 @@ void SketchAPI_Rotation::dump(ModelHighAPI_Dumper& theDumper) const
   AttributeIntegerPtr aNbCopies = numberOfObjects();
   bool isFullValue = valueType()->value() != "SingleAngle";
 
+  // Check all attributes are already dumped. If not, store the constraint as postponed.
+  if (!theDumper.isDumped(aCenter) || !theDumper.isDumped(aRotObjects)) {
+    theDumper.postpone(aBase);
+    return;
+  }
+
   theDumper << aBase << " = " << aSketchName << ".addRotation("
             << aRotObjects << ", " << aCenter << ", " << anAngle << ", " << aNbCopies;
   if (isFullValue)
index 05dcb1c8f994fd05a3f1b34a9e166767e4235942..dddf3b4ad7b0455eca4f2573a182f21a7471d295 100644 (file)
@@ -86,6 +86,13 @@ void SketchAPI_Translation::dump(ModelHighAPI_Dumper& theDumper) const
   AttributeIntegerPtr aNbCopies = numberOfObjects();
   bool isFullValue = valueType()->value() != "SingleValue";
 
+  // Check all attributes are already dumped. If not, store the constraint as postponed.
+  if (!theDumper.isDumped(aStart) || !theDumper.isDumped(aEnd) ||
+      !theDumper.isDumped(aTransObjects)) {
+    theDumper.postpone(aBase);
+    return;
+  }
+
   theDumper << aBase << " = " << aSketchName << ".addTranslation("
             << aTransObjects << ", " << aStart << ", " << aEnd << ", " << aNbCopies;
   if (isFullValue)
index e7ec8b7c75dd03891b82e56f0ad4bde4e7c85cba..94e45677774d15570a4b61c25dafa73957402026 100644 (file)
@@ -179,6 +179,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestConstraintTangent.py
                TestConstraintAngle.py
                TestConstraintMiddlePoint.py
+               TestEdgesOrder.py
                TestMirror.py
                TestMultiRotation.py
                TestMultiTranslation.py
@@ -225,6 +226,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestSignedDistancePointLine.py
                Test2273.py
                Test2280.py
+               Test2287.py
 )
 
 if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
index fb6815a16192451324a9171601093ae40ca45898..1981738505a0213ab9350ba4701f6598f3f229ee 100644 (file)
@@ -162,7 +162,8 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(lastResult());
   if (aResult && aResult->shape() && theID == EXTERNAL_FEATURE_ID()) {
     aResult->setShape(std::shared_ptr<GeomAPI_Edge>());
-    aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
+    if (aProjection)
+      aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
   }
 
   if (aVertex) {
@@ -259,7 +260,8 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
     if (aResult) {
       aResult->setShape(aProjection->lastResult()->shape());
       setResult(aResult);
-      aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
+      GeomShapePtr anEmptyVal;
+      aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), anEmptyVal);
     }
   }
 }
index a7a8f69b224e7250d4ef0b9ad8ab173509c5f3f9..b254d63d4bc890b7e9ca5d45fcb1cef3c6c77f37 100644 (file)
@@ -317,7 +317,7 @@ void SketchPlugin_Split::execute()
 
   // coincidence to feature
   updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences,
-                                        aFeatureResults, aSplitFeature);
+                                        aFeatureResults, aSplitFeature, aFeaturesToDelete);
 
   updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes);
 
@@ -875,7 +875,8 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature(
       const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature,
       const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
       const std::set<ResultPtr>& theFeatureResults,
-      const FeaturePtr& theSplitFeature)
+      const FeaturePtr& theSplitFeature,
+      std::set<FeaturePtr>& theFeaturesToDelete)
 {
   if (theCoincidenceToFeature.empty())
     return;
@@ -898,6 +899,9 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature(
   for (; aCIt != aCLast; aCIt++) {
     FeaturePtr aCoincFeature = aCIt->first;
     std::string anAttributeId = aCIt->second.first;
+    std::string aSecondAttribute = anAttributeId == SketchPlugin_Constraint::ENTITY_A() ?
+        SketchPlugin_Constraint::ENTITY_B() : SketchPlugin_Constraint::ENTITY_A();
+
     AttributePoint2DPtr aCoincPoint = aCIt->second.second;
     std::set<AttributePoint2DPtr>::const_iterator aFCIt = theFurtherCoincidences.begin(),
                                                   aFCLast = theFurtherCoincidences.end();
@@ -909,17 +913,16 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature(
         aFeaturePointAttribute = aFCAttribute;
     }
     if (aFeaturePointAttribute.get()) {
-      aCoincFeature->refattr(anAttributeId)->setObject(ResultPtr());
-      aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute);
+      // create new constraint and remove the current
+      aCoincFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
+          aFeaturePointAttribute, aCoincFeature->refattr(aSecondAttribute)->attr());
+      theFeaturesToDelete.insert(aCIt->first);
       // create new coincidences to split feature points
       std::set<AttributePoint2DPtr>::const_iterator aSFIt = aNewCoincidencesToSplitFeature.begin(),
                                                     aSFLast = aNewCoincidencesToSplitFeature.end();
       for (; aSFIt != aSFLast; aSFIt++) {
         AttributePoint2DPtr aSFAttribute = *aSFIt;
         if (aCoincPnt->isEqual(aSFAttribute->pnt())) {
-          std::string aSecondAttribute = SketchPlugin_Constraint::ENTITY_A();
-          if (anAttributeId == SketchPlugin_Constraint::ENTITY_A())
-            aSecondAttribute = SketchPlugin_Constraint::ENTITY_B();
           createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
                            aSFAttribute, aCoincFeature->refattr(aSecondAttribute)->attr());
         }
index 1c9ae40e53441b66a14737ec0cdd42675579968b..37f1e1659c98c331bf483df8a1b8fbc4183a7e09 100644 (file)
@@ -181,12 +181,15 @@ private:
   /// \param theFurtherCoincidences a list of points where coincidences will be build
   /// \param theFeatureResults created results after split where constaint might be connected
   /// \param theSplitFeature feature created by split, new coincidences to points should be created
+  /// \param theFeaturesToDelete the list of removed features (will be updated here by
+  ///                            the coincidences to be removed)
   /// if theCoincidenceToFeature contains equal points
   void updateCoincidenceConstraintsToFeature(
       const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature,
       const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
       const std::set<ResultPtr>& theFeatureResults,
-      const FeaturePtr& theSplitFeature);
+      const FeaturePtr& theSplitFeature,
+      std::set<FeaturePtr>& theFeaturesToDelete);
 
   /// Move constraints from base feature to given feature
   /// \param theFeature a base feature
index aedc763322e4c4969e9a362fe366714debcf09d9..74be0dc1f4854be50af6d6ec28101fe528128e65 100644 (file)
@@ -379,7 +379,7 @@ void SketchPlugin_Trim::execute()
       anIt != aLast; anIt++) {
     AttributePtr anAttribute = *anIt;
 
-    if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences))
+    if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences, aFeaturesToDelete))
       continue;
 
     // move tangency constraint to the nearest feature if possible
@@ -533,7 +533,8 @@ std::string SketchPlugin_Trim::processEvent(const std::shared_ptr<Events_Message
 }
 
 bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute,
-                                const std::set<AttributePoint2DPtr>& theFurtherCoincidences)
+                                const std::set<AttributePoint2DPtr>& theFurtherCoincidences,
+                                std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete)
 {
   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
   if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
@@ -551,12 +552,9 @@ bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribu
     AttributePoint2DPtr aPointAttribute = (*anIt);
     std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
     if (aPoint2d->isEqual(aRefPnt2d)) {
-      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-                                                                           theAttribute);
-      if (aRefAttr.get()) {
-        aRefAttr->setAttr(aPointAttribute);
-        aFoundPoint = true;
-      }
+      // create new coincidence and then remove the old one
+      createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aRefPointAttr, aPointAttribute);
+      theFeaturesToDelete.insert(aFeature);
     }
   }
   return aFoundPoint;
index f03c5d59f5bca6622e92ae62ac4135d9af77d781..6ad6a58c4f9b9967966fd24798ecd8dcc92a6f6c 100644 (file)
@@ -117,7 +117,8 @@ class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentab
 
 private:
   bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
-            const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+            const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
+            std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete);
   /// Move tangency constraint to the feature if it is geometrically closely to it
   /// \param theAttribute an attribute of a tangent constraint feature
   /// \param theFeature a feature that can be set into the attribute
diff --git a/src/SketchPlugin/Test/Test2287.py b/src/SketchPlugin/Test/Test2287.py
new file mode 100644 (file)
index 0000000..1049f7d
--- /dev/null
@@ -0,0 +1,40 @@
+## 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(-20, -62, 81, 60)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), True)
+SketchLine_2 = SketchProjection_1.createdFeature()
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchProjection_1")])
+model.end()
+
+# before bug fix it was "Sketch_2"
+assert(Edge_1.baseObjects().value(0).namingName() == "Sketch_2/Edge-SketchProjection_1")
+
+assert(model.checkPythonDump())
diff --git a/src/SketchPlugin/Test/TestEdgesOrder.py b/src/SketchPlugin/Test/TestEdgesOrder.py
new file mode 100644 (file)
index 0000000..cc8ae38
--- /dev/null
@@ -0,0 +1,171 @@
+## 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>
+##
+
+"""
+    Verify the order of sketch edges is the same after dump
+"""
+
+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(40, 5, 40, -25)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchLine_2 = Sketch_1.addLine(40, -25, -10, -25)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 50)
+SketchLine_3 = Sketch_1.addLine(-10, -25, -10, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(-10, 5, 40, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+
+# Change Length references
+SketchConstraintLength_1.feature().refattr("ConstraintEntityA").setObject(SketchLine_3.feature().lastResult())
+SketchConstraintLength_2.feature().refattr("ConstraintEntityA").setObject(SketchLine_4.feature().lastResult())
+model.do()
+# Remove the first line, then build it and constraints from scratch
+Part_1_doc.removeFeature(SketchConstraintCoincidence_1.feature())
+Part_1_doc.removeFeature(SketchConstraintCoincidence_4.feature())
+Part_1_doc.removeFeature(SketchLine_1.feature())
+SketchLine_1 = Sketch_1.addLine(40, 5, 40, -25)
+Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+Sketch_1.setLength(SketchLine_1.result(), 20)
+Sketch_1.setLength(SketchLine_2.result(), 40)
+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(), 10, 0)
+
+# Extrude all lateral faces to check their area
+Extrusion_2 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
+SketchLine_5 = Sketch_2.addLine(0.7346748749771982, 2.736245541082907e-015, 0.7346748749771982, 10.00000000000001)
+SketchProjection_1 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchPoint_1.result())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchPoint_2.result())
+SketchLine_6 = Sketch_2.addLine(0.7346748749771982, 10.00000000000001, -19.2653251250228, 10.00000000000001)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_3 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchPoint_3.result())
+SketchLine_7 = Sketch_2.addLine(-19.2653251250228, 10.00000000000001, -19.2653251250228, 2.775557561562891e-015)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchProjection_4 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_4 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchPoint_4.result())
+SketchLine_8 = Sketch_2.addLine(-19.2653251250228, 2.775557561562891e-015, 0.7346748749771974, 3.386180225106727e-015)
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchLine_8.endPoint())
+Extrusion_2.setNestedSketch(Sketch_2)
+
+Extrusion_3 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"))
+SketchLine_9 = Sketch_3.addLine(36.86324678550901, 2.286454635368208e-015, 36.86324678550901, 10)
+SketchProjection_5 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_5 = SketchProjection_5.createdFeature()
+SketchConstraintCoincidence_13 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchPoint_5.result())
+SketchProjection_6 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_6 = SketchProjection_6.createdFeature()
+SketchConstraintCoincidence_14 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchPoint_6.result())
+SketchLine_10 = Sketch_3.addLine(36.86324678550901, 10, -3.136753214490995, 10)
+SketchConstraintCoincidence_15 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchProjection_7 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_7 = SketchProjection_7.createdFeature()
+SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchPoint_7.result())
+SketchLine_11 = Sketch_3.addLine(-3.136753214490995, 10, -3.136753214490995, 2.275957200481571e-015)
+SketchConstraintCoincidence_17 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchProjection_8 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_8 = SketchProjection_8.createdFeature()
+SketchConstraintCoincidence_18 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchPoint_8.result())
+SketchLine_12 = Sketch_3.addLine(-3.136753214490995, 2.275957200481571e-015, 36.86324678550902, 1.387778780781446e-015)
+SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchLine_12.endPoint())
+Extrusion_3.setNestedSketch(Sketch_3)
+
+Extrusion_4 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+SketchLine_13 = Sketch_4.addLine(22.60959895285982, 4.420942808558057e-016, 22.60959895285982, 10)
+SketchProjection_9 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_9 = SketchProjection_9.createdFeature()
+SketchConstraintCoincidence_21 = Sketch_4.setCoincident(SketchLine_13.startPoint(), SketchPoint_9.result())
+SketchProjection_10 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_10 = SketchProjection_10.createdFeature()
+SketchConstraintCoincidence_22 = Sketch_4.setCoincident(SketchLine_13.endPoint(), SketchPoint_10.result())
+SketchLine_14 = Sketch_4.addLine(22.60959895285982, 10, -7.390401047140179, 10)
+SketchConstraintCoincidence_23 = Sketch_4.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchProjection_11 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_11 = SketchProjection_11.createdFeature()
+SketchConstraintCoincidence_24 = Sketch_4.setCoincident(SketchLine_14.endPoint(), SketchPoint_11.result())
+SketchLine_15 = Sketch_4.addLine(-7.390401047140179, 10, -7.390401047140179, 8.881784197001252e-016)
+SketchConstraintCoincidence_25 = Sketch_4.setCoincident(SketchLine_14.endPoint(), SketchLine_15.startPoint())
+SketchProjection_12 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_12 = SketchProjection_12.createdFeature()
+SketchConstraintCoincidence_26 = Sketch_4.setCoincident(SketchLine_15.endPoint(), SketchPoint_12.result())
+SketchLine_16 = Sketch_4.addLine(-7.390401047140179, 8.881784197001252e-016, 22.60959895285983, 0)
+SketchConstraintCoincidence_27 = Sketch_4.setCoincident(SketchLine_15.endPoint(), SketchLine_16.startPoint())
+SketchConstraintCoincidence_28 = Sketch_4.setCoincident(SketchLine_13.startPoint(), SketchLine_16.endPoint())
+Extrusion_4.setNestedSketch(Sketch_4)
+
+Extrusion_5 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+SketchLine_17 = Sketch_5.addLine(-10.64977324988603, -1.185841873934692e-016, -10.64977324988603, -10)
+SketchProjection_13 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_13 = SketchProjection_13.createdFeature()
+SketchConstraintCoincidence_29 = Sketch_5.setCoincident(SketchLine_17.startPoint(), SketchPoint_13.result())
+SketchProjection_14 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_14 = SketchProjection_14.createdFeature()
+SketchConstraintCoincidence_30 = Sketch_5.setCoincident(SketchLine_17.endPoint(), SketchPoint_14.result())
+SketchLine_18 = Sketch_5.addLine(-10.64977324988603, -10, 39.35022675011398, -10)
+SketchConstraintCoincidence_31 = Sketch_5.setCoincident(SketchLine_17.endPoint(), SketchLine_18.startPoint())
+SketchProjection_15 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_15 = SketchProjection_15.createdFeature()
+SketchConstraintCoincidence_32 = Sketch_5.setCoincident(SketchLine_18.endPoint(), SketchPoint_15.result())
+SketchLine_19 = Sketch_5.addLine(39.35022675011398, -10, 39.35022675011398, 4.440892098500626e-016)
+SketchConstraintCoincidence_33 = Sketch_5.setCoincident(SketchLine_18.endPoint(), SketchLine_19.startPoint())
+SketchProjection_16 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_16 = SketchProjection_16.createdFeature()
+SketchConstraintCoincidence_34 = Sketch_5.setCoincident(SketchLine_19.endPoint(), SketchPoint_16.result())
+SketchLine_20 = Sketch_5.addLine(39.35022675011398, 4.440892098500626e-016, -10.64977324988603, 0)
+SketchConstraintCoincidence_35 = Sketch_5.setCoincident(SketchLine_19.endPoint(), SketchLine_20.startPoint())
+SketchConstraintCoincidence_36 = Sketch_5.setCoincident(SketchLine_17.startPoint(), SketchLine_20.endPoint())
+Extrusion_5.setNestedSketch(Sketch_5)
+model.do()
+model.end()
+
+# check volumes
+model.testResultsVolumes(Extrusion_2, [4000])
+model.testResultsVolumes(Extrusion_3, [3000])
+model.testResultsVolumes(Extrusion_4, [5000])
+model.testResultsVolumes(Extrusion_5, [2000])
+
+assert(model.checkPythonDump())
+
+# check volumes after dump and restore
+model.testResultsVolumes(Extrusion_2, [4000])
+model.testResultsVolumes(Extrusion_3, [3000])
+model.testResultsVolumes(Extrusion_4, [5000])
+model.testResultsVolumes(Extrusion_5, [2000])
index 6ec5968e51fb9224ed09312732217cb2f2526780..adfd8ebcc316eeaec98e351e605599b44e3e00ae 100644 (file)
@@ -95,19 +95,19 @@ aProjectedList = [("EDGE", "Sketch_1/Edge-SketchCircle_1_2"),
                   ("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"),
                   #
                   ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"),
-                  ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"),
+                  ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"),
                   ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_1"),
-                  ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"),
+                  ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"),
                   #
-                  ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1"),
-                  ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2"),
-                  ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3"),
+                  ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_3"),
+                  ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/Generated_Face_2"),
                   ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1"),
+                  ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3"),
                   #
                   ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"),
-                  ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"),
+                  ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"),
                   ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1"),
-                  ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1")
+                  ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1")
                   ]
 
 # Test projection to the same plane
@@ -129,12 +129,12 @@ Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To
 testProjections(Part_1_doc, Sketch_6, aProjectedList, aFailedIDs)
 
 # Test projection to orthogonal side face of the prism
-Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
 aFailedIDs = set([0, 1, 18, 20, 26, 28])
 testProjections(Part_1_doc, Sketch_7, aProjectedList, aFailedIDs)
 
 # Test projection to slope side face of the prism
-Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
 aFailedIDs = set([0, 1])
 testProjections(Part_1_doc, Sketch_8, aProjectedList, aFailedIDs)
 
diff --git a/src/SketchPlugin/Test/TestProjectionUpdate.py b/src/SketchPlugin/Test/TestProjectionUpdate.py
new file mode 100644 (file)
index 0000000..e3312d0
--- /dev/null
@@ -0,0 +1,42 @@
+## 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 there is no crash while changing the projecting feature
+"""
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(20, -50, 70, 50)
+model.do()
+
+Sketch_2 = model.addSketch(partSet, model.defaultPlane("YOZ"))
+SketchProjection_1 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s"), True)
+model.do()
+
+# change the feature projected (no crash expected)
+SketchProjection_1.setExternalFeature(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+model.do()
+
+model.end()
index 9521f1db16133c227038ec3b31774bb5de21e722..c8f79b464d7f1b696f4b4a56cf0b1e8fc69688cc 100644 (file)
@@ -243,7 +243,13 @@ void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& theP
     (myConstraint->data()->attribute(SketchPlugin_ConstraintAngle::LOCATION_TYPE_ID()));
   SketcherPrs_Tools::LocationType aLocationType = aLocAttr->isInitialized() ?
     (SketcherPrs_Tools::LocationType)(aLocAttr->value()) : SketcherPrs_Tools::LOCATION_AUTOMATIC;
-  updateArrows(myAspect, GetValue(), aTextSize, aLocationType);
+
+  double aRadius = myCenterPoint.Translated(
+    gp_Vec(myCenterPoint, myFirstPoint).Normalized()*aDist).Distance(myCenterPoint);
+  double anAngleValue = myValue.myDoubleValue;
+  double anAngleCircleLength = aRadius * anAngleValue * PI / 180.;
+
+  updateArrows(myAspect, anAngleCircleLength, aTextSize, aLocationType);
 
   AIS_AngleDimension::Compute(thePresentationManager, thePresentation, theMode);
 
@@ -275,7 +281,7 @@ void SketcherPrs_Angle::ComputeSelection(const Handle(SelectMgr_Selection)& aSel
     return;
   }
   }
-  SetSelToleranceForText2d(SketcherPrs_Tools::getTextHeight());
+  SetSelToleranceForText2d(SketcherPrs_Tools::getArrowSize()/5.);
   AIS_AngleDimension::ComputeSelection(aSelection, aMode);
 }
 
index 69ece0e8709d00810999da8df422b108f0a4d21d..8d7ea1581f67f9e353e856bedbe4a529db9f3f26 100644 (file)
@@ -139,7 +139,9 @@ void SketcherPrs_Coincident::SetColor(const Quantity_NameOfColor aCol)
 void SketcherPrs_Coincident::SetColor(const Quantity_Color &aCol)
 {
   hasOwnColor=Standard_True;
+#ifndef USE_OCCT_720
   myOwnColor=aCol;
+#endif
 }
 
 void SketcherPrs_Coincident::SetCustomColor(const std::vector<int>& theColor)
index 5f9b54cff59faad8698f26c9d2715c414c016ef8..12e9e1270ee0a6352d324ac84066a855f4c4a695 100644 (file)
@@ -311,6 +311,6 @@ void SketcherPrs_LengthDimension::ComputeSelection(const Handle(SelectMgr_Select
     return;
   }
   }
-  SetSelToleranceForText2d(SketcherPrs_Tools::getTextHeight());
+  SetSelToleranceForText2d(SketcherPrs_Tools::getArrowSize()/5.);
   AIS_LengthDimension::ComputeSelection(aSelection, aMode);
 }
index 31921298ba0424bf4a61a7eedc4fcded4f967873..21b6dacb1e0996ecf4cf0df9df4a860ebeaca6a5 100644 (file)
@@ -37,9 +37,9 @@
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintPerpendicular.h>
 
-#include <BRepExtrema_ExtPC.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <Geom_Curve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <TColGeom_SequenceOfCurve.hxx>
 #include <gp_Dir.hxx>
 
@@ -202,22 +202,11 @@ gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP)
       std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
 
     if (aCurve->isCircle()) {
-      GeomEdgePtr aEdgePtr(new GeomAPI_Edge(aShape));
-      GeomVertexPtr aVertexPtr(new GeomAPI_Vertex(theP.X(), theP.Y(), theP.Z()));
-      BRepExtrema_ExtPC aExtrema(aVertexPtr->impl<TopoDS_Vertex>(),
-                                 aEdgePtr->impl<TopoDS_Edge>());
-      int aNb = aExtrema.NbExt();
-      if (aNb > 0) {
-        for (int i = 1; i <= aNb; i++) {
-          if (aExtrema.IsMin(i)) {
-            double aParam = aExtrema.Parameter(i);
-            Handle(Geom_Curve) aCurv = aCurve->impl<Handle_Geom_Curve>();
-            gp_Pnt aP;
-            aCurv->D1(aParam, aP, aVec);
-            break;
-          }
-        }
-      }
+      Handle(Geom_Curve) aCurv = aCurve->impl<Handle_Geom_Curve>();
+      GeomAPI_ProjectPointOnCurve anExtr(theP, aCurv);
+      double aParam = anExtr.LowerDistanceParameter();
+      gp_Pnt aP;
+      aCurv->D1(aParam, aP, aVec);
     } else {
       GeomPointPtr aPnt1 = aCurve->getPoint(aCurve->endParam());
       GeomPointPtr aPnt2 = aCurve->getPoint(aCurve->startParam());
index 3381d5d63a81921dcb339e33a31362801fcd7b7f..8fa795e90b4e94c4d29122700ac908c701c1476a 100644 (file)
@@ -202,6 +202,6 @@ void SketcherPrs_Radius::ComputeSelection(const Handle(SelectMgr_Selection)& aSe
     return;
   }
   }
-  SetSelToleranceForText2d(SketcherPrs_Tools::getTextHeight());
+  SetSelToleranceForText2d(SketcherPrs_Tools::getArrowSize()/5.);
   AIS_RadiusDimension::ComputeSelection(aSelection, aMode);
 }
index 049f6758c4dfcb19b938a68c3d2049323eba89da..9a92cc56348bb62aa714ffb08d6483f8a8d41f77 100644 (file)
@@ -35,7 +35,7 @@ ADD_DEFINITIONS(-DXAO_EXPORTS ${CAS_DEFINITIONS})
 # libraries to link to
 SET(PROJECT_LIBRARIES
   ${LIBXML2_LIBRARIES}
-  ${CAS_TKBRep} ${CAS_TKTopAlgo} ${CAS_TKG2d}
+  ${CAS_TKBRep} ${CAS_TKTopAlgo} ${CAS_TKG2d} ${CAS_TKG3d}
   )
 
 # --- headers ---
index 1bc373d68798e5fb488e122c1bef4ce13db68f87..7f0fe59ff7d9dd72c9f9f147f36063391d4f495a 100644 (file)
@@ -44,12 +44,14 @@ SET(PROJECT_HEADERS
     XGUI_ModuleConnector.h
     XGUI_ObjectsBrowser.h
     XGUI_OperationMgr.h
+    XGUI_PropertyDialog.h
     XGUI_PropertyPanel.h
     XGUI_QtEvents.h
     XGUI_SalomeConnector.h
     XGUI_Selection.h
     XGUI_SelectionMgr.h
     XGUI_Tools.h
+    XGUI_TransparencyWidget.h
     XGUI_ViewerProxy.h
     XGUI_Workshop.h
     XGUI_WorkshopListener.h
@@ -68,8 +70,10 @@ SET(PROJECT_MOC_HEADERS
     XGUI_ModuleConnector.h
     XGUI_ObjectsBrowser.h
     XGUI_OperationMgr.h
+    XGUI_PropertyDialog.h
     XGUI_PropertyPanel.h
     XGUI_SelectionMgr.h
+    XGUI_TransparencyWidget.h
     XGUI_ViewerProxy.h
     XGUI_Workshop.h
     XGUI_WorkshopListener.h
@@ -95,12 +99,14 @@ SET(PROJECT_SOURCES
     XGUI_ModuleConnector.cpp
     XGUI_ObjectsBrowser.cpp
     XGUI_OperationMgr.cpp
+    XGUI_PropertyDialog.cpp
     XGUI_PropertyPanel.cpp
     XGUI_QtEvents.cpp
     XGUI_SalomeConnector.cpp
     XGUI_Selection.cpp
     XGUI_SelectionMgr.cpp
     XGUI_Tools.cpp
+    XGUI_TransparencyWidget.cpp
     XGUI_ViewerProxy.cpp
     XGUI_Workshop.cpp
     XGUI_WorkshopListener.cpp
@@ -158,7 +164,7 @@ SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESO
 #SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESOURCES})
 SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES} ${PROJECT_RESOURCES} ${PREFERENCES_XML})
 
-ADD_DEFINITIONS( -DXGUI_EXPORTS ${CAS_DEFINITIONS} )
+ADD_DEFINITIONS( -DXGUI_EXPORTS ${CAS_DEFINITIONS} -D_CRT_SECURE_NO_WARNINGS)
 
 SET(PROJECT_INCLUDES
     ${PROJECT_SOURCE_DIR}/src/Events
index d0ee1667c6196630a1f434424ef9febada2dfc60..4d97e46d0dd67020cd2760875188e42cbb54a1b2 100644 (file)
@@ -47,6 +47,8 @@
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultField.h>
+#include <ModelAPI_Folder.h>
+#include <ModelAPI_AttributeReference.h>
 
 #include <Config_DataModelReader.h>
 
@@ -66,7 +68,7 @@
 XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
     : QObject(theParent),
       myWorkshop(theParent),
-      mySeparator(0)
+      mySeparator1(0), mySeparator2(0), mySeparator3(0)
 {
 }
 
@@ -107,6 +109,12 @@ void XGUI_ContextMenuMgr::createActions()
   aAction = ModuleBase_Tools::createAction(QIcon(""), tr("Deflection..."), aDesktop);
   addAction("DEFLECTION_CMD", aAction);
 
+#ifdef USE_TRANSPARENCY
+  aAction = ModuleBase_Tools::createAction(QIcon(":pictures/transparency.png"),
+                                           tr("Transparency..."), aDesktop);
+  addAction("TRANSPARENCY_CMD", aAction);
+#endif
+
   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil.png"), tr("Show"), aDesktop);
   addAction("SHOW_CMD", aAction);
 
@@ -129,8 +137,14 @@ void XGUI_ContextMenuMgr::createActions()
                                            aDesktop);
   addAction("WIREFRAME_CMD", aAction);
 
-  mySeparator = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
-  mySeparator->setSeparator(true);
+  mySeparator1 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+  mySeparator1->setSeparator(true);
+
+  mySeparator2 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+  mySeparator2->setSeparator(true);
+
+  mySeparator3 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+  mySeparator3->setSeparator(true);
 
   //mySelectActions = new QActionGroup(this);
   //mySelectActions->setExclusive(true);
@@ -174,6 +188,27 @@ void XGUI_ContextMenuMgr::createActions()
   addAction("TINSPECTOR_VIEW", aAction);
 #endif
 
+  // Features folders actions
+  aAction = ModuleBase_Tools::createAction(QIcon(":pictures/create_folder.png"),
+                                           tr("Insert a folder before"), aDesktop);
+  addAction("INSERT_FOLDER_CMD", aAction);
+
+  aAction = ModuleBase_Tools::createAction(QIcon(":pictures/insert_folder_before.png"),
+                                           tr("Move into the previous folder"), aDesktop);
+  addAction("ADD_TO_FOLDER_BEFORE_CMD", aAction);
+
+  aAction = ModuleBase_Tools::createAction(QIcon(":pictures/insert_folder_after.png"),
+                                           tr("Move into the next folder"), aDesktop);
+  addAction("ADD_TO_FOLDER_AFTER_CMD", aAction);
+
+  aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_out_before.png"),
+                                           tr("Move out before the folder"), aDesktop);
+  addAction("ADD_OUT_FOLDER_BEFORE_CMD", aAction);
+
+  aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_out_after.png"),
+                                           tr("Move out after the folder"), aDesktop);
+  addAction("ADD_OUT_FOLDER_AFTER_CMD", aAction);
+
   buildObjBrowserMenu();
   buildViewerMenu();
 }
@@ -257,10 +292,11 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
     bool hasParameter = false;
     bool hasCompositeOwner = false;
     bool hasResultInHistory = false;
+    bool hasFolder = false;
     ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter,
-                                   hasCompositeOwner, hasResultInHistory);
+                                   hasCompositeOwner, hasResultInHistory, hasFolder);
     //Process Feature
-    if (aSelected == 1) {
+    if (aSelected == 1) { // single selection
       ObjectPtr aObject = aObjects.first();
       if (aObject) {
         if (hasResult && myWorkshop->canBeShaded(aObject)) {
@@ -301,7 +337,8 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
                                                   (hasFeature || hasParameter));
         }
       }
-    } else {
+      // end single selection
+    } else { // multiselection
       // parameter is commented because the actions are not in the list of result parameter actions
       if (hasResult /*&& (!hasParameter)*/) {
         action("SHOW_CMD")->setEnabled(true);
@@ -310,7 +347,98 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
         action("SHADING_CMD")->setEnabled(true);
         action("WIREFRAME_CMD")->setEnabled(true);
       }
-    }
+    } // end multiselection
+
+    // Check folder management commands state if only features are selected
+    if ((!hasResult) && hasFeature && (!hasParameter) && (!hasCompositeOwner) &&
+      (!hasResultInHistory) && (!hasFolder)) {
+      std::list<FeaturePtr> aFeatures = aSelMgr->getSelectedFeatures();
+      if (aFeatures.size() > 0) { // Check that features do not include Parts
+        QModelIndexList aIndexes = aSelMgr->selection()->selectedIndexes();
+        QModelIndex aFirstIdx = aIndexes.first();
+        QModelIndex aLastIdx = aIndexes.last();
+        QModelIndex aParentIdx = aFirstIdx.parent();
+
+        // if all selected are from the same level
+        bool isSameParent = true;
+        foreach(QModelIndex aIdx, aIndexes) {
+          if (aIdx.parent() != aParentIdx) {
+            isSameParent = false;
+            break;
+          }
+        }
+        if (isSameParent) {
+          // Check is selection continuous
+          XGUI_DataModel* aModel = myWorkshop->objectBrowser()->dataModel();
+          DocumentPtr aDoc = aMgr->activeDocument();
+          std::list<FeaturePtr> aFeatures = aSelMgr->getSelectedFeatures();
+
+          bool isContinuos = true;
+          if (aSelected > 1) {
+            int aId = -1;
+            foreach(FeaturePtr aF, aFeatures) {
+              if (aId == -1)
+                aId = aDoc->index(aF);
+              else {
+                aId++;
+                if (aId != aDoc->index(aF)) {
+                  isContinuos = false;
+                  break;
+                }
+              }
+            }
+          }
+          if (isContinuos) {
+            ObjectPtr aDataObj = aModel->object(aParentIdx);
+
+            ObjectPtr aPrevObj;
+            if (aFirstIdx.row() > 0) {
+              QModelIndex aPrevIdx = aFirstIdx.sibling(aFirstIdx.row() - 1, 0);
+              aPrevObj = aModel->object(aPrevIdx);
+            }
+
+            ObjectPtr aNextObj;
+            if (aLastIdx.row() < (aModel->rowCount(aParentIdx) - 1)) {
+              QModelIndex aNextIdx = aFirstIdx.sibling(aLastIdx.row() + 1, 0);
+              aNextObj = aModel->object(aNextIdx);
+            }
+
+            bool isPrevFolder = (aPrevObj.get() &&
+              (aPrevObj->groupName() == ModelAPI_Folder::group()));
+            bool isNextFolder = (aNextObj.get() &&
+              (aNextObj->groupName() == ModelAPI_Folder::group()));
+            bool isInFolder = (aDataObj.get() &&
+              (aDataObj->groupName() == ModelAPI_Folder::group()));
+            bool isOutsideFolder = !isInFolder;
+
+            bool hasFirst = false;
+            bool hasLast = false;
+            if (isInFolder) {
+              FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aDataObj);
+              FeaturePtr aFirstFeatureInFolder;
+              AttributeReferencePtr aFirstFeatAttr =
+                  aFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+              if (aFirstFeatAttr)
+                aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+              hasFirst = (aFirstFeatureInFolder == aFeatures.front());
+
+              FeaturePtr aLastFeatureInFolder;
+              AttributeReferencePtr aLastFeatAttr =
+                  aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+              if (aLastFeatAttr)
+                aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+              hasLast = (aLastFeatureInFolder == aFeatures.back());
+            }
+            action("INSERT_FOLDER_CMD")->setEnabled(isOutsideFolder);
+            action("ADD_TO_FOLDER_BEFORE_CMD")->setEnabled(isOutsideFolder && isPrevFolder);
+            action("ADD_TO_FOLDER_AFTER_CMD")->setEnabled(isOutsideFolder && isNextFolder);
+            action("ADD_OUT_FOLDER_BEFORE_CMD")->setEnabled(isInFolder && hasFirst);
+            action("ADD_OUT_FOLDER_AFTER_CMD")->setEnabled(isInFolder && hasLast);
+          }
+        }
+      }
+    } // end folder management commands
+
     bool allActive = true;
     foreach( ObjectPtr aObject, aObjects )
       if( aMgr->activeDocument() != aObject->document() )  {
@@ -326,7 +454,7 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
 
     action("SHOW_RESULTS_CMD")->setEnabled(hasFeature);
     action("SHOW_FEATURE_CMD")->setEnabled(hasResult && hasResultInHistory);
-  }
+  } // end selection processing
 
   // Show/Hide command has to be disabled for objects from non active document
   bool aDeactivate = false;
@@ -346,12 +474,11 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
     action("SHOW_ONLY_CMD")->setEnabled(false);
   }
 
-  if (myWorkshop->canChangeColor())
-    action("COLOR_CMD")->setEnabled(true);
-
-  if (myWorkshop->canChangeDeflection())
-    action("DEFLECTION_CMD")->setEnabled(true);
-
+  action("COLOR_CMD")->setEnabled(myWorkshop->canChangeProperty("COLOR_CMD"));
+  action("DEFLECTION_CMD")->setEnabled(myWorkshop->canChangeProperty("DEFLECTION_CMD"));
+#ifdef USE_TRANSPARENCY
+  action("TRANSPARENCY_CMD")->setEnabled(myWorkshop->canChangeProperty("TRANSPARENCY_CMD"));
+#endif
   #ifdef _DEBUG
     #ifdef TINSPECTOR
       action("TINSPECTOR_VIEW")->setEnabled(true);
@@ -449,12 +576,17 @@ void XGUI_ContextMenuMgr::updateViewerMenu()
   if (aModule)
     aModule->updateViewerMenu(myActions);
 
-  if (myWorkshop->canChangeColor())
+  if (myWorkshop->canChangeProperty("COLOR_CMD"))
     action("COLOR_CMD")->setEnabled(true);
 
-  if (myWorkshop->canChangeDeflection())
+  if (myWorkshop->canChangeProperty("DEFLECTION_CMD"))
     action("DEFLECTION_CMD")->setEnabled(true);
 
+#ifdef USE_TRANSPARENCY
+  if (myWorkshop->canChangeProperty("TRANSPARENCY_CMD"))
+    action("TRANSPARENCY_CMD")->setEnabled(true);
+#endif
+
   action("DELETE_CMD")->setEnabled(true);
 }
 
@@ -482,10 +614,13 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu()
   aList.append(action("SHOW_CMD"));
   aList.append(action("HIDE_CMD"));
   aList.append(action("SHOW_ONLY_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator1);
   aList.append(action("RENAME_CMD"));
   aList.append(action("COLOR_CMD"));
   aList.append(action("DEFLECTION_CMD"));
+#ifdef USE_TRANSPARENCY
+  aList.append(action("TRANSPARENCY_CMD"));
+#endif
   aList.append(action("SHOW_FEATURE_CMD"));
   myObjBrowserMenus[ModelAPI_ResultConstruction::group()] = aList;
 
@@ -494,15 +629,18 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu()
   aList.clear();
   aList.append(action("WIREFRAME_CMD"));
   aList.append(action("SHADING_CMD"));
-  aList.append(mySeparator); // this separator is not shown as this action is added after show only
+  aList.append(mySeparator1); // this separator is not shown as this action is added after show only
   // qt list container contains only one instance of the same action
   aList.append(action("SHOW_CMD"));
   aList.append(action("HIDE_CMD"));
   aList.append(action("SHOW_ONLY_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator2);
   aList.append(action("RENAME_CMD"));
   aList.append(action("COLOR_CMD"));
   aList.append(action("DEFLECTION_CMD"));
+#ifdef USE_TRANSPARENCY
+  aList.append(action("TRANSPARENCY_CMD"));
+#endif
   aList.append(action("SHOW_FEATURE_CMD"));
   myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList;
   // Group menu
@@ -516,18 +654,30 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu()
   aList.append(action("RENAME_CMD"));
   aList.append(action("SHOW_RESULTS_CMD"));
   aList.append(action("MOVE_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator1);
+  aList.append(action("INSERT_FOLDER_CMD"));
+  aList.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
+  aList.append(action("ADD_TO_FOLDER_AFTER_CMD"));
+  aList.append(mySeparator2);
+  aList.append(action("ADD_OUT_FOLDER_BEFORE_CMD"));
+  aList.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
+  aList.append(mySeparator3);
   aList.append(action("CLEAN_HISTORY_CMD"));
   aList.append(action("DELETE_CMD"));
   myObjBrowserMenus[ModelAPI_Feature::group()] = aList;
 
   aList.clear();
   aList.append(action("RENAME_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator1);
   aList.append(action("CLEAN_HISTORY_CMD"));
   aList.append(action("DELETE_CMD"));
   myObjBrowserMenus[ModelAPI_ResultParameter::group()] = aList;
   //-------------------------------------
+
+  aList.clear();
+  aList.append(action("DELETE_CMD"));
+  myObjBrowserMenus[ModelAPI_Folder::group()] = aList;
+
 }
 
 void XGUI_ContextMenuMgr::buildViewerMenu()
@@ -536,9 +686,12 @@ void XGUI_ContextMenuMgr::buildViewerMenu()
   // Result construction menu
   aList.append(action("HIDE_CMD"));
   aList.append(action("SHOW_ONLY_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator1);
   aList.append(action("COLOR_CMD"));
   aList.append(action("DEFLECTION_CMD"));
+#ifdef USE_TRANSPARENCY
+  aList.append(action("TRANSPARENCY_CMD"));
+#endif
   myViewerMenu[ModelAPI_ResultConstruction::group()] = aList;
   // Result part menu
   myViewerMenu[ModelAPI_ResultPart::group()] = aList;
@@ -547,12 +700,15 @@ void XGUI_ContextMenuMgr::buildViewerMenu()
   aList.clear();
   aList.append(action("WIREFRAME_CMD"));
   aList.append(action("SHADING_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator1);
   aList.append(action("HIDE_CMD"));
   aList.append(action("SHOW_ONLY_CMD"));
-  aList.append(mySeparator);
+  aList.append(mySeparator2);
   aList.append(action("COLOR_CMD"));
   aList.append(action("DEFLECTION_CMD"));
+#ifdef USE_TRANSPARENCY
+  aList.append(action("TRANSPARENCY_CMD"));
+#endif
   myViewerMenu[ModelAPI_ResultBody::group()] = aList;
   // Group menu
   myViewerMenu[ModelAPI_ResultGroup::group()] = aList;
@@ -581,15 +737,22 @@ void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const
   } else if (aSelected > 1) {
       aActions.append(action("WIREFRAME_CMD"));
       aActions.append(action("SHADING_CMD"));
-      aActions.append(mySeparator);
+      aActions.append(mySeparator1);
       aActions.append(action("SHOW_CMD"));
       aActions.append(action("HIDE_CMD"));
       aActions.append(action("SHOW_ONLY_CMD"));
-      aActions.append(mySeparator);
+      aActions.append(mySeparator2);
+      aActions.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
+      aActions.append(action("ADD_TO_FOLDER_AFTER_CMD"));
+      aActions.append(action("ADD_OUT_FOLDER_BEFORE_CMD"));
+      aActions.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
+      aActions.append(mySeparator3);
       //aActions.append(action("MOVE_CMD"));
       aActions.append(action("COLOR_CMD"));
       aActions.append(action("DEFLECTION_CMD"));
-
+#ifdef USE_TRANSPARENCY
+      aActions.append(action("TRANSPARENCY_CMD"));
+#endif
       aActions.append(action("CLEAN_HISTORY_CMD"));
       aActions.append(action("DELETE_CMD"));
   }
@@ -645,7 +808,9 @@ void XGUI_ContextMenuMgr::addViewerMenu(QMenu* theMenu) const
   aActions.append(action("HIDEALL_CMD"));
   aActions.append(action("COLOR_CMD"));
   aActions.append(action("DEFLECTION_CMD"));
-
+#ifdef USE_TRANSPARENCY
+  aActions.append(action("TRANSPARENCY_CMD"));
+#endif
   theMenu->addActions(aActions);
 
   QMap<int, QAction*> aMenuActions;
index 7513d5e25199d57206bb7c3e2eeafc29a003f6a4..97a8584dfe0b8e4e03f6f2048cb313eb5906e714 100644 (file)
@@ -142,7 +142,9 @@ signals:
 
   //QActionGroup* mySelectActions;
 
-  QAction* mySeparator;
+  QAction* mySeparator1;
+  QAction* mySeparator2;
+  QAction* mySeparator3;
 };
 
 #endif
index cc12b80903cb17464d15ce58e17164f45946a333..fe9fbfcdcca1d35c1e1f0cc282f3f7c7fe78fa0c 100644 (file)
@@ -42,7 +42,7 @@
 double getDeflection(const ResultPtr& theResult)
 {
   double aDeflection = -1;
-  // get color from the attribute of the result
+  // get deflection from the attribute of the result
   if (theResult.get() != NULL &&
       theResult->data()->attribute(ModelAPI_Result::DEFLECTION_ID()).get() != NULL) {
     AttributeDoublePtr aDoubleAttr = theResult->data()->real(ModelAPI_Result::DEFLECTION_ID());
@@ -118,6 +118,27 @@ double XGUI_CustomPrs::getDefaultDeflection(const ObjectPtr& theObject)
   return aDeflection;
 }
 
+double getTransparency(const ResultPtr& theResult)
+{
+  double aDeflection = -1;
+  // get transparency from the attribute of the result
+  if (theResult.get() != NULL &&
+      theResult->data()->attribute(ModelAPI_Result::TRANSPARENCY_ID()).get() != NULL) {
+    AttributeDoublePtr aDoubleAttr = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID());
+    if (aDoubleAttr.get() && aDoubleAttr->isInitialized()) {
+      double aValue = aDoubleAttr->value();
+      if (aValue > 0) /// zero value should not be used as a transparency(previous studies)
+        aDeflection = aDoubleAttr->value();
+    }
+  }
+  return aDeflection;
+}
+
+double getDefaultTransparency(const ResultPtr& theResult)
+{
+  return 0;
+}
+
 XGUI_CustomPrs::XGUI_CustomPrs(XGUI_Workshop* theWorkshop)
 : myWorkshop(theWorkshop)
 {
@@ -138,6 +159,14 @@ double XGUI_CustomPrs::getResultDeflection(const ResultPtr& theResult)
   return aDeflection;
 }
 
+double XGUI_CustomPrs::getResultTransparency(const ResultPtr& theResult)
+{
+  double aTransparency = getTransparency(theResult);
+  if (aTransparency < 0)
+    aTransparency = getDefaultTransparency(theResult);
+  return aTransparency;
+}
+
 bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
                                            std::shared_ptr<GeomAPI_ICustomPrs> theCustomPrs)
 {
@@ -158,6 +187,8 @@ bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr the
     aCustomized = !aColor.empty() && thePrs->setColor(aColor[0], aColor[1], aColor[2]);
 
     aCustomized = thePrs->setDeflection(getResultDeflection(theResult)) | aCustomized;
+
+    aCustomized = thePrs->setTransparency(getResultTransparency(theResult)) | aCustomized;
   }
   ModuleBase_IModule* aModule = myWorkshop->module();
   aCustomized = aModule->customisePresentation(theResult, thePrs, theCustomPrs) || aCustomized;
index 7b5e2e1845a516c0ef672da90419b808334d7334..6a2af267c0e7d73b876b162f7aa9a22c2bb439c0 100644 (file)
@@ -55,6 +55,11 @@ public:
   /// \return theDeflection a real value
   static double getResultDeflection(const ResultPtr& theResult);
 
+  /// Returns transparency of a result object
+  /// \param theResult a result object
+  /// \return theTransparency a real value
+  static double getResultTransparency(const ResultPtr& theResult);
+
   /// Returns the default object color. It obtains colorConfigInfo of the object
   /// and find it in preferences. If there are no this color in preference and an empty
   /// color is interpreted as invalid, it shows error message
index 746b33e03ec1f2b8a4530c33cb27996a186c01cf..d428a2c501986816457ec569efff57f10207b880 100644 (file)
@@ -35,6 +35,8 @@
 #include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_ResultField.h>
 #include <ModelAPI_Tools.h>
+#include <ModelAPI_Folder.h>
+#include <ModelAPI_AttributeReference.h>
 
 #include <Config_FeatureMessage.h>
 #include <Config_DataModelReader.h>
@@ -73,7 +75,10 @@ ResultPartPtr getPartResult(ModelAPI_Object* theObj)
 /// Returns pointer on document if the given object is document object
 ModelAPI_Document* getSubDocument(void* theObj)
 {
-  ModelAPI_Document* aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+  ModelAPI_Document* aDoc = 0;
+  try {
+    aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+  } catch(...) {}
   return aDoc;
 }
 
@@ -141,7 +146,7 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
         // Insert new object
         int aRow = aRootDoc->size(aObjType) - 1;
         if (aRow != -1) {
-          if (aObjType == aRootType) {
+          if ((aObjType == aRootType) || (aObjType == ModelAPI_Folder::group())) {
             insertRow(aRow + aNbFolders + 1);
           } else {
             int aFolderId = myXMLReader->rootFolderId(aObjType);
@@ -165,10 +170,10 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
               }
             }
          }
-          int aRow = aDoc->index(aObject);
+          int aRow = aDoc->index(aObject, true);
           if (aRow != -1) {
             int aNbSubFolders = foldersCount(aDoc.get());
-            if (aObjType == aSubType) {
+            if ((aObjType == aSubType) || (aObjType == ModelAPI_Folder::group())) {
               // List of objects under document root
               insertRow(aRow + aNbSubFolders, aDocRoot);
             } else {
@@ -215,8 +220,8 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
     for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) {
       std::string aGroup = (*aIt);
       if (aDoc == aRootDoc) {  // If root objects
-        int aRow = aRootDoc->size(aGroup);
-        if (aGroup == aRootType) {
+        int aRow = aRootDoc->size(aGroup, true);
+        if ((aGroup == aRootType) || (aGroup == ModelAPI_Folder::group())) {
           // Process root folder
           removeRow(aRow + aNbFolders);
           rebuildBranch(aNbFolders, aRow);
@@ -232,7 +237,7 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
         // Check that some folders could erased
         QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
         foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
-          if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup) == 0)) {
+          if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup, true) == 0)) {
             // Appears first object in folder which can not be shown empty
             removeRow(myXMLReader->rootFolderId(aGroup));
             removeShownFolder(aRootDoc, aNotEmptyFolder);
@@ -244,9 +249,9 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
         // Remove row for sub-document
         QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0);
         if (aDocRoot.isValid()) {
-          int aRow = aDoc->size(aGroup);
+          int aRow = aDoc->size(aGroup, true);
           int aNbSubFolders = foldersCount(aDoc.get());
-          if (aGroup == aSubType) {
+          if ((aGroup == aSubType) || (aGroup == ModelAPI_Folder::group())) {
             // List of objects under document root
             removeRow(aRow + aNbSubFolders, aDocRoot);
             rebuildBranch(aNbSubFolders, aRow, aDocRoot);
@@ -261,7 +266,7 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
           }
           // Check that some folders could disappear
           QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
-          int aSize = aDoc->size(aGroup);
+          int aSize = aDoc->size(aGroup, true);
           foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
             if ((aNotEmptyFolder.toStdString() == aGroup) && (aSize == 0)) {
               // Appears first object in folder which can not be shown empty
@@ -283,7 +288,6 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
     std::set<ObjectPtr> aObjects = aUpdMsg->objects();
 
     std::set<ObjectPtr>::const_iterator aIt;
-    std::string aObjType;
     for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
       ObjectPtr aObject = (*aIt);
       if (aObject->data()->isValid()) {
@@ -295,9 +299,13 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
             QModelIndex aIndex = objectIndex(aResult, 0);
             removeRows(0, aResult->stepsSize(), aIndex);
         } else {
-          QModelIndex aIndex = objectIndex(aObject, 0);
-          if (aIndex.isValid()) {
-            emit dataChanged(aIndex, aIndex);
+          if (aObject->groupName() == ModelAPI_Folder::group()) {
+            rebuildDataTree();
+          } else {
+            QModelIndex aIndex = objectIndex(aObject, 0);
+            if (aIndex.isValid()) {
+              emit dataChanged(aIndex, aIndex);
+            }
           }
         }
       } else {
@@ -383,7 +391,7 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn
 {
   std::string aType = theObject->groupName();
   DocumentPtr aDoc = theObject->document();
-  int aRow = aDoc->index(theObject);
+  int aRow = aDoc->index(theObject, true);
   if (aRow == -1) {
     // it could be a part of complex object
     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
@@ -397,6 +405,10 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn
           }
         }
       }
+      int aFRow = -1;
+      FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow);
+      if (aFolder.get())
+        aRow = aFRow;
     } else {
       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
       if (aResult.get()) {
@@ -413,10 +425,11 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn
   }
   SessionPtr aSession = ModelAPI_Session::get();
   DocumentPtr aRootDoc = aSession->moduleDocument();
-  if (aDoc == aRootDoc && myXMLReader->rootType() == aType) {
+  if (aDoc == aRootDoc &&
+    ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) {
     // The object from root document
     aRow += foldersCount();
-  } else if (myXMLReader->subType() == aType) {
+  } else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) {
     // The object from sub document
     aRow += foldersCount(aDoc.get());
   }
@@ -497,14 +510,13 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
         }
       }
     } else {
-      ModelAPI_Object* aObj =
-        dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
+      ObjectPtr aObj = object(theIndex);
       if (aObj) {
         switch (theRole) {
         case Qt::DisplayRole:
           {
             if (aObj->groupName() == ModelAPI_ResultParameter::group()) {
-              ModelAPI_ResultParameter* aParam = dynamic_cast<ModelAPI_ResultParameter*>(aObj);
+              ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObj);
               AttributeDoublePtr aValueAttribute =
                 aParam->data()->real(ModelAPI_ResultParameter::VALUE());
               QString aVal = QString::number(aValueAttribute->value());
@@ -513,7 +525,7 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
             }
             QString aSuffix;
             if (aObj->groupName() == myXMLReader->subType()) {
-              ResultPartPtr aPartRes = getPartResult(aObj);
+              ResultPartPtr aPartRes = getPartResult(aObj.get());
               if (aPartRes.get()) {
                 if (aPartRes->partDoc().get() == NULL)
                   aSuffix = " (Not loaded)";
@@ -522,7 +534,12 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
             return aObj->data()->name().c_str() + aSuffix;
           }
         case Qt::DecorationRole:
-          return ModuleBase_IconFactory::get()->getIcon(object(theIndex));
+          {
+            if (aObj->groupName() == ModelAPI_Folder::group())
+              return QIcon(":pictures/features_folder.png");
+            else
+              return ModuleBase_IconFactory::get()->getIcon(aObj);
+          }
         }
       } else {
         switch (theRole) {
@@ -564,7 +581,7 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
     int aNbItems = 0;
     std::string aType = myXMLReader->rootType();
     if (!aType.empty())
-      aNbItems = aRootDoc->size(aType);
+      aNbItems = aRootDoc->size(aType, true);
     return aNbFolders + aNbItems;
   }
 
@@ -601,7 +618,7 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
         int aNbSubItems = 0;
         std::string aSubType = myXMLReader->subType();
         if (!aSubType.empty())
-          aNbSubItems = aSubDoc->size(aSubType);
+          aNbSubItems = aSubDoc->size(aSubType, true);
         return aNbSubItems + aNbSubFolders;
       } else {
         // Check for composite object
@@ -614,6 +631,9 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
         ModelAPI_ResultField* aFieldRes = dynamic_cast<ModelAPI_ResultField*>(aObj);
         if (aFieldRes)
           return aFieldRes->stepsSize();
+        ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aObj);
+        if (aFolder)
+          return getNumberOfFolderItems(aFolder);
       }
     }
   }
@@ -641,8 +661,8 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &
     else { // return object under root index
       std::string aType = myXMLReader->rootType();
       int aObjId = theRow - aNbFolders;
-      if (aObjId < aRootDoc->size(aType)) {
-        ObjectPtr aObj = aRootDoc->object(aType, aObjId);
+      if (aObjId < aRootDoc->size(aType, true)) {
+        ObjectPtr aObj = aRootDoc->object(aType, aObjId, true);
         aIndex = objectIndex(aObj, theColumn);
       }
     }
@@ -652,7 +672,7 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &
     if (aId == 0) { // return object index inside of first level of folders
       std::string aType = myXMLReader->rootFolderType(aParentPos);
       if (theRow < aRootDoc->size(aType)) {
-        ObjectPtr aObj = aRootDoc->object(aType, theRow);
+        ObjectPtr aObj = aRootDoc->object(aType, theRow, true);
         aIndex = objectIndex(aObj, theColumn);
       }
     } else {
@@ -685,7 +705,7 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &
           } else {
             // this is an object under sub document root
             std::string aType = myXMLReader->subType();
-            ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders);
+            ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders, true);
             aIndex = objectIndex(aObj, theColumn);
           }
         } else {
@@ -704,6 +724,11 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &
                 dynamic_cast<ModelAPI_ResultField*>(aParentObj);
               if (aFieldRes) {
                 aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow));
+              } else {
+                ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aParentObj);
+                ObjectPtr aObj = getObjectInFolder(aFolder, theRow);
+                if (aObj.get())
+                  aIndex = objectIndex(aObj, theColumn);
               }
             }
           }
@@ -734,7 +759,7 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
     }
     ObjectPtr aObj = object(theIndex);
     if (!aObj.get()) {
-      // It can b e a step of a field
+      // It can be a step of a field
       ModelAPI_ResultField::ModelAPI_FieldStep* aStep =
         dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
         ((ModelAPI_Entity*)theIndex.internalPointer());
@@ -760,6 +785,11 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
       if (aCompFea.get()) {
         return objectIndex(aCompFea);
       }
+      DocumentPtr aDoc = aFeature->document();
+      int aRow;
+      FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow);
+      if (aFolder.get())
+        return objectIndex(aFolder);
     }
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
     if (aResult.get()) {
@@ -773,7 +803,7 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
     DocumentPtr aRootDoc = aSession->moduleDocument();
     DocumentPtr aSubDoc = aObj->document();
     if (aSubDoc == aRootDoc) {
-      if (aType == myXMLReader->rootType())
+      if ((aType == myXMLReader->rootType()) || (aType == ModelAPI_Folder::group()))
         return QModelIndex();
       else {
         // return first level of folder index
@@ -782,7 +812,7 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
         return createIndex(aFolderId, 1, (void*)Q_NULLPTR);
       }
     } else {
-      if (aType == myXMLReader->subType())
+      if ((aType == myXMLReader->subType()) || (aType == ModelAPI_Folder::group()))
         return findDocumentRootIndex(aSubDoc.get());
       else {
         // return first level of folder index
@@ -912,11 +942,11 @@ QModelIndex
       }
     }
   } else { // If document is attached to feature
-    int aNb = aRootDoc->size(ModelAPI_Feature::group());
+    int aNb = aRootDoc->size(ModelAPI_Feature::group(), true);
     ObjectPtr aObj;
     ResultPartPtr aPartRes;
     for (int i = 0; i < aNb; i++) {
-      aObj = aRootDoc->object(ModelAPI_Feature::group(), i);
+      aObj = aRootDoc->object(ModelAPI_Feature::group(), i, true);
       aPartRes = getPartResult(aObj.get());
       if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
         int aRow = i;
@@ -1089,6 +1119,8 @@ XGUI_DataModel::VisibilityState
 
   ObjectPtr aObj = object(theIndex);
   if (aObj.get()) {
+    if (aObj->groupName() == ModelAPI_ResultParameter::group())
+      return NoneState;
     ResultPtr aResObj = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
     if (aResObj.get()) {
       XGUI_Displayer* aDisplayer = myWorkshop->displayer();
@@ -1117,3 +1149,45 @@ XGUI_DataModel::VisibilityState
   }
   return NoneState;
 }
+
+
+int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const
+{
+  DocumentPtr aDoc = theFolder->document();
+
+  FeaturePtr aFirstFeatureInFolder;
+  AttributeReferencePtr aFirstFeatAttr =
+      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  if (aFirstFeatAttr)
+    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+  if (!aFirstFeatureInFolder.get())
+    return 0;
+
+  FeaturePtr aLastFeatureInFolder;
+  AttributeReferencePtr aLastFeatAttr =
+      theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+  if (aLastFeatAttr)
+    aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+  if (!aLastFeatureInFolder.get())
+    return 0;
+
+  int aFirst = aDoc->index(aFirstFeatureInFolder);
+  int aLast = aDoc->index(aLastFeatureInFolder);
+  return aLast - aFirst + 1;
+}
+
+ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const
+{
+  DocumentPtr aDoc = theFolder->document();
+
+  FeaturePtr aFirstFeatureInFolder;
+  AttributeReferencePtr aFirstFeatAttr =
+      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  if (aFirstFeatAttr)
+    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+  if (!aFirstFeatureInFolder.get())
+    return ObjectPtr();
+
+  int aFirst = aDoc->index(aFirstFeatureInFolder);
+  return aDoc->object(ModelAPI_Feature::group(), aFirst + theId);
+}
index 53e9109801667ffbe392733c4636fb5dbbcd619d..d20679f7983742f681b4309247321b1331292581 100644 (file)
@@ -182,6 +182,9 @@ private:
   /// \param fromRoot - root document flag
   QStringList listOfShowNotEmptyFolders(bool fromRoot = true) const;
 
+  int getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const;
+  ObjectPtr getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const;
+
   VisibilityState getVisibilityState(const QModelIndex& theIndex) const;
 
   void addShownFolder(DocumentPtr theDoc, QString theFolder)
index 4a9582d29d38ed7ba2c964a79f6ae7f605a3e54d..9612452007b84038bfce8bec51f01a0824c51f4f 100644 (file)
@@ -74,7 +74,7 @@
 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
 
 #ifdef TINSPECTOR
-#include <VInspectorAPI_CallBack.hxx>
+#include <inspector/VInspectorAPI_CallBack.hxx>
 #endif
 
 #include <Events_Loop.h>
@@ -1518,7 +1518,7 @@ void XGUI_Displayer::displayTrihedron(bool theToDisplay) const
   } else {
     deactivateTrihedron(false);
 
-    aContext->Erase(aTrihedron);
+    aContext->Erase(aTrihedron, Standard_True);
     #ifdef TINSPECTOR
     if (getCallBack()) getCallBack()->Remove(aTrihedron);
     #endif
index ad655723d54f603c55fcd010b18861dbacce117d..50f690425b92de3e73a40b4e3ce721691c1bb6cb 100644 (file)
@@ -59,7 +59,7 @@ public:
   /// \param theParent the parent to be deleted when the parent is deleted
   /// \param theOperationMgr the class to perform deletion
   XGUI_ShortCutListener(QObject* theParent, XGUI_OperationMgr* theOperationMgr)
-    : QObject(theParent), myOperationMgr(theOperationMgr)
+    : QObject(theParent), myOperationMgr(theOperationMgr), myIsActive(false)
   {
     qApp->installEventFilter(this);
   }
@@ -202,6 +202,18 @@ ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation*
   return myOperations.at(idx - 1);
 }
 
+ModuleBase_ModelWidget* XGUI_OperationMgr::activeWidget() const
+{
+  ModuleBase_ModelWidget* anActiveWidget = 0;
+  ModuleBase_Operation* anOperation = currentOperation();
+  if (anOperation) {
+    ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+    if (aPanel)
+      anActiveWidget = aPanel->activeWidget();
+  }
+  return anActiveWidget;
+}
+
 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
 {
   if (hasOperation())
@@ -697,7 +709,7 @@ bool XGUI_OperationMgr::onKeyPressed(QObject *theObject, QKeyEvent* theEvent)
         ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
         ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
         if (anActiveWgt)
-          isAccepted = anActiveWgt && anActiveWgt->processEscape();
+          isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEscape);
       }
       // default Escape button functionality
       if (!isAccepted && aOperation) {
@@ -737,7 +749,7 @@ bool XGUI_OperationMgr::onProcessEnter(QObject* theObject)
     }
   }
   if (!isAborted) {
-    isAccepted = anActiveWgt && anActiveWgt->processEnter();
+    isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEnter);
     if (!isAccepted) {
       isAccepted =
         myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");
@@ -784,7 +796,7 @@ bool XGUI_OperationMgr::onProcessDelete(QObject* theObject)
       if (isPPChildObject) {
         anActiveWgt = aPanel->activeWidget();
         if (anActiveWgt) {
-          isAccepted = anActiveWgt->processDelete();
+          isAccepted = anActiveWgt->processAction(ActionDelete);
         }
       }
     }
index 2c5eb00757834767951a87d088953bf8d9d00217..a2e2f0ed0d3176d4a8632d3acfa4c54e9e901e16 100755 (executable)
@@ -113,6 +113,10 @@ public:
   /// else, or if there is no parent - returns NULL
   ModuleBase_Operation* previousOperation(ModuleBase_Operation* theOperation) const;
 
+  /// Returns an active widget of the current operation.
+  /// \return widget or NULL
+  ModuleBase_ModelWidget* activeWidget() const;
+
   /// Start the operation and append it to the stack of operations
   /// \param theOperation the started operation
   /// \return the state whether the current operation is started
diff --git a/src/XGUI/XGUI_PropertyDialog.cpp b/src/XGUI/XGUI_PropertyDialog.cpp
new file mode 100644 (file)
index 0000000..ab15ae8
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include <XGUI_PropertyDialog.h>
+
+#include <QDialogButtonBox>
+#include <QLabel>
+#include <QGridLayout>
+
+XGUI_PropertyDialog::XGUI_PropertyDialog(QWidget* theParent)
+: QDialog(theParent), myContentWidget(0)
+{
+  myLayout = new QGridLayout(this);
+
+  QDialogButtonBox* aButtons = new QDialogButtonBox(
+    QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
+  connect(aButtons, SIGNAL(accepted()), this, SLOT(accept()));
+  connect(aButtons, SIGNAL(rejected()), this, SLOT(reject()));
+
+  myLayout->addWidget(aButtons, 1, 0);
+}
+
+void XGUI_PropertyDialog::setContent(QWidget* theWidget)
+{
+  myLayout->addWidget(theWidget, 0, 0);
+}
diff --git a/src/XGUI/XGUI_PropertyDialog.h b/src/XGUI/XGUI_PropertyDialog.h
new file mode 100644 (file)
index 0000000..647340f
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_PropertyDialog_H
+#define XGUI_PropertyDialog_H
+
+#include "XGUI.h"
+
+#include <QDialog>
+
+class QGridLayout;
+/**
+* \ingroup GUI
+* A dialog that contains property widget and accept/reject buttons.
+*/
+class XGUI_PropertyDialog : public QDialog
+{
+  Q_OBJECT
+public:
+  /// Constructor
+  /// \param theParent a parent widget for the dialog
+  XGUI_EXPORT XGUI_PropertyDialog(QWidget* theParent);
+
+  XGUI_EXPORT virtual ~XGUI_PropertyDialog() {};
+
+  /// Set content of the dialog
+  /// \param theWidget a content widget
+  void setContent(QWidget* theWidget);
+
+private:
+  QGridLayout* myLayout; /// grid layout where the first row is reserved for content widget,
+  /// the second row contains dialog buttons
+  QWidget* myContentWidget; /// content widget of the dialog
+};
+
+#endif
index f91a1b39106e9dcca9fa07f691d04ab18962ce09..ed7e5e23330e21ab0925e668d5cb580c0f4a8e13 100755 (executable)
@@ -46,7 +46,7 @@
 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
 
 #ifdef TINSPECTOR
-#include <VInspectorAPI_CallBack.hxx>
+#include <inspector/VInspectorAPI_CallBack.hxx>
 #endif
 
 XGUI_SelectionMgr::XGUI_SelectionMgr(XGUI_Workshop* theParent)
@@ -220,3 +220,23 @@ void XGUI_SelectionMgr::convertToObjectBrowserSelection(
     }
   }
 }
+
+std::list<FeaturePtr> XGUI_SelectionMgr::getSelectedFeatures()
+{
+  std::list<FeaturePtr> aFeatures;
+  QObjectPtrList aObjects = selection()->selectedObjects();
+  if (aObjects.isEmpty())
+    return aFeatures;
+
+  bool isPart = false;
+  foreach(ObjectPtr aObj, aObjects) {
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+    if (aFeature.get()) {
+      ResultPtr aRes = aFeature->firstResult();
+      isPart = (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group()));
+      if (!isPart)
+        aFeatures.push_back(aFeature);
+    }
+  }
+  return aFeatures;
+}
\ No newline at end of file
index 25bb95d85b774d0452595435a47041cdc1f8bf53..06e6fe54e5d0f19274413f0a56504b9db9722940 100644 (file)
@@ -24,6 +24,7 @@
 #include "XGUI.h"
 #include <ModuleBase_Definitions.h>
 #include <ModuleBase_ISelection.h>
+#include <ModelAPI_Feature.h>
 #include <QObject>
 #include <QModelIndexList>
 
@@ -77,6 +78,9 @@ Q_OBJECT
   /// \param thePlace a widget where selection has happened.
   void updateSelectionBy(const ModuleBase_ISelection::SelectionPlace& thePlace);
 
+  /// Returns list of selected features (ignores other selected objects and parts)
+  std::list<FeaturePtr> getSelectedFeatures();
+
 signals:
   //! Emited when selection in a one of viewers was changed
   void selectionChanged();
diff --git a/src/XGUI/XGUI_TransparencyWidget.cpp b/src/XGUI/XGUI_TransparencyWidget.cpp
new file mode 100644 (file)
index 0000000..76ec83d
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "XGUI_TransparencyWidget.h"
+
+#include <QCheckBox>
+#include <QDoubleSpinBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QSlider>
+
+XGUI_TransparencyWidget::XGUI_TransparencyWidget(QWidget* theParent, const QString& theLabelText)
+  : QWidget(theParent)
+{
+  QHBoxLayout* aLay = new QHBoxLayout(this);
+  aLay->setContentsMargins(0, 0, 0, 0);
+
+  mySpinValue = new QDoubleSpinBox(this);
+  mySpinValue->setRange(0, 1);
+  mySpinValue->setSingleStep(0.1);
+  mySliderValue = new QSlider(Qt::Horizontal, this);
+  mySliderValue->setRange(0, 100);
+
+  myPreview = new QCheckBox("Preview", this);
+  myPreview->setChecked(true);
+
+  if (!theLabelText.isEmpty())
+    aLay->addWidget(new QLabel(theLabelText, this));
+  aLay->addWidget(mySpinValue);
+  aLay->addWidget(mySliderValue);
+  aLay->addWidget(myPreview);
+
+  connect(mySpinValue, SIGNAL(valueChanged(double)), this, SLOT(onSpinValueChanged(double)));
+  connect(mySliderValue, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int)));
+  connect(myPreview, SIGNAL(toggled(bool)), this, SIGNAL(previewStateChanged()));
+}
+
+void XGUI_TransparencyWidget::setValue(double theValue)
+{
+  bool isSpinBlocked = mySpinValue->blockSignals(true);
+  bool isSliderBlocked = mySliderValue->blockSignals(true);
+
+  mySpinValue->setValue(theValue);
+  mySliderValue->setValue(theValue * 100);
+
+  mySpinValue->blockSignals(isSpinBlocked);
+  mySliderValue->blockSignals(isSliderBlocked);
+}
+
+double XGUI_TransparencyWidget::getValue() const
+{
+  return mySpinValue->value();
+}
+
+bool XGUI_TransparencyWidget::isPreviewNeeded() const
+{
+  return myPreview->isChecked();
+}
+
+void XGUI_TransparencyWidget::onSpinValueChanged(double theValue)
+{
+  setValue(theValue);
+  emit transparencyValueChanged();
+}
+
+void XGUI_TransparencyWidget::onSliderValueChanged(int theValue)
+{
+  setValue((double)theValue / 100);
+  emit transparencyValueChanged();
+}
diff --git a/src/XGUI/XGUI_TransparencyWidget.h b/src/XGUI/XGUI_TransparencyWidget.h
new file mode 100644 (file)
index 0000000..006d129
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_TransparencyWidget_H
+#define XGUI_TransparencyWidget_H
+
+#include "XGUI.h"
+
+#include <QWidget>
+
+class QDoubleSpinBox;
+class QSlider;
+class QCheckBox;
+
+/**
+* \ingroup GUI
+* A class of a widget to chose transparency. range of values is [0, 1],
+* where 0 - there is no transparency, 1 - the object is fully transparent.
+*/
+class XGUI_TransparencyWidget : public QWidget
+{
+  Q_OBJECT
+public:
+  /// Constructor
+  /// \param theParent a parent widget for the dialog
+  /// \param theLabelText if not empty, the information label will be shown in the widget
+  XGUI_EXPORT XGUI_TransparencyWidget(QWidget* theParent,
+                                      const QString& theLabelText = QString());
+  XGUI_EXPORT virtual ~XGUI_TransparencyWidget() {};
+
+  /// Initializes the dialog with the given value.
+  /// \param theValue transparency value
+  void setValue(double theValue);
+
+  /// Returns the current transparency value.
+  /// \return value
+  double getValue() const;
+
+  /// Returns true if the value should be applyed immediatelly
+  /// \return state of preview check control
+  bool isPreviewNeeded() const;
+
+signals:
+  void transparencyValueChanged();
+  void previewStateChanged();
+
+private slots:
+  /// Update slider value by spin value
+  /// \param theValue the new spin value
+  void onSpinValueChanged(double theValue);
+
+  /// Update spin value by slider value
+  /// \param theValue the new slider value
+  void onSliderValueChanged(int theValue);
+
+private:
+  QDoubleSpinBox* mySpinValue; /// value control
+  QSlider* mySliderValue; /// slider to select value
+  QCheckBox* myPreview; /// do preview immediatelly
+};
+
+#endif
index 7a11ee1bb221fce84b09df16ff07c921c5b6fce3..5112ff24ccbbfe703fcaa1763a46c9c50d8d787f 100755 (executable)
@@ -24,6 +24,7 @@
 #include "XGUI_MenuMgr.h"
 #include "XGUI_ColorDialog.h"
 #include "XGUI_DeflectionDialog.h"
+#include "XGUI_TransparencyWidget.h"
 #include "XGUI_ContextMenuMgr.h"
 #include "XGUI_Displayer.h"
 #include "XGUI_ErrorDialog.h"
@@ -32,6 +33,7 @@
 #include "XGUI_ObjectsBrowser.h"
 #include "XGUI_OperationMgr.h"
 #include "XGUI_PropertyPanel.h"
+#include "XGUI_PropertyDialog.h"
 #include "XGUI_SalomeConnector.h"
 #include "XGUI_Selection.h"
 #include "XGUI_SelectionMgr.h"
@@ -53,6 +55,8 @@
 #include <AppElements_Workbench.h>
 #endif
 
+#include <Config_XMLReader.h>
+
 #include <ModelAPI_AttributeDocRef.h>
 #include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_AttributeDouble.h>
 #ifdef TINSPECTOR
 #include <CDF_Session.hxx>
 #include <CDF_Application.hxx>
-#include <TInspector_Communicator.hxx>
-#include <VInspector_CallBack.hxx>
+#include <inspector/TInspector_Communicator.hxx>
+#include <inspector/VInspector_CallBack.hxx>
 static TInspector_Communicator* MyTCommunicator;
 static Handle(VInspector_CallBack) MyVCallBack;
 
@@ -293,7 +297,14 @@ void XGUI_Workshop::startApplication()
   Config_PropManager::registerProp("Plugins", "default_path", "Default Path",
                                    Config_Prop::Directory, "");
 
+  std::string aDir = Config_XMLReader::resourcesConfigFile();
+  Config_PropManager::registerProp("Plugins", "import_initial_path", "Import initial directory",
+                                   Config_Prop::Directory, aDir);
 
+#ifdef _DEBUG
+  Config_PropManager::registerProp("Plugins", "create_part_by_start", "Create Part by Start",
+    Config_Prop::Boolean, "false");
+#endif
   registerValidators();
 
   // Calling of  loadCustomProps before activating module is required
@@ -313,6 +324,13 @@ void XGUI_Workshop::startApplication()
           SLOT(onTrihedronVisibilityChanged(bool)));
 
   emit applicationStarted();
+
+#ifdef _DEBUG
+  bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start");
+  if (aNewPart) {
+      module()->launchOperation("Part", false); // PartSetPlugin_Part::ID()
+  }
+#endif
 }
 
 void XGUI_Workshop::activateModule()
@@ -600,8 +618,6 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation)
       aWidget->restoreValue();
     aWidget->enableFocusProcessing();
   }
-  ModuleBase_Tools::flushUpdated(aFeature);
-
   // update visible state of Preview button
   std::shared_ptr<Config_FeatureMessage> aFeatureInfo;
 #ifdef HAVE_SALOME
@@ -630,6 +646,10 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation)
                   new Events_Message(Events_Loop::eventByName(EVENT_PREVIEW_BLOCKED)));
     Events_Loop::loop()->send(aMsg);
   }
+  // if update happens after preview is blocked, it does nothing when blocked
+  // it improves performance for valid objects on feature start
+  ModuleBase_Tools::flushUpdated(aFeature);
+
   myPropertyPanel->setModelWidgets(aWidgets);
   aFOperation->setPropertyPanel(myPropertyPanel);
 
@@ -851,6 +871,22 @@ void XGUI_Workshop::openDirectory(const QString& theDirectory)
 #ifndef HAVE_SALOME
   myMainWindow->setCurrentDir(myCurrentDir, true);
 #endif
+
+#ifdef _DEBUG
+  bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start");
+  if (aNewPart) {
+
+    DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+    int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+    if (aSize > 0 ) {
+      ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), 0);
+      ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
+      if (aPart.get())
+        aPart->activate();
+    }
+  }
+#endif
+
   QApplication::restoreOverrideCursor();
 }
 
@@ -982,6 +1018,10 @@ bool XGUI_Workshop::onSaveAs()
 //******************************************************
 void XGUI_Workshop::onUndo(int theTimes)
 {
+  ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+  if (anActiveWidget && anActiveWidget->processAction(ActionUndo))
+    return;
+
   objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
   SessionPtr aMgr = ModelAPI_Session::get();
   std::list<std::string> aUndoList = aMgr->undoList();
@@ -1005,6 +1045,10 @@ void XGUI_Workshop::onUndo(int theTimes)
 //******************************************************
 void XGUI_Workshop::onRedo(int theTimes)
 {
+  ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+  if (anActiveWidget && anActiveWidget->processAction(ActionRedo))
+    return;
+
   // the viewer update should be blocked in order to avoid the features blinking. For the created
   // feature a results are created, the flush of the created signal caused the viewer redisplay for
   // each created result. After a redisplay signal is flushed. So, the viewer update is blocked
@@ -1054,13 +1098,13 @@ void XGUI_Workshop::onRedo(int theTimes)
 //******************************************************
 void XGUI_Workshop::onWidgetStateChanged(int thePreviousState)
 {
-  ModuleBase_ModelWidget* anActiveWidget = 0;
-  ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
-  if (anOperation) {
-    ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
-    if (aPanel)
-      anActiveWidget = aPanel->activeWidget();
-  }
+  ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+  //ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
+  //if (anOperation) {
+  //  ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+  //  if (aPanel)
+  //    anActiveWidget = aPanel->activeWidget();
+  //}
   if (anActiveWidget)
     operationMgr()->onValidateOperation();
 
@@ -1189,10 +1233,24 @@ void XGUI_Workshop::updateCommandStatus()
   if (aMgr->hasModuleDocument()) {
     foreach(QAction* aCmd, aCommands) {
       QString aId = aCmd->data().toString();
-      if (aId == "UNDO_CMD")
-        aCmd->setEnabled(myModule->canUndo());
-      else if (aId == "REDO_CMD")
-        aCmd->setEnabled(myModule->canRedo());
+      if (aId == "UNDO_CMD") {
+        bool isActionEnabled = false;
+        // if ultimate is true -> using result of operation only, or using OR combination
+        ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+        if (anActiveWidget && anActiveWidget->canProcessAction(ActionUndo, isActionEnabled))
+          aCmd->setEnabled(isActionEnabled);
+        else
+          aCmd->setEnabled(myModule->canUndo());
+      }
+      else if (aId == "REDO_CMD") {
+        bool isActionEnabled = false;
+        // if ultimate is true -> using result of operation only, or using OR combination
+        ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+        if (anActiveWidget && anActiveWidget->canProcessAction(ActionRedo, isActionEnabled))
+          aCmd->setEnabled(isActionEnabled);
+        else
+          aCmd->setEnabled(myModule->canRedo());
+      }
       else
         // Enable all commands
         aCmd->setEnabled(true);
@@ -1354,6 +1412,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
     changeColor(aObjects);
   else if (theId == "DEFLECTION_CMD")
     changeDeflection(aObjects);
+#ifdef USE_TRANSPARENCY
+  else if (theId == "TRANSPARENCY_CMD")
+    changeTransparency(aObjects);
+#endif
   else if (theId == "SHOW_CMD") {
     showObjects(aObjects, true);
     mySelector->updateSelectionBy(ModuleBase_ISelection::Browser);
@@ -1390,6 +1452,16 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
     setViewerSelectionMode(TopAbs_EDGE);
   } else if (theId == "SELECT_FACE_CMD") {
     setViewerSelectionMode(TopAbs_FACE);
+  } else if (theId == "INSERT_FOLDER_CMD") {
+    insertFeatureFolder();
+  } else if (theId == "ADD_TO_FOLDER_BEFORE_CMD") {
+    insertToFolder(true);
+  } else if (theId == "ADD_TO_FOLDER_AFTER_CMD") {
+    insertToFolder(false);
+  } else if (theId == "ADD_OUT_FOLDER_BEFORE_CMD") {
+    moveOutFolder(true);
+  } else if (theId == "ADD_OUT_FOLDER_AFTER_CMD") {
+    moveOutFolder(false);
   } else if (theId == "SELECT_RESULT_CMD") {
     //setViewerSelectionMode(-1);
     //IMP: an attempt to use result selection with other selection modes
@@ -1484,9 +1556,10 @@ void XGUI_Workshop::deleteObjects()
   bool hasParameter = false;
   bool hasCompositeOwner = false;
   bool hasResultInHistory = false;
+  bool hasFolder = false;
   ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasCompositeOwner,
-                                 hasResultInHistory);
-  if (!(hasFeature || hasParameter))
+                                 hasResultInHistory, hasFolder);
+  if (!(hasFeature || hasParameter || hasFolder))
     return;
 
   // delete objects
@@ -1495,6 +1568,9 @@ void XGUI_Workshop::deleteObjects()
   ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
   ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
 
+  std::set<FolderPtr> aFolders;
+  ModuleBase_Tools::convertToFolders(anObjects, aFolders);
+
   bool aDone = false;
   QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text() + " %1";
   aDescription = aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
@@ -1513,6 +1589,18 @@ void XGUI_Workshop::deleteObjects()
       aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
     aDone = ModelAPI_Tools::removeFeatures(aFeatures, false);
   }
+  if (aFolders.size() > 0) {
+    std::set<FolderPtr>::const_iterator anIt = aFolders.begin(),
+                                         aLast = aFolders.end();
+    for (; anIt != aLast; anIt++) {
+      FolderPtr aFolder = *anIt;
+      if (aFolder.get()) {
+        DocumentPtr aDoc = aFolder->document();
+        aDoc->removeFolder(aFolder);
+      }
+    }
+  }
+
   if (aDone)
     operationMgr()->commitOperation();
   else
@@ -1851,17 +1939,25 @@ bool XGUI_Workshop::canBeShaded(const ObjectPtr& theObject) const
 }
 
 //**************************************************************
-bool XGUI_Workshop::canChangeColor() const
+bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const
 {
-  QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
+  if (theActionName == "COLOR_CMD" ||
+      theActionName == "DEFLECTION_CMD"
+#ifdef USE_TRANSPARENCY
+      || theActionName == "TRANSPARENCY_CMD"
+#endif
+      ) {
+    QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
 
-  std::set<std::string> aTypes;
-  aTypes.insert(ModelAPI_ResultGroup::group());
-  aTypes.insert(ModelAPI_ResultConstruction::group());
-  aTypes.insert(ModelAPI_ResultBody::group());
-  aTypes.insert(ModelAPI_ResultPart::group());
+    std::set<std::string> aTypes;
+    aTypes.insert(ModelAPI_ResultGroup::group());
+    aTypes.insert(ModelAPI_ResultConstruction::group());
+    aTypes.insert(ModelAPI_ResultBody::group());
+    aTypes.insert(ModelAPI_ResultPart::group());
 
-  return hasResults(aObjects, aTypes);
+    return hasResults(aObjects, aTypes);
+  }
+  return false;
 }
 
 void setColor(ResultPtr theResult, const std::vector<int>& theColor)
@@ -1948,19 +2044,6 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
 }
 
 //**************************************************************
-bool XGUI_Workshop::canChangeDeflection() const
-{
-  QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
-
-  std::set<std::string> aTypes;
-  aTypes.insert(ModelAPI_ResultGroup::group());
-  aTypes.insert(ModelAPI_ResultConstruction::group());
-  aTypes.insert(ModelAPI_ResultBody::group());
-  aTypes.insert(ModelAPI_ResultPart::group());
-
-  return hasResults(aObjects, aTypes);
-}
-
 void setDeflection(ResultPtr theResult, const double theDeflection)
 {
   if (!theResult.get())
@@ -1971,13 +2054,41 @@ void setDeflection(ResultPtr theResult, const double theDeflection)
     aDeflectionAttr->setValue(theDeflection);
 }
 
+//**************************************************************
+void setTransparency(ResultPtr theResult, double theTransparency)
+{
+  if (!theResult.get())
+    return;
+
+  AttributeDoublePtr anAttribute = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID());
+  if (anAttribute.get() != NULL)
+    anAttribute->setValue(theTransparency);
+}
+
+//**************************************************************
+void setTransparency(double theTransparency, const QObjectPtrList& theObjects)
+{
+  foreach(ObjectPtr anObj, theObjects) {
+    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
+    if (aResult.get() != NULL) {
+      ResultCompSolidPtr aCompsolidResult =
+        std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
+      if (aCompsolidResult.get() != NULL) { // change property for all sub-solids
+        for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
+          setTransparency(aCompsolidResult->subResult(i), theTransparency);
+        }
+      }
+      setTransparency(aResult, theTransparency);
+    }
+  }
+}
 
 //**************************************************************
 void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects)
 {
   AttributeDoublePtr aDoubleAttr;
-  // 1. find the current color of the object. This is a color of AIS presentation
-  // The objects are iterated until a first valid color is found
+  // 1. find the current property of the object. This is a property of AIS presentation
+  // The objects are iterated until a first valid property is found
   double aDeflection = -1;
   foreach(ObjectPtr anObject, theObjects) {
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
@@ -1985,9 +2096,9 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects)
       aDeflection = XGUI_CustomPrs::getResultDeflection(aResult);
     }
     else {
-      // TODO: remove the obtaining a color from the AIS object
+      // TODO: remove the obtaining a property from the AIS object
       // this does not happen never because:
-      // 1. The color can be changed only on results
+      // 1. The property can be changed only on results
       // 2. The result can be not visualized in the viewer(e.g. Origin Construction)
       AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject);
       if (anAISObj.get()) {
@@ -2022,7 +2133,7 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects)
     if (aResult.get() != NULL) {
       ResultCompSolidPtr aCompsolidResult =
         std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
-      if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids
+      if (aCompsolidResult.get() != NULL) { // change property for all sub-solids
         for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
           setDeflection(aCompsolidResult->subResult(i), aDeflection);
         }
@@ -2034,6 +2145,90 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects)
   updateCommandStatus();
 }
 
+//**************************************************************
+void XGUI_Workshop::changeTransparency(const QObjectPtrList& theObjects)
+{
+  AttributeDoublePtr aDoubleAttr;
+  // 1. find the current property of the object. This is a property of AIS presentation
+  // The objects are iterated until a first valid property is found
+  double aCurrentValue = -1;
+  foreach(ObjectPtr anObject, theObjects) {
+    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+    if (aResult.get()) {
+      aCurrentValue = XGUI_CustomPrs::getResultTransparency(aResult);
+    }
+    else {
+      // TODO: remove the obtaining a property from the AIS object
+      // this does not happen never because:
+      // 1. The property can be changed only on results
+      // 2. The result can be not visualized in the viewer(e.g. Origin Construction)
+      AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject);
+      if (anAISObj.get()) {
+        aCurrentValue = anAISObj->getDeflection();
+      }
+    }
+    if (aCurrentValue > 0)
+      break;
+  }
+  if (aCurrentValue < 0)
+    return;
+
+  if (!abortAllOperations())
+  return;
+
+  // 2. show the dialog to change the value
+  XGUI_PropertyDialog* aDlg = new XGUI_PropertyDialog(desktop());
+  aDlg->setWindowTitle("Transparency");
+  XGUI_TransparencyWidget* aTransparencyWidget = new XGUI_TransparencyWidget(aDlg);
+  connect(aTransparencyWidget, SIGNAL(transparencyValueChanged()),
+          this, SLOT(onTransparencyValueChanged()));
+  connect(aTransparencyWidget, SIGNAL(previewStateChanged()),
+          this, SLOT(onPreviewStateChanged()));
+  aDlg->setContent(aTransparencyWidget);
+  aTransparencyWidget->setValue(aCurrentValue);
+
+  // 3. abort the previous operation and start a new one
+  SessionPtr aMgr = ModelAPI_Session::get();
+  QString aDescription = contextMenuMgr()->action("TRANSPARENCY_CMD")->text();
+  aMgr->startOperation(aDescription.toStdString());
+
+  aDlg->move(QCursor::pos());
+  bool isDone = aDlg->exec() == QDialog::Accepted;
+  if (!isDone)
+    return;
+
+  // 4. set the value to all results
+  aCurrentValue = aTransparencyWidget->getValue();
+  setTransparency(aCurrentValue, theObjects);
+
+  aMgr->finishOperation();
+  updateCommandStatus();
+}
+
+//**************************************************************
+void XGUI_Workshop::onTransparencyValueChanged()
+{
+  XGUI_TransparencyWidget* aTransparencyWidget = (XGUI_TransparencyWidget*)sender();
+  if (!aTransparencyWidget || !aTransparencyWidget->isPreviewNeeded())
+    return;
+
+  QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+  setTransparency(aTransparencyWidget->getValue(), anObjects);
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+}
+
+//**************************************************************
+void XGUI_Workshop::onPreviewStateChanged()
+{
+  XGUI_TransparencyWidget* aTransparencyWidget = (XGUI_TransparencyWidget*)sender();
+  if (!aTransparencyWidget || !aTransparencyWidget->isPreviewNeeded())
+    return;
+
+  QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+  setTransparency(aTransparencyWidget->getValue(), anObjects);
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+}
+
 //**************************************************************
 #define SET_DISPLAY_GROUP(aGroupName, aDisplay) \
 for (int i = 0; i < aDoc->size(aGroupName); i++) { \
@@ -2045,6 +2240,15 @@ void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible)
     aObj->setDisplayed(isVisible);
   }
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+#ifndef WIN32
+  // Necessary for update icons in ObjectBrowser on Linux
+  QModelIndexList aIndexes = mySelector->selection()->selectedIndexes();
+  foreach (QModelIndex aIdx, aIndexes) {
+    if (aIdx.column() == 0) {
+      myObjectBrowser->treeView()->update(aIdx);
+    }
+  }
+#endif
 }
 
 //**************************************************************
@@ -2070,6 +2274,15 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
     aObj->setDisplayed(true);
   }
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+#ifndef WIN32
+  // Necessary for update icons in ObjectBrowser on Linux
+  QModelIndexList aIndexes = mySelector->selection()->selectedIndexes();
+  foreach (QModelIndex aIdx, aIndexes) {
+    if (aIdx.column() == 0) {
+      myObjectBrowser->treeView()->update(aIdx);
+    }
+  }
+#endif
 }
 
 
@@ -2129,6 +2342,9 @@ void XGUI_Workshop::closeDocument()
   objectBrowser()->clearContent();
 
   module()->closeDocument();
+  // we need to clear viewer (with created filters) to do not have problems in 2nd SALOME study
+  module()->clearViewer();
+
 
   // data model need not process the document's signals about objects modifications as
   // the document is closed
@@ -2275,3 +2491,54 @@ void XGUI_Workshop::highlightFeature(const QObjectPtrList& theObjects)
     objectBrowser()->blockSignals(aBlocked);
   }
 }
+
+void XGUI_Workshop::insertFeatureFolder()
+{
+  QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
+  if (aObjects.isEmpty())
+    return;
+  ObjectPtr aObj = aObjects.first();
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+  if (aFeature.get() == NULL)
+    return;
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aDoc = aMgr->activeDocument();
+
+  aMgr->startOperation();
+  aDoc->addFolder(aFeature);
+  aMgr->finishOperation();
+}
+
+
+void XGUI_Workshop::insertToFolder(bool isBefore)
+{
+  std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
+  if (aFeatures.empty())
+    return;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aDoc = aMgr->activeDocument();
+
+  FolderPtr aFolder = isBefore? aDoc->findFolderAbove(aFeatures):
+                                aDoc->findFolderBelow(aFeatures);
+  if (!aFolder.get())
+    return;
+
+  aMgr->startOperation();
+  aDoc->moveToFolder(aFeatures, aFolder);
+  aMgr->finishOperation();
+}
+
+void XGUI_Workshop::moveOutFolder(bool isBefore)
+{
+  std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
+  if (aFeatures.empty())
+    return;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aDoc = aMgr->activeDocument();
+
+  aMgr->startOperation();
+  aDoc->removeFromFolder(aFeatures, isBefore);
+  aMgr->finishOperation();
+}
\ No newline at end of file
index 0f0c350fd4cd455a1662df74bce6472c3e2881c8..8a96cfa803fd838891e70dad003e90cf6974a787 100755 (executable)
@@ -211,23 +211,25 @@ Q_OBJECT
   bool canBeShaded(const ObjectPtr& theObject) const;
 
   //! Returns true if there is at least one selected body/construction/group result
+  //! \param theActionName text of the checked action
   //! \return boolean value
-  bool canChangeColor() const;
+  bool canChangeProperty(const QString& theActionName) const;
 
   //! Change color of the results if it is possible
   //! The operation is available for construction, body and group results
   //! theObjects a list of selected objects
   void changeColor(const QObjectPtrList& theObjects);
 
-  //! Returns true if there is at least one selected body/construction/group result
-  //! \return boolean value
-  bool canChangeDeflection() const;
-
   //! Change deflection of the results if it is possible
   //! The operation is available for construction, body and group results
   //! theObjects a list of selected objects
   void changeDeflection(const QObjectPtrList& theObjects);
 
+  //! Change transparency of the results if it is possible
+  //! The operation is available for construction, body and group results
+  //! theObjects a list of selected objects
+  void changeTransparency(const QObjectPtrList& theObjects);
+
   //! Show the given features in 3d Viewer
   void showObjects(const QObjectPtrList& theList, bool isVisible);
 
@@ -423,6 +425,11 @@ signals:
   /// Activates/deactivates the trihedron in the viewer AIS context
   void onTrihedronVisibilityChanged(bool theState);
 
+  /// Apply the current transparency value if preview in transparency dialog is switched on
+  void onTransparencyValueChanged();
+
+  /// Switch on/off preview of transparency change
+  void onPreviewStateChanged();
 
  protected:
   /// Sets the granted operations for the parameter operation. Firstly, it finds the nested features
@@ -441,6 +448,15 @@ private:
   /// Display results from a group
   void displayGroupResults(DocumentPtr theDoc, std::string theGroup);
 
+  /// Insert folder object before currently selected feature
+  void insertFeatureFolder();
+
+  /// Insert an object to a folder above or below
+  void insertToFolder(bool isBefore);
+
+  /// Insert an object to a folder above or below
+  void moveOutFolder(bool isBefore);
+
  private slots:
   /// SLOT, that is called after the operation is started. Update workshop state according to
   /// the started operation, e.g. visualizes the property panel and connect to it.
index 222dfd208af47fb5b1cf90f762e6f12026980708..cc92ee6fb0955fdc58ca6f119adfa1a2e819d53d 100644 (file)
      <file>pictures/eyeclosed.png</file>
      <file>pictures/eyemiclosed.png</file>
      <file>pictures/eyeopen.png</file>
+
+     <file>pictures/transparency.png</file>
+     <file>pictures/features_folder.png</file>
+     <file>pictures/create_folder.png</file>
+     <file>pictures/insert_folder_after.png</file>
+     <file>pictures/insert_folder_before.png</file>
+     <file>pictures/move_out_after.png</file>
+     <file>pictures/move_out_before.png</file>
  </qresource>
  </RCC>
diff --git a/src/XGUI/pictures/create_folder.png b/src/XGUI/pictures/create_folder.png
new file mode 100644 (file)
index 0000000..371d86d
Binary files /dev/null and b/src/XGUI/pictures/create_folder.png differ
diff --git a/src/XGUI/pictures/features_folder.png b/src/XGUI/pictures/features_folder.png
new file mode 100644 (file)
index 0000000..055992b
Binary files /dev/null and b/src/XGUI/pictures/features_folder.png differ
diff --git a/src/XGUI/pictures/insert_folder_after.png b/src/XGUI/pictures/insert_folder_after.png
new file mode 100644 (file)
index 0000000..f10a6c9
Binary files /dev/null and b/src/XGUI/pictures/insert_folder_after.png differ
diff --git a/src/XGUI/pictures/insert_folder_before.png b/src/XGUI/pictures/insert_folder_before.png
new file mode 100644 (file)
index 0000000..2563478
Binary files /dev/null and b/src/XGUI/pictures/insert_folder_before.png differ
diff --git a/src/XGUI/pictures/move_out_after.png b/src/XGUI/pictures/move_out_after.png
new file mode 100644 (file)
index 0000000..6adcf64
Binary files /dev/null and b/src/XGUI/pictures/move_out_after.png differ
diff --git a/src/XGUI/pictures/move_out_before.png b/src/XGUI/pictures/move_out_before.png
new file mode 100644 (file)
index 0000000..cf248a6
Binary files /dev/null and b/src/XGUI/pictures/move_out_before.png differ
diff --git a/src/XGUI/pictures/transparency.png b/src/XGUI/pictures/transparency.png
new file mode 100644 (file)
index 0000000..774160e
Binary files /dev/null and b/src/XGUI/pictures/transparency.png differ
index 95e76725ba00f75c8cf3e224bda0ee3e1e059a11..772056c0a4731b86c15ddd631a455f69598adbed 100644 (file)
@@ -82,7 +82,7 @@ Box_12 = model.addBox(Part_1_doc, Point_1, Point_5)
 Box_13 = model.addBox(Part_1_doc, Vertex_3, Point_2)
 Box_14 = model.addBox(Part_1_doc, Point_2, Vertex_3)
 Box_15 = model.addBox(Part_1_doc, model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_4e"), model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_7s-SketchLine_6e"))
-Box_16 = model.addBox(Part_1_doc, model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_1"))
+Box_16 = model.addBox(Part_1_doc, model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_3&Extrusion_2_1/Generated_Face_2&Extrusion_2_1/To_Face_1"))
 Box_17 = model.addBox(Part_1_doc, model.selection("VERTEX", "Vertex_1_1"), model.selection("VERTEX", "Vertex_2_1"))
 Box_18 = model.addBox(Part_1_doc, "dx", "dy", "dz")
 model.do()
index 5577a9654c1e730857e431af90e86316504abc76..56fcd4ed2f865b5a945e6f2ca9cfffbdff13ea94 100644 (file)
@@ -181,16 +181,16 @@ Translation_6 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_
 Translation_7 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_7_1")], model.selection("EDGE", "Edge_1_1"), 15)
 Translation_8 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_8_1")], model.selection("EDGE", "Box_8_1/Right&Box_8_1/Top"), 15)
 Translation_9 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_9_1")], model.selection("EDGE", "PartSet/Axis_4"), 15)
-Translation_10 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_1_1")], model.selection("EDGE", "PartSet/OZ"), 15)
-Translation_11 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_2_1")], model.selection("EDGE", "PartSet/OZ"), 0)
-Translation_12 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_3_1")], model.selection("EDGE", "PartSet/OZ"), -15)
-Translation_13 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_4_1")], model.selection("EDGE", "InvalidName"), 15)
-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_10 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_10_1")], model.selection("EDGE", "PartSet/OZ"), 15)
+Translation_11 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_11_1")], model.selection("EDGE", "PartSet/OZ"), 0)
+Translation_12 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_12_1")], model.selection("EDGE", "PartSet/OZ"), -15)
+Translation_13 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_13_1")], model.selection("EDGE", "InvalidName"), 15)
+Translation_14 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_14_1")], model.selection("EDGE", "PartSet/OZ"), "d")
+Translation_15 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_15_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 50)
+Translation_16 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_16_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_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_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_17_1")], model.selection("EDGE", "Box_17_1/Translated_Face_3_4&Box_17_1/Translated_Face_3_1"), 50)
+Translation_18 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_18_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)
 Translation_21 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_4/")], model.selection("EDGE", "OX"), -15)
index 327b8e741ccd25be359cff69b3b91477c2c4889d..bc030e28bc7a06258c5bb462251a92f0be086632 100644 (file)
@@ -91,93 +91,93 @@ model.addParameter(Part_1_doc, "d", "15")
 
 # Translation 27
 Translation_27_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_2_1")], [model.selection("SOLID", "Translation_1_1")])
-Translation_27 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_1_1")], model.selection("EDGE", "PartSet/OX"), 15)
+Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_2_1")], [model.selection("SOLID", "Box_1_1")])
+Translation_27 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_2_1")], model.selection("EDGE", "PartSet/OX"), 15)
 
 # Translation 28
 Translation_28_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_2 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_4_1")], [model.selection("SOLID", "Translation_3_1")])
-Translation_28 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_2_1")], model.selection("EDGE", "PartSet/OX"), 0)
+Intersection_2 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_4_1")], [model.selection("SOLID", "Box_3_1")])
+Translation_28 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_4_1")], model.selection("EDGE", "PartSet/OX"), 0)
 
 # Translation 29
 Translation_29_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_5_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_3 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_6_1")], [model.selection("SOLID", "Translation_5_1")])
-Translation_29 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_3_1")], model.selection("EDGE", "PartSet/OX"), -15)
+Intersection_3 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_6_1")], [model.selection("SOLID", "Box_5_1")])
+Translation_29 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_6_1")], model.selection("EDGE", "PartSet/OX"), -15)
 
 # Translation 30
 Translation_30_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_7_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_4 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_8_1")], [model.selection("SOLID", "Translation_7_1")])
-Translation_30 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_4_1")], model.selection("EDGE", "InvalidName"), -15)
+Intersection_4 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_8_1")], [model.selection("SOLID", "Box_7_1")])
+Translation_30 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_8_1")], model.selection("EDGE", "InvalidName"), -15)
 
 # Translation 31
 Translation_31_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_9_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_5 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_10_1")], [model.selection("SOLID", "Translation_9_1")])
-Translation_31 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_5_1")], model.selection("EDGE", "PartSet/OY"), "d")
+Intersection_5 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_10_1")], [model.selection("SOLID", "Box_9_1")])
+Translation_31 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_10_1")], model.selection("EDGE", "PartSet/OY"), "d")
 
 # Translation 32
 Translation_32_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_11_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_6 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_12_1")], [model.selection("SOLID", "Translation_11_1")])
-Translation_32 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_6_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
+Intersection_6 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_12_1")], [model.selection("SOLID", "Box_11_1")])
+Translation_32 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_12_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
 
 # Translation 33
 Translation_33_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_13_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_7 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_14_1")], [model.selection("SOLID", "Translation_13_1")])
-Translation_33 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_7_1")], model.selection("EDGE", "Edge_1_1"), 15)
+Intersection_7 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_14_1")], [model.selection("SOLID", "Box_13_1")])
+Translation_33 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_14_1")], model.selection("EDGE", "Edge_1_1"), 15)
 
 # Translation 34
 Translation_34_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_15_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_8 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_16_1")], [model.selection("SOLID", "Translation_15_1")])
-Translation_34 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_8_1")], model.selection("EDGE", "Intersection_8_1_6"), 15)
+Intersection_8 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_16_1")], [model.selection("SOLID", "Box_15_1")])
+Translation_34 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_16_1")], model.selection("EDGE", "Intersection_8_1_6"), 15)
 
 # Translation 35
 Translation_35_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_17_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_9 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_18_1")], [model.selection("SOLID", "Translation_17_1")])
-Translation_35 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_9_1")], model.selection("EDGE", "Axis_1"), 15)
+Intersection_9 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_18_1")], [model.selection("SOLID", "Box_17_1")])
+Translation_35 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_18_1")], model.selection("EDGE", "Axis_1"), 15)
 
 #Translation 36
 Translation_36_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_19_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_20_1"), model.selection("SOLID", "Translation_19_1")])
-Translation_36 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OX"), 15)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_20_1"), model.selection("SOLID", "Box_19_1")])
+Translation_36 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_20_1")], model.selection("EDGE", "PartSet/OX"), 15)
 
 ## Translation 37
 Translation_37_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_21_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_2 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_22_1"), model.selection("SOLID", "Translation_21_1")])
-Translation_37 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_2_1")], model.selection("EDGE", "PartSet/OX"), 0)
+Partition_2 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_22_1"), model.selection("SOLID", "Box_21_1")])
+Translation_37 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_22_1")], model.selection("EDGE", "PartSet/OX"), 0)
 
 ## Translation 38
 Translation_38_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_23_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_3 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_24_1"), model.selection("SOLID", "Translation_23_1")])
-Translation_38 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_3_1")], model.selection("EDGE", "PartSet/OX"), 0)
+Partition_3 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_24_1"), model.selection("SOLID", "Box_23_1")])
+Translation_38 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_24_1")], model.selection("EDGE", "PartSet/OX"), 0)
 
 ## Translation 39
 Translation_39_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_25_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_4 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_26_1"), model.selection("SOLID", "Translation_25_1")])
-Translation_39 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_4_1")], model.selection("EDGE", "InvalidName"), 0)
+Partition_4 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_26_1"), model.selection("SOLID", "Box_25_1")])
+Translation_39 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_26_1")], model.selection("EDGE", "InvalidName"), 0)
 
 ## Translation 40
 Translation_40_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_27_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_5 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_28_1"), model.selection("SOLID", "Translation_27_1")])
-Translation_40 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_5_1")], model.selection("EDGE", "PartSet/OX"), "d")
+Partition_5 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_28_1"), model.selection("SOLID", "Box_27_1")])
+Translation_40 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_28_1")], model.selection("EDGE", "PartSet/OX"), "d")
 
 # Translation 41
 Translation_41_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_29_1")], model.selection("EDGE", "PartSet/OX"), 5)
-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)
+Partition_6 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_30_1"), model.selection("SOLID", "Box_29_1")])
+Translation_41 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_30_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
 
 # 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)
+Partition_7 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_32_1"), model.selection("SOLID", "Box_31_1")])
+Translation_42 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_32_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_1/Modified_Face_1_4&Partition_8_1_1/Modified_Face_1_1"), 15)
+Partition_8 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_34_1"), model.selection("SOLID", "Box_33_1")])
+Translation_43 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_34_1")], model.selection("EDGE", "Partition_8_1_1/Modified_Face_2_5&Partition_8_1_1/Modified_Face_2_2"), 15)
 
 # Translation 44
 Translation_44_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_35_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_9 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_36_1"), model.selection("SOLID", "Translation_35_1")])
-Translation_44 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_9_1")], model.selection("EDGE", "Axis_1"), 15)
+Partition_9 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_36_1"), model.selection("SOLID", "Box_35_1")])
+Translation_44 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_36_1")], model.selection("EDGE", "Axis_1"), 15)
 model.do()
 model.end()
 
index 8d7af9855c22c26dfc710a9442c928ae892f1ece..dadc9d953e52076dc434e5f7b46891a5b3676173 100644 (file)
@@ -162,14 +162,23 @@ Face_13 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-Sket
 
 # Shells
 Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_1.result().setName("Shell_1_1")
 Shell_2 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_2.result().setName("Shell_2_1")
 Shell_3 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_3.result().setName("Shell_3_1")
 Shell_4 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_4.result().setName("Shell_4_1")
 Shell_5 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_5.result().setName("Shell_5_1")
 Shell_6 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_12_1"), model.selection("FACE", "Face_13_1")])
+Shell_6.result().setName("Shell_6_1")
 Shell_7 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_12_1"), model.selection("FACE", "Face_13_1")])
+Shell_7.result().setName("Shell_7_1")
 Shell_8 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_8.result().setName("Shell_8_1")
 Shell_9 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_9.result().setName("Shell_9_1")
 
 # Parameters
 model.addParameter(Part_1_doc, "d", "15")
index a7dc181339852050bba0ccab0393db03ec3f7958..7029f13964babaeabd6584891ea42243dfeaba2a 100644 (file)
@@ -95,22 +95,23 @@ SketchConstraintCoincidence_14.setName("SketchConstraintCoincidence_15")
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_8f-SketchLine_9f-SketchLine_10f-SketchArc_1_2r-SketchArc_2_2r")], model.selection(), "b/2", "b/2")
 Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"))
-SketchPoint_2 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_1"))
+SketchPoint_2 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"))
 SketchCircle_1 = Sketch_2.addCircle(-15, 35.00000000000001, 25)
 SketchConstraintCoincidence_15 = Sketch_2.setCoincident(SketchPoint_2.result(), SketchCircle_1.center())
 SketchConstraintCoincidence_15.setName("SketchConstraintCoincidence_16")
 SketchConstraintRadius_3 = Sketch_2.setRadius(SketchCircle_1.results()[1], "50/2")
 model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_1_2f")], model.selection(), 0, 13, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"))
-SketchPoint_3 = Sketch_3.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_3&ExtrusionCut_1_1/Modfied_2&ExtrusionCut_1_1/Modfied_4"))
-SketchLine_11 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_2&ExtrusionCut_1_1/Modfied_4"))
+SketchPoint_3 = Sketch_3.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_2&ExtrusionCut_1_1/Modfied_3&ExtrusionCut_1_1/Modfied_4"))
+SketchLine_11 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_3&ExtrusionCut_1_1/Modfied_4"))
 SketchArc_3 = Sketch_3.addArc(-15, 35.00000000000001, -15, 46.0103340429751, -17.02045759563166, 24.17663606626138, True)
 SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchPoint_3.result(), SketchArc_3.center())
 SketchConstraintCoincidence_16.setName("SketchConstraintCoincidence_17")
 SketchConstraintCoincidence_17 = Sketch_3.setCoincident(SketchLine_11.result(), SketchArc_3.startPoint())
 SketchConstraintCoincidence_17.setName("SketchConstraintCoincidence_18")
-SketchArc_4 = Sketch_3.addArc(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_3&ExtrusionCut_1_1/Modfied_4"))
+SketchArc_4 = Sketch_3.addArc(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_2&ExtrusionCut_1_1/Modfied_4"))
 SketchConstraintCoincidence_18 = Sketch_3.setCoincident(SketchArc_3.endPoint(), SketchArc_4.results()[1])
 SketchConstraintCoincidence_18.setName("SketchConstraintCoincidence_19")
 SketchLine_12 = Sketch_3.addLine(-15, 46.0103340429751, -15, 35.00000000000001)
@@ -127,14 +128,16 @@ SketchConstraintCoincidence_23 = Sketch_3.setCoincident(SketchArc_3.results()[1]
 SketchConstraintCoincidence_23.setName("SketchConstraintCoincidence_24")
 model.do()
 ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_3_2f-SketchLine_12f-SketchArc_5_2r")], model.selection(), 5, 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
 Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_1_1/To_Face_1"))
-SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "ExtrusionFuse_1_1/Modfied_5&ExtrusionFuse_1_1/Modfied_4&ExtrusionFuse_1_1/To_Face_1"))
+SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "ExtrusionFuse_1_1/Modfied_4&ExtrusionFuse_1_1/Modfied_5&ExtrusionFuse_1_1/To_Face_1"))
 SketchCircle_2 = Sketch_4.addCircle(-15, 35.00000000000001, 5)
 SketchConstraintCoincidence_24 = Sketch_4.setCoincident(SketchPoint_4.result(), SketchCircle_2.center())
 SketchConstraintCoincidence_24.setName("SketchConstraintCoincidence_25")
 SketchConstraintRadius_4 = Sketch_4.setRadius(SketchCircle_2.results()[1], "10/2")
 model.do()
 ExtrusionFuse_2 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchCircle_2_2f")], model.selection(), 8, 0, [model.selection("SOLID", "ExtrusionFuse_1_1")])
+ExtrusionFuse_2.result().setName("ExtrusionFuse_2_1")
 Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
 SketchArc_6 = Sketch_5.addArc(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&ExtrusionFuse_1_1/Modfied_3"))
 SketchArc_7 = Sketch_5.addArc(-45, 35, -45, 5, -25.41666666666737, 12.27351642784166, False)
@@ -164,14 +167,15 @@ SketchConstraintCoincidence_33 = Sketch_5.setCoincident(SketchArc_9.startPoint()
 SketchConstraintCoincidence_33.setName("SketchConstraintCoincidence_34")
 model.do()
 ExtrusionFuse_3 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_7_2f-SketchArc_8_2r-SketchLine_13r-SketchArc_9_2r")], model.selection(), 0, 8, [model.selection("SOLID", "ExtrusionFuse_2_1")])
+ExtrusionFuse_3.result().setName("ExtrusionFuse_3_1")
 Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_3_1/Modfied_3"))
-SketchLine_14 = Sketch_6.addLine(model.selection("EDGE", "ExtrusionFuse_3_1/Modfied_3&Extrusion_1_1/Generated_Face_5"))
+SketchLine_14 = Sketch_6.addLine(model.selection("EDGE", "ExtrusionFuse_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7"))
 SketchArc_10 = Sketch_6.addArc(55, 35, 55, 15, 35, 35, True)
 SketchConstraintCoincidence_34 = Sketch_6.setCoincident(SketchLine_14.result(), SketchArc_10.center())
 SketchConstraintCoincidence_34.setName("SketchConstraintCoincidence_35")
 SketchConstraintCoincidence_35 = Sketch_6.setCoincident(SketchLine_14.result(), SketchArc_10.startPoint())
 SketchConstraintCoincidence_35.setName("SketchConstraintCoincidence_36")
-SketchLine_15 = Sketch_6.addLine(model.selection("EDGE", "ExtrusionFuse_3_1/Modfied_3&Extrusion_1_1/Generated_Face_4"))
+SketchLine_15 = Sketch_6.addLine(model.selection("EDGE", "ExtrusionFuse_3_1/Modfied_3&Extrusion_1_1/Generated_Face_8"))
 SketchConstraintDistance_8 = Sketch_6.setDistance(SketchArc_10.center(), SketchLine_15.result(), 35)
 SketchLine_16 = Sketch_6.addLine(35, 35, 35, 48)
 SketchConstraintCoincidence_36 = Sketch_6.setCoincident(SketchArc_10.endPoint(), SketchLine_16.startPoint())
@@ -194,9 +198,10 @@ SketchConstraintCoincidence_41 = Sketch_6.setCoincident(SketchLine_14.endPoint()
 SketchConstraintCoincidence_41.setName("SketchConstraintCoincidence_42")
 model.do()
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_6/Wire-SketchArc_10_2f-SketchLine_16r-SketchLine_18f-SketchLine_19r")], model.selection(), 0, 9, [model.selection("SOLID", "ExtrusionFuse_3_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_4"))
 SketchCircle_4 = Sketch_7.addCircle(45, 35, 5)
-SketchLine_20 = Sketch_7.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_1&ExtrusionCut_2_1/Modfied_4"))
+SketchLine_20 = Sketch_7.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&ExtrusionCut_2_1/Modfied_4"))
 SketchConstraintDistance_9 = Sketch_7.setDistance(SketchCircle_4.center(), SketchLine_20.result(), 10)
 SketchConstraintRadius_6 = Sketch_7.setRadius(SketchCircle_4.results()[1], "10/2")
 SketchLine_21 = Sketch_7.addLine(35, 35, 45, 35)
@@ -209,7 +214,8 @@ SketchConstraintCoincidence_43.setName("SketchConstraintCoincidence_44")
 SketchConstraintHorizontal_4 = Sketch_7.setHorizontal(SketchLine_21.result())
 model.do()
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_7/Face-SketchCircle_4_2f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/From_Face_1"), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_8"))
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
 SketchLine_22 = Sketch_8.addLine(55, 25, 5.000000000000002, 25)
 SketchLine_23 = Sketch_8.addLine(5.000000000000002, 25, 5.000000000000002, 13)
 SketchLine_24 = Sketch_8.addLine(5.000000000000002, 13, 55, 13)
@@ -228,15 +234,16 @@ SketchConstraintHorizontal_6 = Sketch_8.setHorizontal(SketchLine_24.result())
 SketchConstraintVertical_8 = Sketch_8.setVertical(SketchLine_25.result())
 SketchConstraintLength_2 = Sketch_8.setLength(SketchLine_22.result(), 50)
 SketchConstraintLength_3 = Sketch_8.setLength(SketchLine_25.result(), 12)
-SketchProjection_1 = Sketch_8.addProjection(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_1&ExtrusionCut_2_1/Modfied_2"))
+SketchProjection_1 = Sketch_8.addProjection(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&ExtrusionCut_2_1/Modfied_1"))
 SketchLine_26 = SketchProjection_1.createdFeature()
 SketchConstraintCoincidence_48 = Sketch_8.setCoincident(SketchLine_22.startPoint(), SketchLine_26.result())
 SketchConstraintCoincidence_48.setName("SketchConstraintCoincidence_49")
-SketchLine_27 = Sketch_8.addLine(model.selection("EDGE", "ExtrusionCut_3_1/Modfied_2&Extrusion_1_1/Generated_Face_8"))
+SketchLine_27 = Sketch_8.addLine(model.selection("EDGE", "ExtrusionCut_3_1/Modfied_2&Extrusion_1_1/Generated_Face_4"))
 SketchConstraintCoincidence_49 = Sketch_8.setCoincident(SketchLine_22.startPoint(), SketchLine_27.result())
 SketchConstraintCoincidence_49.setName("SketchConstraintCoincidence_50")
 model.do()
-ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_8"), 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
 Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_1_1/Modfied_2"))
 SketchLine_28 = Sketch_9.addLine(25, -45, 18.44853578320836, -63)
 SketchLine_29 = Sketch_9.addLine(model.selection("EDGE", "ExtrusionFuse_1_1/Modfied_2&ExtrusionCut_4_1/Modfied_6"))
@@ -259,6 +266,7 @@ SketchConstraintCoincidence_55 = Sketch_9.setCoincident(SketchLine_28.startPoint
 SketchConstraintCoincidence_55.setName("SketchConstraintCoincidence_56")
 model.do()
 ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchLine_28f-SketchLine_31f-SketchLine_32f")], model.selection(), model.selection(), 0, model.selection("FACE", "ExtrusionCut_4_1/Modfied_3"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
+ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
 Sketch_10 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_5_1/Modfied_1"))
 SketchCircle_5 = Sketch_10.addCircle(-6.000000000000002, 4.999999999999997, 5)
 SketchLine_33 = Sketch_10.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_3&ExtrusionCut_5_1/Modfied_1"))
@@ -268,6 +276,7 @@ SketchConstraintDistance_12 = Sketch_10.setDistance(SketchCircle_5.result(), Ske
 SketchConstraintRadius_7 = Sketch_10.setRadius(SketchCircle_5.results()[1], "10/2")
 model.do()
 ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_10/Face-SketchCircle_5_2f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
+ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
 model.do()
 
 # Test reexecution after parameter change
index 08f4d7b42b603e47de93a7cc4ac96878dfa18f0d..8bed73f7c2ca3fc2b5251eecc66efd1c4f38ef93 100644 (file)
@@ -141,6 +141,7 @@ model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_1_2f")], model.selection(), 75, 45)
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
 Boolean_1 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
+Boolean_1.result().setName("Boolean_1_1")
 Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
 SketchLine_20 = Sketch_4.addLine(-4, 38.00000000000001, -4, 21.26617031813674)
 SketchLine_20.setName("SketchLine_36")
@@ -353,9 +354,11 @@ model.do()
 Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 50, 30)
 Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
 Boolean_2 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], [model.selection("SOLID", "Extrusion_4_1")])
+Boolean_2.result().setName("Boolean_2_1")
 Extrusion_5 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
 Extrusion_6 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2f")], model.selection(), 75, 40)
 Boolean_3 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Extrusion_6_1")], [model.selection("SOLID", "Extrusion_5_1")])
+Boolean_3.result().setName("Boolean_3_1")
 Sketch_5 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
 SketchLine_38 = Sketch_5.addLine(44, 3.464101615137769, 17.52573586555855, 49.31887218898888)
 SketchLine_38.setName("SketchLine_41")
@@ -489,21 +492,24 @@ SketchConstraintCoincidence_90.setName("SketchConstraintCoincidence_94")
 model.do()
 Extrusion_7 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchLine_55r-SketchLine_44r-SketchLine_52r-SketchLine_53r-SketchLine_54r-SketchLine_47r-SketchLine_48r-SketchLine_49r-SketchArc_12_2r-SketchArc_13_2r")], model.selection(), 0, 40)
 Boolean_4 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Boolean_2_1")])
+Boolean_4.result().setName("Boolean_4_1")
 Boolean_5 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Boolean_4_1")], [model.selection("SOLID", "Extrusion_7_1")])
+Boolean_5.result().setName("Boolean_5_1")
 Boolean_6 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_5_1")], [model.selection("SOLID", "Boolean_3_1")])
+Boolean_6.result().setName("Boolean_6_1")
 Extrusion_8 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_10r-SketchLine_11r-SketchLine_8r-SketchLine_3r-SketchLine_9r-SketchLine_6r-SketchArc_1_2r-SketchArc_2_2f")], model.selection(), 55, 55)
-Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_8_1/Generated_Face_7"))
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_8_1/Generated_Face_1"))
 SketchLine_54 = Sketch_7.addLine(55, -9.237604307034024, 55, -60)
 SketchLine_54.setName("SketchLine_66")
 SketchLine_54.result().setName("SketchLine_66")
-SketchPoint_6 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_7&Extrusion_8_1/Generated_Face_6&Extrusion_8_1/To_Face_1"))
+SketchPoint_6 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_2&Extrusion_8_1/Generated_Face_1&Extrusion_8_1/To_Face_1"))
 SketchLine_55 = Sketch_7.addLine(55, -9.237604307034024, 55, -70)
 SketchLine_55.setName("SketchLine_57")
 SketchLine_55.result().setName("SketchLine_57")
 SketchLine_55.setAuxiliary(True)
 SketchConstraintCoincidence_91 = Sketch_7.setCoincident(SketchLine_55.startPoint(), SketchPoint_6.result())
 SketchConstraintCoincidence_91.setName("SketchConstraintCoincidence_95")
-SketchPoint_7 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_8&Extrusion_8_1/Generated_Face_7&Extrusion_8_1/To_Face_1"))
+SketchPoint_7 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_8&Extrusion_8_1/Generated_Face_1&Extrusion_8_1/To_Face_1"))
 SketchConstraintCoincidence_92 = Sketch_7.setCoincident(SketchLine_55.endPoint(), SketchPoint_7.result())
 SketchConstraintCoincidence_92.setName("SketchConstraintCoincidence_96")
 SketchLine_56 = Sketch_7.addLine(45.00000000000001, -70, -45.00000000000001, -70)
@@ -515,7 +521,7 @@ SketchLine_57.result().setName("SketchLine_58")
 SketchLine_57.setAuxiliary(True)
 SketchConstraintCoincidence_93 = Sketch_7.setCoincident(SketchLine_55.endPoint(), SketchLine_57.startPoint())
 SketchConstraintCoincidence_93.setName("SketchConstraintCoincidence_97")
-SketchPoint_8 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_8&Extrusion_8_1/Generated_Face_7&Extrusion_8_1/From_Face_1"))
+SketchPoint_8 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_8&Extrusion_8_1/Generated_Face_1&Extrusion_8_1/From_Face_1"))
 SketchConstraintCoincidence_94 = Sketch_7.setCoincident(SketchLine_57.endPoint(), SketchPoint_8.result())
 SketchConstraintCoincidence_94.setName("SketchConstraintCoincidence_98")
 SketchLine_58 = Sketch_7.addLine(-55.00000000000001, -59.99999999999999, -55, -9.237604307034024)
@@ -525,7 +531,7 @@ SketchLine_59 = Sketch_7.addLine(-55, -70, -55, -9.237604307034024)
 SketchLine_59.setAuxiliary(True)
 SketchConstraintCoincidence_95 = Sketch_7.setCoincident(SketchLine_57.endPoint(), SketchLine_59.startPoint())
 SketchConstraintCoincidence_95.setName("SketchConstraintCoincidence_99")
-SketchPoint_9 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_7&Extrusion_8_1/Generated_Face_6&Extrusion_8_1/From_Face_1"))
+SketchPoint_9 = Sketch_7.addPoint(model.selection("VERTEX", "Extrusion_8_1/Generated_Face_2&Extrusion_8_1/Generated_Face_1&Extrusion_8_1/From_Face_1"))
 SketchConstraintCoincidence_96 = Sketch_7.setCoincident(SketchLine_59.endPoint(), SketchPoint_9.result())
 SketchConstraintCoincidence_96.setName("SketchConstraintCoincidence_100")
 SketchLine_60 = Sketch_7.addLine(-55, -9.237604307034024, -61.32702426187202, -9.237604307034024)
@@ -605,7 +611,7 @@ SketchConstraintRadius_15 = Sketch_7.setRadius(SketchCircle_6.results()[1], 5)
 SketchCircle_7 = Sketch_7.addCircle(-44, -20.23760430703402, 5)
 SketchConstraintRadius_16 = Sketch_7.setRadius(SketchCircle_7.results()[1], 5)
 SketchConstraintDistance_31 = Sketch_7.setDistance(SketchCircle_6.center(), SketchLine_54.result(), 11)
-SketchLine_66 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_8_1/Generated_Face_7&Extrusion_8_1/Generated_Face_6"))
+SketchLine_66 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_8_1/Generated_Face_2&Extrusion_8_1/Generated_Face_1"))
 SketchLine_66.setName("SketchLine_69")
 SketchLine_66.result().setName("SketchLine_69")
 SketchConstraintDistance_32 = Sketch_7.setDistance(SketchCircle_6.center(), SketchLine_66.result(), 11)
@@ -613,18 +619,19 @@ SketchConstraintDistance_33 = Sketch_7.setDistance(SketchCircle_7.center(), Sket
 SketchConstraintDistance_34 = Sketch_7.setDistance(SketchCircle_7.center(), SketchLine_66.result(), 11)
 model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchLine_66f-SketchLine_67f-SketchLine_68f-SketchLine_60f-SketchLine_61f-SketchLine_62f-SketchLine_63f-SketchLine_64f-SketchArc_14_2r-SketchArc_15_2r"), model.selection("FACE", "Sketch_7/Face-SketchCircle_4_2f"), model.selection("FACE", "Sketch_7/Face-SketchCircle_5_2f"), model.selection("FACE", "Sketch_7/Face-SketchCircle_7_2f"), model.selection("FACE", "Sketch_7/Face-SketchCircle_6_2f")], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_8_1")])
-Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_8_1/Generated_Face_5"))
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_8_1/Generated_Face_3"))
 SketchLine_67 = Sketch_8.addLine(55, -34.06366588218793, 55, 66.69872981077805)
 SketchLine_67.setName("SketchLine_79")
 SketchLine_67.result().setName("SketchLine_79")
-SketchPoint_10 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_1&Extrusion_8_1/Generated_Face_5"))
+SketchPoint_10 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_1&Extrusion_8_1/Generated_Face_3"))
 SketchLine_68 = Sketch_8.addLine(55, -34.06366588218793, 55, 76.69872981077803)
 SketchLine_68.setName("SketchLine_70")
 SketchLine_68.result().setName("SketchLine_70")
 SketchLine_68.setAuxiliary(True)
 SketchConstraintCoincidence_116 = Sketch_8.setCoincident(SketchLine_68.startPoint(), SketchPoint_10.result())
 SketchConstraintCoincidence_116.setName("SketchConstraintCoincidence_120")
-SketchPoint_11 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_1&Extrusion_8_1/Generated_Face_5&Extrusion_8_1/Generated_Face_4"))
+SketchPoint_11 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_1&Extrusion_8_1/Generated_Face_3&Extrusion_8_1/Generated_Face_4"))
 SketchConstraintCoincidence_117 = Sketch_8.setCoincident(SketchLine_68.endPoint(), SketchPoint_11.result())
 SketchConstraintCoincidence_117.setName("SketchConstraintCoincidence_121")
 SketchLine_69 = Sketch_8.addLine(45, 76.69872981077805, -44.9999999570576, 76.69872981077805)
@@ -636,7 +643,7 @@ SketchLine_70.result().setName("SketchLine_71")
 SketchLine_70.setAuxiliary(True)
 SketchConstraintCoincidence_118 = Sketch_8.setCoincident(SketchLine_68.endPoint(), SketchLine_70.startPoint())
 SketchConstraintCoincidence_118.setName("SketchConstraintCoincidence_122")
-SketchPoint_12 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_3&Extrusion_8_1/Generated_Face_5&Extrusion_8_1/Generated_Face_4"))
+SketchPoint_12 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_3&Extrusion_8_1/Generated_Face_3&Extrusion_8_1/Generated_Face_4"))
 SketchConstraintCoincidence_119 = Sketch_8.setCoincident(SketchLine_70.endPoint(), SketchPoint_12.result())
 SketchConstraintCoincidence_119.setName("SketchConstraintCoincidence_123")
 SketchLine_71 = Sketch_8.addLine(-55, 66.69872976783566, -55, -34.06366588218793)
@@ -646,7 +653,7 @@ SketchLine_72 = Sketch_8.addLine(-55, 76.69872981077803, -55, -34.06366588218793
 SketchLine_72.setAuxiliary(True)
 SketchConstraintCoincidence_120 = Sketch_8.setCoincident(SketchLine_70.endPoint(), SketchLine_72.startPoint())
 SketchConstraintCoincidence_120.setName("SketchConstraintCoincidence_124")
-SketchPoint_13 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_3&Extrusion_8_1/Generated_Face_5"))
+SketchPoint_13 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_3&Extrusion_8_1/Generated_Face_3"))
 SketchConstraintCoincidence_121 = Sketch_8.setCoincident(SketchLine_72.endPoint(), SketchPoint_13.result())
 SketchConstraintCoincidence_121.setName("SketchConstraintCoincidence_125")
 SketchLine_73 = Sketch_8.addLine(-55, -34.06366588218793, -83.25521566485324, -34.06366588218793)
@@ -761,7 +768,9 @@ SketchConstraintDistance_44 = Sketch_8.setDistance(SketchArc_18.startPoint(), Sk
 SketchConstraintDistance_44.setName("SketchConstraintDistance_45")
 model.do()
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_79r-SketchLine_80r-SketchLine_81r-SketchLine_73r-SketchLine_74r-SketchLine_75r-SketchLine_76r-SketchLine_77r-SketchArc_16_2r-SketchArc_17_2r"), model.selection("WIRE", "Sketch_8/Wire-SketchCircle_8_2f"), model.selection("WIRE", "Sketch_8/Wire-SketchCircle_9_2f"), model.selection("WIRE", "Sketch_8/Wire-SketchArc_19_2f-SketchArc_18_2f-SketchLine_82f-SketchLine_83r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Boolean_7 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Boolean_6_1")], [model.selection("SOLID", "ExtrusionCut_2_1")])
+Boolean_7.result().setName("Boolean_7_1")
 model.do()
 
 # Test reexecution after parameter change
index 406f788e2671c8e00f411eecaa5b41797eee3eec..fc234273f2010e96e3b1491f6c0df56bc22c9f8c 100644 (file)
@@ -29,6 +29,7 @@ model.addParameter(partSet, "Rod", "12")
 model.addParameter(partSet, "Thickness", "25")
 Part_1 = model.addPart(partSet)
 Part_1.setName("Body")
+Part_1.result().setName("Part_1")
 Part_1_doc = Part_1.document()
 model.addParameter(Part_1_doc, "Radius", "50", "Radius of the body")
 model.addParameter(Part_1_doc, "Width", "25", "Width of body arms")
@@ -99,14 +100,14 @@ SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_5.startPoint(
 SketchConstraintCoincidence_10.setName("SketchConstraintCoincidence_35")
 model.do()
 Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_4r-SketchArc_1_2f-SketchArc_2_2f-SketchLine_28r-SketchLine_29r")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
-Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_5"))
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_2"))
 SketchLine_8 = Sketch_2.addLine(0, 0, 25, 43.30127018922193)
 SketchLine_8.setName("SketchLine_5")
 SketchLine_8.result().setName("SketchLine_5")
 SketchLine_8.setAuxiliary(True)
 SketchPoint_3 = Sketch_2.addPoint(model.selection("VERTEX", "PartSet/Origin"))
 SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_8.startPoint(), SketchPoint_3.result())
-SketchCircle_1 = Sketch_2.addCircle(model.selection("EDGE", "Revolution_1_1/Generated_Face_6&Revolution_1_1/Generated_Face_5"))
+SketchCircle_1 = Sketch_2.addCircle(model.selection("EDGE", "Revolution_1_1/Generated_Face_2&Revolution_1_1/Generated_Face_1"))
 SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
 SketchLine_9 = Sketch_2.addLine(39.43375672974064, -43.30127018922192, 15.87711932209923, -2.499977343709401)
 SketchLine_9.setName("SketchLine_10")
@@ -116,7 +117,7 @@ SketchLine_10.setName("SketchLine_6")
 SketchLine_10.result().setName("SketchLine_6")
 SketchLine_10.setAuxiliary(True)
 SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchLine_10.startPoint(), SketchPoint_3.result())
-SketchCircle_2 = Sketch_2.addCircle(model.selection("EDGE", "Revolution_1_1/Generated_Face_6&Revolution_1_1/Generated_Face_5"))
+SketchCircle_2 = Sketch_2.addCircle(model.selection("EDGE", "Revolution_1_1/Generated_Face_2&Revolution_1_1/Generated_Face_1"))
 SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchCircle_2.results()[1])
 SketchLine_11 = Sketch_2.addLine(15.87713238415337, 2.499999967850816, 39.43375672974065, 43.30127018922192)
 SketchLine_12 = Sketch_2.addLine(model.selection("EDGE", "PartSet/OX"))
@@ -227,9 +228,11 @@ SketchLine_22.result().setName("SketchLine_19")
 SketchConstraintDistance_9 = Sketch_2.setDistance(SketchArc_9.center(), SketchPoint_3.coordinates(), 21)
 SketchConstraintDistance_9.setName("SketchConstraintDistance_8")
 model.do()
-Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_10r-SketchLine_11r-SketchArc_3_2f-SketchArc_4_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_14r-SketchArc_7_2f-SketchLine_15r-SketchArc_8_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_12r-SketchArc_5_2f-SketchLine_13r-SketchArc_6_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_19f-SketchLine_20f-SketchLine_21f-SketchArc_10_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_16f-SketchLine_17f-SketchLine_18f-SketchArc_9_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchArc_11_2f")], model.selection(), model.selection(), 10, model.selection("FACE", "Revolution_1_1/Generated_Face_2"), 10)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_10r-SketchLine_11r-SketchArc_3_2f-SketchArc_4_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_14r-SketchArc_7_2f-SketchLine_15r-SketchArc_8_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_12r-SketchArc_5_2f-SketchLine_13r-SketchArc_6_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_19f-SketchLine_20f-SketchLine_21f-SketchArc_10_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_16f-SketchLine_17f-SketchLine_18f-SketchArc_9_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchArc_11_2f")], model.selection(), model.selection(), 10, model.selection("FACE", "Revolution_1_1/Generated_Face_5"), 10)
 Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_4"), model.selection("SOLID", "Extrusion_1_5")])
+Boolean_1.result().setName("Boolean_1_1")
 Boolean_2 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3"), model.selection("SOLID", "Extrusion_1_6")])
+Boolean_2.result().setName("Boolean_2_1")
 Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Boolean_2_1/Modified_7"), model.selection("FACE", "Boolean_2_1/Modified_9"))
 Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
 SketchCircle_3 = Sketch_3.addCircle(25, -10, 4)
@@ -254,15 +257,23 @@ SketchConstraintDistance_13.setName("SketchConstraintDistance_12")
 model.do()
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_3_2f"), model.selection("WIRE", "Sketch_3/Wire-SketchCircle_4_2f")], model.selection(), model.selection("FACE", "Boolean_1_1/Modified_6"), 5, model.selection("FACE", "Boolean_1_1/Modified_8"), 5)
 Boolean_3 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_2_1")], [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2")])
+Boolean_3.result().setName("Boolean_3_1")
 Recover_1 = model.addRecover(Part_1_doc, Boolean_3, [Extrusion_2.results()[1], Extrusion_2.result()])
 Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_1_1"), model.selection("SOLID", "Recover_1_2")], model.selection("EDGE", "PartSet/OZ"), 120)
+Rotation_1.result().setName("Rotation_1_1")
+Rotation_1.results()[1].setName("Rotation_1_2")
 Boolean_4 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_3_1")], [model.selection("SOLID", "Rotation_1_1"), model.selection("SOLID", "Rotation_1_2")])
+Boolean_4.result().setName("Boolean_4_1")
 Recover_2 = model.addRecover(Part_1_doc, Boolean_4, [Rotation_1.results()[1], Rotation_1.result()])
 Rotation_2 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_2_1"), model.selection("SOLID", "Recover_2_2")], model.selection("EDGE", "PartSet/OZ"), 120)
+Rotation_2.result().setName("Rotation_2_1")
+Rotation_2.results()[1].setName("Rotation_2_2")
 Boolean_5 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_4_1")], [model.selection("SOLID", "Rotation_2_2"), model.selection("SOLID", "Rotation_2_1")])
+Boolean_5.result().setName("Boolean_5_1")
 model.do()
 Part_2 = model.addPart(partSet)
 Part_2.setName("Arm 1")
+Part_2.result().setName("Part_2")
 Part_2_doc = Part_2.document()
 model.addParameter(Part_2_doc, "a", "7.5")
 model.addParameter(Part_2_doc, "b", "12.5")
@@ -497,24 +508,32 @@ model.do()
 Face_1 = model.addFace(Part_2_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchArc_4_2f-SketchArc_5_2f-SketchArc_6_2f-SketchArc_7_2f-SketchArc_8_2f-SketchArc_9_2f-SketchArc_10_2f")])
 Axis_4 = model.addAxis(Part_2_doc, model.selection("FACE", "PartSet/XOZ"), model.selection("VERTEX", "Sketch_2/Vertex-SketchArc_3-SketchLine_20s"))
 Rotation_3 = model.addRotation(Part_2_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "Axis_1"), -43.8752)
+Rotation_3.result().setName("Rotation_1_1")
 Pipe_1 = model.addPipe(Part_2_doc, [model.selection("FACE", "Rotation_1_1")], model.selection("EDGE", "Sketch_2/Edge-SketchArc_3_2"))
+Pipe_1.result().setName("Pipe_1_1")
 Extrusion_3 = model.addExtrusion(Part_2_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_2_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_14r-SketchLine_15r-SketchLine_16r-SketchLine_17r")], model.selection(), "Gap/2", "Gap/2")
 Boolean_6 = model.addFuse(Part_2_doc, [model.selection("SOLID", "Pipe_1_1")], [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2")])
+Boolean_6.result().setName("Boolean_1_1")
 Extrusion_4 = model.addExtrusion(Part_2_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_3_2f")], model.selection(), "Gap", "Gap")
 Boolean_7 = model.addCut(Part_2_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
+Boolean_7.result().setName("Boolean_2_1")
 Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Boolean_2_1")], model.selection("VERTEX", "Sketch_2/Vertex-SketchArc_3_2s"), model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_21e"))
+Translation_1.result().setName("Translation_1_1")
 model.do()
 Part_3 = model.duplicatePart(Part_2)
 Part_3.setName("Arm 2")
+Part_3.result().setName("Part_3")
 model.do()
 Part_4 = model.duplicatePart(Part_3)
 Part_4.setName("Arm 3")
+Part_4.result().setName("Part_4")
 model.do()
 Translation_4 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_2/"), model.selection("COMPOUND", "Part_3/"), model.selection("COMPOUND", "Part_4/")], model.selection("EDGE", "OX"), -40)
 Rotation_6 = model.addRotation(partSet, [model.selection("COMPOUND", "Translation_1_2/")], model.selection("EDGE", "OZ"), 120)
 Rotation_7 = model.addRotation(partSet, [model.selection("COMPOUND", "Translation_1_3/")], model.selection("EDGE", "OZ"), 240)
 Part_5 = model.addPart(partSet)
 Part_5.setName("Rod part")
+Part_5.result().setName("Part_5")
 Part_5_doc = Part_5.document()
 Parameter_H = model.addParameter(partSet, "H", "110")
 Sketch_10 = model.addSketch(Part_5_doc, model.defaultPlane("YOZ"))
@@ -546,7 +565,7 @@ SketchLine_99 = Sketch_10.addLine(model.selection("EDGE", "PartSet/OY"))
 SketchConstraintDistance_35 = Sketch_10.setDistance(SketchLine_98.endPoint(), SketchLine_99.result(), "Thickness")
 model.do()
 Revolution_2 = model.addRevolution(Part_5_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r-SketchLine_5r-SketchLine_6r")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_6"), 360, 0)
-Sketch_11 = model.addSketch(Part_5_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_5"))
+Sketch_11 = model.addSketch(Part_5_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_1"))
 SketchCircle_14 = Sketch_11.addCircle(0, 0, 8.5)
 SketchCircle_14.setAuxiliary(True)
 SketchPoint_8 = Sketch_11.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_6e"))
@@ -588,7 +607,7 @@ SketchConstraintCoincidence_248 = Sketch_12.setCoincident(SketchLine_106.startPo
 SketchConstraintHorizontal_20 = Sketch_12.setHorizontal(SketchLine_107.result())
 SketchConstraintVertical_20 = Sketch_12.setVertical(SketchLine_106.result())
 SketchConstraintAngle_8 = Sketch_12.setAngle(SketchLine_108.result(), SketchLine_107.result(), 30)
-SketchLine_109 = Sketch_12.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3"))
+SketchLine_109 = Sketch_12.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_3"))
 SketchConstraintCoincidence_249 = Sketch_12.setCoincident(SketchLine_108.endPoint(), SketchLine_109.result())
 SketchProjection_2 = Sketch_12.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"))
 SketchLine_110 = SketchProjection_2.createdFeature()
@@ -598,7 +617,9 @@ SketchConstraintDistance_37 = Sketch_12.setDistance(SketchLine_108.startPoint(),
 model.do()
 Revolution_3 = model.addRevolution(Part_5_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_14f-SketchLine_15f-SketchLine_16f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
 Boolean_12 = model.addCut(Part_5_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Revolution_2_1")])
+Boolean_12.result().setName("Boolean_1_1")
 Boolean_13 = model.addFuse(Part_5_doc, [model.selection("SOLID", "Boolean_1_1"), model.selection("SOLID", "Revolution_1_1")], [])
+Boolean_13.result().setName("Boolean_2_1")
 
 # Test reexecution after parameter change
 Parameter_H.setValue(120)
index 846b051b3a446a9986ef9841f3cd1a15bb1076b4..5db7d85c26a5532bf9d71b1e451447822ade6e2e 100644 (file)
@@ -79,6 +79,7 @@ SketchConstraintCoincidence_8 = Sketch_5.setCoincident(SketchAPI_Line(SketchLine
 SketchConstraintCoincidence_8.setName("SketchConstraintCoincidence_16")
 Extrusion_5.setNestedSketch(Sketch_5)
 Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_4_1"), model.selection("SOLID", "Extrusion_5_1"), model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_3_1")], [])
+Boolean_1.result().setName("Boolean_1_1")
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection("FACE", "Extrusion_5_1/To_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "Boolean_1_1")])
 Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/From_Face_1"))
 SketchCircle_6 = Sketch_6.addCircle(0, 0, 4.2)
@@ -87,6 +88,7 @@ SketchPoint_2 = Sketch_6.addPoint(model.selection("VERTEX", "PartSet/Origin"))
 SketchConstraintCoincidence_9 = Sketch_6.setCoincident(SketchPoint_2.coordinates(), SketchCircle_6.center())
 SketchConstraintCoincidence_9.setName("SketchConstraintCoincidence_17")
 ExtrusionCut_1.setNestedSketch(Sketch_6)
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
 SketchCircle_7 = Sketch_7.addCircle(0, -85, 66)
 SketchLine_6 = Sketch_7.addLine(model.selection("EDGE", "PartSet/OY"))
@@ -97,6 +99,7 @@ SketchMultiRotation_1 = Sketch_7.addRotation([SketchCircle_7.results()[1]], Sket
 [SketchCircle_8, SketchCircle_9] = SketchMultiRotation_1.rotated()
 model.do()
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_22"))
 SketchLine_7 = Sketch_8.addLine(-2.320957096353877e-016, 11.00000001704673, -7, 11.00000001704673)
 SketchConstraintHorizontal_1 = Sketch_8.setHorizontal(SketchLine_7.result())
index 42dcf26c4399e669bd1a0cdc903516dec8041e11..3690c9d3b03974561cbb10fc7d30863bc1d36bcb 100644 (file)
@@ -411,8 +411,11 @@ SketchConstraintRadius_10.setName("SketchConstraintRadius_4")
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), "TL/2-3", "TL/2-3")
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 100, 100, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), "TL/2", "TL/2", [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 60, 60, [model.selection("SOLID", "ExtrusionFuse_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Sketch_5 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
 SketchCircle_5 = Sketch_5.addCircle(30, -41, 7.5)
 SketchLine_37 = Sketch_5.addLine(model.selection("EDGE", "PartSet/OX"))
@@ -539,6 +542,7 @@ SketchConstraintRadius_13 = Sketch_7.setRadius(SketchArc_7.results()[1], "BHPFR"
 SketchConstraintRadius_13.setName("SketchConstraintRadius_8")
 model.do()
 RevolutionFuse_1 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection("EDGE", "Sketch_7/Edge-SketchLine_41"), 360, 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+RevolutionFuse_1.result().setName("RevolutionFuse_1_1")
 Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
 SketchLine_49 = Sketch_8.addLine(32, 6, 32.50001476412091, 6.000000000000001)
 SketchLine_49.setName("SketchLine_55")
@@ -635,6 +639,7 @@ SketchConstraintRadius_14 = Sketch_8.setRadius(SketchArc_8.results()[1], 1.5)
 SketchConstraintRadius_14.setName("SketchConstraintRadius_9")
 model.do()
 RevolutionFuse_2 = model.addRevolutionFuse(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_55r-SketchLine_49f-SketchLine_50f-SketchLine_56r-SketchLine_52f-SketchLine_53f-SketchArc_7_2r")], model.selection("EDGE", "Sketch_8/Edge-SketchLine_50"), 360, 0, [model.selection("SOLID", "RevolutionFuse_1_1")])
+RevolutionFuse_2.result().setName("RevolutionFuse_2_1")
 Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 30, True)
 Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
 SketchLine_57 = Sketch_9.addLine(-32.50001494742042, 5.999999999999998, -32, 6)
@@ -827,7 +832,9 @@ SketchConstraintRadius_16 = Sketch_10.setRadius(SketchArc_10.results()[1], 1.5)
 SketchConstraintRadius_16.setName("SketchConstraintRadius_11")
 model.do()
 RevolutionFuse_3 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "Sketch_9/Edge-SketchLine_58"), 360, 0, [model.selection("SOLID", "RevolutionFuse_2_1")])
+RevolutionFuse_3.result().setName("RevolutionFuse_3_1")
 RevolutionFuse_4 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_10")], model.selection("EDGE", "Sketch_10/Edge-SketchLine_66"), 360, 0, [model.selection("SOLID", "RevolutionFuse_3_1")])
+RevolutionFuse_4.result().setName("RevolutionFuse_4_1")
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchCircle_11_2f"), model.selection("FACE", "Sketch_6/Face-SketchCircle_9_2f"), model.selection("WIRE", "Sketch_6/Wire-SketchCircle_10_2f"), model.selection("FACE", "Sketch_6/Face-SketchCircle_12_2f")], model.selection("EDGE", "PartSet/OZ"), "BPS+5", 5, [model.selection("SOLID", "RevolutionFuse_4_1")])
 
 # Test reexecution after parameter change
index 2cf0f7929f70077410e8f14eb2523e05f700b822..f095cbb63e47ed54c2132aa19d46cd8d08a99de7 100644 (file)
@@ -583,8 +583,10 @@ SketchLine_379 = Sketch_3.addLine(model.selection("EDGE", "PartSet/OY"))
 SketchConstraintDistance_13 = Sketch_3.setDistance(SketchCircle_4.center(), SketchLine_379.result(), 15)
 model.do()
 Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_8f-SketchLine_9f-SketchLine_11f-SketchLine_12f-SketchLine_13f-SketchLine_14f")], model.selection("EDGE", "PartSet/OX"), 360, 0)
-ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_1_2r-SketchLine_382f-SketchLine_383f-SketchLine_20f-SketchArc_2_2r-SketchLine_21f-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f-SketchLine_30f-SketchLine_31f-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f-SketchLine_36f-SketchLine_37f-SketchLine_38f-SketchLine_39f-SketchLine_40f-SketchLine_41f-SketchLine_42f-SketchLine_43f-SketchLine_44f-SketchLine_45f-SketchLine_46f-SketchLine_47f-SketchLine_48f-SketchLine_49f-SketchLine_50f-SketchLine_51f-SketchLine_52f-SketchLine_53f-SketchLine_54f-SketchLine_55f-SketchLine_56f-SketchLine_57f-SketchLine_58f-SketchLine_59f-SketchLine_60f-SketchLine_61f-SketchLine_62f-SketchLine_63f-SketchLine_64f-SketchLine_65f-SketchLine_66f-SketchLine_67f-SketchLine_68f-SketchLine_69f-SketchLine_70f-SketchLine_71f-SketchLine_72f-SketchLine_73f-SketchLine_74f-SketchLine_75f-SketchLine_76f-SketchLine_77f-SketchLine_78f-SketchLine_79f-SketchLine_80f-SketchLine_81f-SketchLine_82f-SketchLine_83f-SketchLine_84f-SketchLine_85f-SketchLine_86f-SketchLine_87f-SketchLine_88f-SketchLine_89f-SketchLine_90f-SketchLine_91f-SketchLine_92f-SketchLine_93f-SketchLine_94f-SketchLine_95f-SketchLine_96f-SketchLine_97f-SketchLine_98f-SketchLine_99f-SketchLine_100f-SketchLine_101f-SketchLine_102f-SketchLine_103f-SketchLine_104f-SketchLine_105f-SketchLine_106f-SketchLine_107f-SketchLine_108f-SketchLine_109f-SketchLine_110f-SketchLine_111f-SketchLine_112f-SketchLine_113f-SketchLine_114f-SketchLine_115f-SketchLine_116f-SketchLine_117f-SketchLine_118f-SketchLine_119f-SketchLine_120f-SketchLine_121f-SketchLine_122f-SketchLine_123f-SketchLine_124f-SketchLine_125f-SketchLine_126f-SketchLine_127f-SketchLine_128f-SketchLine_129f-SketchLine_130f-SketchLine_131f-SketchLine_132f-SketchLine_133f-SketchLine_134f-SketchLine_135f-SketchLine_136f-SketchLine_137f-SketchLine_138f-SketchLine_139f-SketchLine_140f-SketchLine_141f-SketchLine_142f-SketchLine_143f-SketchLine_144f-SketchLine_145f-SketchLine_146f-SketchLine_147f-SketchLine_148f-SketchLine_149f-SketchLine_150f-SketchLine_151f-SketchLine_152f-SketchLine_153f-SketchLine_154f-SketchLine_155f-SketchLine_156f-SketchLine_157f-SketchLine_158f-SketchLine_159f-SketchLine_160f-SketchLine_161f-SketchLine_162f-SketchLine_163f-SketchLine_164f-SketchLine_165f-SketchLine_166f-SketchLine_167f-SketchLine_168f-SketchLine_169f-SketchLine_170f-SketchLine_171f-SketchLine_172f-SketchLine_173f-SketchLine_174f-SketchLine_175f-SketchLine_176f-SketchLine_177f-SketchLine_178f-SketchLine_179f-SketchLine_180f-SketchLine_181f-SketchLine_182f-SketchLine_183f-SketchLine_184f-SketchLine_185f-SketchLine_186f-SketchLine_187f-SketchLine_188f-SketchLine_189f-SketchLine_190f-SketchLine_191f-SketchLine_192f-SketchLine_193f-SketchLine_194f-SketchLine_195f-SketchLine_196f-SketchLine_197f-SketchLine_198f-SketchLine_199f-SketchArc_3_2r-SketchArc_4_2r-SketchArc_5_2r-SketchArc_6_2r-SketchArc_7_2r-SketchArc_8_2r-SketchArc_9_2r-SketchArc_10_2r-SketchArc_11_2r-SketchArc_12_2r-SketchArc_13_2r-SketchArc_14_2r-SketchArc_15_2r-SketchArc_16_2r-SketchArc_17_2r-SketchArc_18_2r-SketchArc_19_2r-SketchArc_20_2r-SketchArc_21_2r-SketchArc_22_2r-SketchArc_23_2r-SketchArc_24_2r-SketchArc_25_2r-SketchArc_26_2r-SketchArc_27_2r-SketchArc_28_2r-SketchArc_29_2r-SketchArc_30_2r-SketchArc_31_2r-SketchArc_32_2r-SketchArc_33_2r-SketchArc_34_2r-SketchArc_35_2r-SketchArc_36_2r-SketchArc_37_2r-SketchArc_38_2r-SketchArc_39_2r-SketchArc_40_2r-SketchArc_41_2r-SketchArc_42_2r-SketchArc_43_2r-SketchArc_44_2r-SketchArc_45_2r-SketchArc_46_2r-SketchArc_47_2r-SketchArc_48_2r-SketchArc_49_2r-SketchArc_50_2r-SketchArc_51_2r-SketchArc_52_2r-SketchArc_53_2r-SketchArc_54_2r-SketchArc_55_2r-SketchArc_56_2r-SketchArc_57_2r-SketchArc_58_2r-SketchArc_59_2r-SketchArc_60_2r-SketchArc_61_2r-SketchArc_62_2r-SketchArc_63_2r-SketchArc_64_2r-SketchArc_65_2r-SketchArc_66_2r-SketchArc_67_2r-SketchArc_68_2r-SketchArc_69_2r-SketchArc_70_2r-SketchArc_71_2r-SketchArc_72_2r-SketchArc_73_2r-SketchArc_74_2r-SketchArc_75_2r-SketchArc_76_2r-SketchArc_77_2r-SketchArc_78_2r-SketchArc_79_2r-SketchArc_80_2r-SketchArc_81_2r-SketchArc_82_2r-SketchArc_83_2r-SketchArc_84_2r-SketchArc_85_2r-SketchArc_86_2r-SketchArc_87_2r-SketchArc_88_2r-SketchArc_89_2r-SketchArc_90_2r-SketchArc_91_2r-SketchArc_92_2r-SketchArc_93_2r-SketchArc_94_2r-SketchArc_95_2r-SketchArc_96_2r-SketchArc_97_2r-SketchArc_98_2r-SketchArc_99_2r-SketchArc_100_2r-SketchArc_101_2r-SketchArc_102_2r-SketchArc_103_2r-SketchArc_104_2r-SketchArc_105_2r-SketchArc_106_2r-SketchArc_107_2r-SketchArc_108_2r-SketchArc_109_2r-SketchArc_110_2r-SketchArc_111_2r-SketchArc_112_2r-SketchArc_113_2r-SketchArc_114_2r-SketchArc_115_2r-SketchArc_116_2r-SketchArc_117_2r-SketchArc_118_2r-SketchArc_119_2r-SketchArc_120_2r-SketchArc_121_2r-SketchArc_122_2r-SketchArc_123_2r-SketchArc_124_2r-SketchArc_125_2r-SketchArc_126_2r-SketchArc_127_2r-SketchArc_128_2r-SketchArc_129_2r-SketchArc_130_2r-SketchArc_131_2r-SketchArc_132_2r-SketchArc_133_2r-SketchArc_134_2r-SketchArc_135_2r-SketchArc_136_2r-SketchArc_137_2r-SketchArc_138_2r-SketchArc_139_2r-SketchArc_140_2r-SketchArc_141_2r-SketchArc_142_2r-SketchArc_143_2r-SketchArc_144_2r-SketchArc_145_2r-SketchArc_146_2r-SketchArc_147_2r-SketchArc_148_2r-SketchArc_149_2r-SketchArc_150_2r-SketchArc_151_2r-SketchArc_152_2r-SketchArc_153_2r-SketchArc_154_2r-SketchArc_155_2r-SketchArc_156_2r-SketchArc_157_2r-SketchArc_158_2r-SketchArc_159_2r-SketchArc_160_2r-SketchArc_161_2r-SketchArc_162_2r-SketchArc_163_2r-SketchArc_164_2r-SketchArc_165_2r-SketchArc_166_2r-SketchArc_167_2r-SketchArc_168_2r-SketchArc_169_2r-SketchArc_170_2r-SketchArc_171_2r-SketchArc_172_2r-SketchArc_173_2r-SketchArc_174_2r-SketchArc_175_2r-SketchArc_176_2r-SketchArc_177_2r-SketchArc_178_2r-SketchArc_179_2r-SketchArc_180_2r-SketchLine_200f-SketchLine_201f-SketchLine_202f-SketchLine_203f-SketchLine_204f-SketchLine_205f-SketchLine_206f-SketchLine_207f-SketchLine_208f-SketchLine_209f-SketchLine_210f-SketchLine_211f-SketchLine_212f-SketchLine_213f-SketchLine_214f-SketchLine_215f-SketchLine_216f-SketchLine_217f-SketchLine_218f-SketchLine_219f-SketchLine_220f-SketchLine_221f-SketchLine_222f-SketchLine_223f-SketchLine_224f-SketchLine_225f-SketchLine_226f-SketchLine_227f-SketchLine_228f-SketchLine_229f-SketchLine_230f-SketchLine_231f-SketchLine_232f-SketchLine_233f-SketchLine_234f-SketchLine_235f-SketchLine_236f-SketchLine_237f-SketchLine_238f-SketchLine_239f-SketchLine_240f-SketchLine_241f-SketchLine_242f-SketchLine_243f-SketchLine_244f-SketchLine_245f-SketchLine_246f-SketchLine_247f-SketchLine_248f-SketchLine_249f-SketchLine_250f-SketchLine_251f-SketchLine_252f-SketchLine_253f-SketchLine_254f-SketchLine_255f-SketchLine_256f-SketchLine_257f-SketchLine_258f-SketchLine_259f-SketchLine_260f-SketchLine_261f-SketchLine_262f-SketchLine_263f-SketchLine_264f-SketchLine_265f-SketchLine_266f-SketchLine_267f-SketchLine_268f-SketchLine_269f-SketchLine_270f-SketchLine_271f-SketchLine_272f-SketchLine_273f-SketchLine_274f-SketchLine_275f-SketchLine_276f-SketchLine_277f-SketchLine_278f-SketchLine_279f-SketchLine_280f-SketchLine_281f-SketchLine_282f-SketchLine_283f-SketchLine_284f-SketchLine_285f-SketchLine_286f-SketchLine_287f-SketchLine_288f-SketchLine_289f-SketchLine_290f-SketchLine_291f-SketchLine_292f-SketchLine_293f-SketchLine_294f-SketchLine_295f-SketchLine_296f-SketchLine_297f-SketchLine_298f-SketchLine_299f-SketchLine_300f-SketchLine_301f-SketchLine_302f-SketchLine_303f-SketchLine_304f-SketchLine_305f-SketchLine_306f-SketchLine_307f-SketchLine_308f-SketchLine_309f-SketchLine_310f-SketchLine_311f-SketchLine_312f-SketchLine_313f-SketchLine_314f-SketchLine_315f-SketchLine_316f-SketchLine_317f-SketchLine_318f-SketchLine_319f-SketchLine_320f-SketchLine_321f-SketchLine_322f-SketchLine_323f-SketchLine_324f-SketchLine_325f-SketchLine_326f-SketchLine_327f-SketchLine_328f-SketchLine_329f-SketchLine_330f-SketchLine_331f-SketchLine_332f-SketchLine_333f-SketchLine_334f-SketchLine_335f-SketchLine_336f-SketchLine_337f-SketchLine_338f-SketchLine_339f-SketchLine_340f-SketchLine_341f-SketchLine_342f-SketchLine_343f-SketchLine_344f-SketchLine_345f-SketchLine_346f-SketchLine_347f-SketchLine_348f-SketchLine_349f-SketchLine_350f-SketchLine_351f-SketchLine_352f-SketchLine_353f-SketchLine_354f-SketchLine_355f-SketchLine_356f-SketchLine_357f-SketchLine_358f-SketchLine_359f-SketchLine_360f-SketchLine_361f-SketchLine_362f-SketchLine_363f-SketchLine_364f-SketchLine_365f-SketchLine_366f-SketchLine_367f-SketchLine_368f-SketchLine_369f-SketchLine_370f-SketchLine_371f-SketchLine_372f-SketchLine_373f-SketchLine_374f-SketchLine_375f-SketchLine_376f-SketchLine_377f-SketchCircle_3_2f")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_7"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_1_2r-SketchLine_382f-SketchLine_383f-SketchLine_20f-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f-SketchLine_30f-SketchLine_31f-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f-SketchLine_36f-SketchLine_37f-SketchLine_38f-SketchLine_39f-SketchLine_40f-SketchLine_41f-SketchLine_42f-SketchLine_43f-SketchLine_44f-SketchLine_45f-SketchLine_46f-SketchLine_47f-SketchLine_48f-SketchLine_49f-SketchLine_50f-SketchLine_51f-SketchLine_52f-SketchLine_53f-SketchLine_54f-SketchLine_55f-SketchLine_56f-SketchLine_57f-SketchLine_58f-SketchLine_59f-SketchLine_60f-SketchLine_61f-SketchLine_62f-SketchLine_63f-SketchLine_64f-SketchLine_65f-SketchLine_66f-SketchLine_67f-SketchLine_68f-SketchLine_69f-SketchLine_70f-SketchLine_71f-SketchLine_72f-SketchLine_73f-SketchLine_74f-SketchLine_75f-SketchLine_76f-SketchLine_77f-SketchLine_78f-SketchLine_79f-SketchLine_80f-SketchLine_81f-SketchLine_82f-SketchLine_83f-SketchLine_84f-SketchLine_85f-SketchLine_86f-SketchLine_87f-SketchLine_88f-SketchLine_89f-SketchLine_90f-SketchLine_91f-SketchLine_92f-SketchLine_93f-SketchLine_94f-SketchLine_95f-SketchLine_96f-SketchLine_97f-SketchLine_98f-SketchLine_99f-SketchLine_100f-SketchLine_101f-SketchLine_102f-SketchLine_103f-SketchLine_104f-SketchLine_105f-SketchLine_106f-SketchLine_107f-SketchLine_108f-SketchLine_109f-SketchLine_110f-SketchLine_111f-SketchLine_112f-SketchLine_113f-SketchLine_114f-SketchLine_115f-SketchLine_116f-SketchLine_117f-SketchLine_118f-SketchLine_119f-SketchLine_120f-SketchLine_121f-SketchLine_122f-SketchLine_123f-SketchLine_124f-SketchLine_125f-SketchLine_126f-SketchLine_127f-SketchLine_128f-SketchLine_129f-SketchLine_130f-SketchLine_131f-SketchLine_132f-SketchLine_133f-SketchLine_134f-SketchLine_135f-SketchLine_136f-SketchLine_137f-SketchLine_138f-SketchLine_139f-SketchLine_140f-SketchLine_141f-SketchLine_142f-SketchLine_143f-SketchLine_144f-SketchLine_145f-SketchLine_146f-SketchLine_147f-SketchLine_148f-SketchLine_149f-SketchLine_150f-SketchLine_151f-SketchLine_152f-SketchLine_153f-SketchLine_154f-SketchLine_155f-SketchLine_156f-SketchLine_157f-SketchLine_158f-SketchLine_159f-SketchLine_160f-SketchLine_161f-SketchLine_162f-SketchLine_163f-SketchLine_164f-SketchLine_165f-SketchLine_166f-SketchLine_167f-SketchLine_168f-SketchLine_169f-SketchLine_170f-SketchLine_171f-SketchLine_172f-SketchLine_173f-SketchLine_174f-SketchLine_175f-SketchLine_176f-SketchLine_177f-SketchLine_178f-SketchLine_179f-SketchLine_180f-SketchLine_181f-SketchLine_182f-SketchLine_183f-SketchLine_184f-SketchLine_185f-SketchLine_186f-SketchLine_187f-SketchLine_188f-SketchLine_189f-SketchLine_190f-SketchLine_191f-SketchLine_192f-SketchLine_193f-SketchLine_194f-SketchLine_195f-SketchLine_196f-SketchLine_197f-SketchLine_198f-SketchLine_199f-SketchArc_2_2r-SketchArc_3_2r-SketchArc_4_2r-SketchArc_5_2r-SketchArc_6_2r-SketchArc_7_2r-SketchArc_8_2r-SketchArc_9_2r-SketchArc_10_2r-SketchArc_11_2r-SketchArc_12_2r-SketchArc_13_2r-SketchArc_14_2r-SketchArc_15_2r-SketchArc_16_2r-SketchArc_17_2r-SketchArc_18_2r-SketchArc_19_2r-SketchArc_20_2r-SketchArc_21_2r-SketchArc_22_2r-SketchArc_23_2r-SketchArc_24_2r-SketchArc_25_2r-SketchArc_26_2r-SketchArc_27_2r-SketchArc_28_2r-SketchArc_29_2r-SketchArc_30_2r-SketchArc_31_2r-SketchArc_32_2r-SketchArc_33_2r-SketchArc_34_2r-SketchArc_35_2r-SketchArc_36_2r-SketchArc_37_2r-SketchArc_38_2r-SketchArc_39_2r-SketchArc_40_2r-SketchArc_41_2r-SketchArc_42_2r-SketchArc_43_2r-SketchArc_44_2r-SketchArc_45_2r-SketchArc_46_2r-SketchArc_47_2r-SketchArc_48_2r-SketchArc_49_2r-SketchArc_50_2r-SketchArc_51_2r-SketchArc_52_2r-SketchArc_53_2r-SketchArc_54_2r-SketchArc_55_2r-SketchArc_56_2r-SketchArc_57_2r-SketchArc_58_2r-SketchArc_59_2r-SketchArc_60_2r-SketchArc_61_2r-SketchArc_62_2r-SketchArc_63_2r-SketchArc_64_2r-SketchArc_65_2r-SketchArc_66_2r-SketchArc_67_2r-SketchArc_68_2r-SketchArc_69_2r-SketchArc_70_2r-SketchArc_71_2r-SketchArc_72_2r-SketchArc_73_2r-SketchArc_74_2r-SketchArc_75_2r-SketchArc_76_2r-SketchArc_77_2r-SketchArc_78_2r-SketchArc_79_2r-SketchArc_80_2r-SketchArc_81_2r-SketchArc_82_2r-SketchArc_83_2r-SketchArc_84_2r-SketchArc_85_2r-SketchArc_86_2r-SketchArc_87_2r-SketchArc_88_2r-SketchArc_89_2r-SketchArc_90_2r-SketchArc_91_2r-SketchArc_92_2r-SketchArc_93_2r-SketchArc_94_2r-SketchArc_95_2r-SketchArc_96_2r-SketchArc_97_2r-SketchArc_98_2r-SketchArc_99_2r-SketchArc_100_2r-SketchArc_101_2r-SketchArc_102_2r-SketchArc_103_2r-SketchArc_104_2r-SketchArc_105_2r-SketchArc_106_2r-SketchArc_107_2r-SketchArc_108_2r-SketchArc_109_2r-SketchArc_110_2r-SketchArc_111_2r-SketchArc_112_2r-SketchArc_113_2r-SketchArc_114_2r-SketchArc_115_2r-SketchArc_116_2r-SketchArc_117_2r-SketchArc_118_2r-SketchArc_119_2r-SketchArc_120_2r-SketchArc_121_2r-SketchArc_122_2r-SketchArc_123_2r-SketchArc_124_2r-SketchArc_125_2r-SketchArc_126_2r-SketchArc_127_2r-SketchArc_128_2r-SketchArc_129_2r-SketchArc_130_2r-SketchArc_131_2r-SketchArc_132_2r-SketchArc_133_2r-SketchArc_134_2r-SketchArc_135_2r-SketchArc_136_2r-SketchArc_137_2r-SketchArc_138_2r-SketchArc_139_2r-SketchArc_140_2r-SketchArc_141_2r-SketchArc_142_2r-SketchArc_143_2r-SketchArc_144_2r-SketchArc_145_2r-SketchArc_146_2r-SketchArc_147_2r-SketchArc_148_2r-SketchArc_149_2r-SketchArc_150_2r-SketchArc_151_2r-SketchArc_152_2r-SketchArc_153_2r-SketchArc_154_2r-SketchArc_155_2r-SketchArc_156_2r-SketchArc_157_2r-SketchArc_158_2r-SketchArc_159_2r-SketchArc_160_2r-SketchArc_161_2r-SketchArc_162_2r-SketchArc_163_2r-SketchArc_164_2r-SketchArc_165_2r-SketchArc_166_2r-SketchArc_167_2r-SketchArc_168_2r-SketchArc_169_2r-SketchArc_170_2r-SketchArc_171_2r-SketchArc_172_2r-SketchArc_173_2r-SketchArc_174_2r-SketchArc_175_2r-SketchArc_176_2r-SketchArc_177_2r-SketchArc_178_2r-SketchArc_179_2r-SketchArc_180_2r-SketchLine_21f-SketchLine_200f-SketchLine_201f-SketchLine_202f-SketchLine_203f-SketchLine_204f-SketchLine_205f-SketchLine_206f-SketchLine_207f-SketchLine_208f-SketchLine_209f-SketchLine_210f-SketchLine_211f-SketchLine_212f-SketchLine_213f-SketchLine_214f-SketchLine_215f-SketchLine_216f-SketchLine_217f-SketchLine_218f-SketchLine_219f-SketchLine_220f-SketchLine_221f-SketchLine_222f-SketchLine_223f-SketchLine_224f-SketchLine_225f-SketchLine_226f-SketchLine_227f-SketchLine_228f-SketchLine_229f-SketchLine_230f-SketchLine_231f-SketchLine_232f-SketchLine_233f-SketchLine_234f-SketchLine_235f-SketchLine_236f-SketchLine_237f-SketchLine_238f-SketchLine_239f-SketchLine_240f-SketchLine_241f-SketchLine_242f-SketchLine_243f-SketchLine_244f-SketchLine_245f-SketchLine_246f-SketchLine_247f-SketchLine_248f-SketchLine_249f-SketchLine_250f-SketchLine_251f-SketchLine_252f-SketchLine_253f-SketchLine_254f-SketchLine_255f-SketchLine_256f-SketchLine_257f-SketchLine_258f-SketchLine_259f-SketchLine_260f-SketchLine_261f-SketchLine_262f-SketchLine_263f-SketchLine_264f-SketchLine_265f-SketchLine_266f-SketchLine_267f-SketchLine_268f-SketchLine_269f-SketchLine_270f-SketchLine_271f-SketchLine_272f-SketchLine_273f-SketchLine_274f-SketchLine_275f-SketchLine_276f-SketchLine_277f-SketchLine_278f-SketchLine_279f-SketchLine_280f-SketchLine_281f-SketchLine_282f-SketchLine_283f-SketchLine_284f-SketchLine_285f-SketchLine_286f-SketchLine_287f-SketchLine_288f-SketchLine_289f-SketchLine_290f-SketchLine_291f-SketchLine_292f-SketchLine_293f-SketchLine_294f-SketchLine_295f-SketchLine_296f-SketchLine_297f-SketchLine_298f-SketchLine_299f-SketchLine_300f-SketchLine_301f-SketchLine_302f-SketchLine_303f-SketchLine_304f-SketchLine_305f-SketchLine_306f-SketchLine_307f-SketchLine_308f-SketchLine_309f-SketchLine_310f-SketchLine_311f-SketchLine_312f-SketchLine_313f-SketchLine_314f-SketchLine_315f-SketchLine_316f-SketchLine_317f-SketchLine_318f-SketchLine_319f-SketchLine_320f-SketchLine_321f-SketchLine_322f-SketchLine_323f-SketchLine_324f-SketchLine_325f-SketchLine_326f-SketchLine_327f-SketchLine_328f-SketchLine_329f-SketchLine_330f-SketchLine_331f-SketchLine_332f-SketchLine_333f-SketchLine_334f-SketchLine_335f-SketchLine_336f-SketchLine_337f-SketchLine_338f-SketchLine_339f-SketchLine_340f-SketchLine_341f-SketchLine_342f-SketchLine_343f-SketchLine_344f-SketchLine_345f-SketchLine_346f-SketchLine_347f-SketchLine_348f-SketchLine_349f-SketchLine_350f-SketchLine_351f-SketchLine_352f-SketchLine_353f-SketchLine_354f-SketchLine_355f-SketchLine_356f-SketchLine_357f-SketchLine_358f-SketchLine_359f-SketchLine_360f-SketchLine_361f-SketchLine_362f-SketchLine_363f-SketchLine_364f-SketchLine_365f-SketchLine_366f-SketchLine_367f-SketchLine_368f-SketchLine_369f-SketchLine_370f-SketchLine_371f-SketchLine_372f-SketchLine_373f-SketchLine_374f-SketchLine_375f-SketchLine_376f-SketchLine_377f-SketchCircle_3_2f")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_5"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_4_2f")], model.selection(), 30, 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 
 # Test reexecution after parameter change
 Parameter_H.setValue(14)
index 6a874b4274fc94426f40e6e18442233abd794523..569774775979a22d82aededb3bbcea0d71b763f1 100644 (file)
@@ -82,6 +82,7 @@ SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_3.endPoint(), Sketc
 model.do()
 Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_7r-SketchLine_1r-SketchLine_2r-SketchLine_8r-SketchArc_1_2f")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 0, 180)
 ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_7r-SketchLine_1r-SketchLine_2r-SketchLine_8r-SketchArc_1_2f")], model.selection(), 0, 25, [model.selection("SOLID", "Revolution_1_1")])
+ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
 Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
 SketchLine_9 = Sketch_2.addLine(0, 20, -17.00000285538278, 20)
 SketchLine_9.setName("SketchLine_13")
@@ -127,6 +128,7 @@ SketchConstraintDistance_3 = Sketch_2.setDistance(SketchLine_10.startPoint(), Sk
 SketchConstraintDistance_4 = Sketch_2.setDistance(SketchLine_11.endPoint(), SketchLine_10.result(), 20)
 model.do()
 ExtrusionFuse_2 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_13f-SketchLine_9f-SketchLine_10f-SketchLine_14f-SketchArc_2_2f")], model.selection(), 0, 25, [model.selection("SOLID", "ExtrusionFuse_1_1")])
+ExtrusionFuse_2.result().setName("ExtrusionFuse_2_1")
 Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_2_1/Modfied_8"))
 SketchLine_15 = Sketch_3.addLine(0, -20, -17.00000002635728, -20)
 SketchLine_15.setName("SketchLine_19")
@@ -134,7 +136,7 @@ SketchLine_15.result().setName("SketchLine_19")
 SketchLine_16 = Sketch_3.addLine(-20, 0, 0, 0)
 SketchLine_16.setName("SketchLine_15")
 SketchLine_16.result().setName("SketchLine_15")
-SketchPoint_2 = Sketch_3.addPoint(model.selection("VERTEX", "ExtrusionFuse_2_1/Modfied_7&ExtrusionFuse_2_1/Modfied_5&ExtrusionFuse_2_1/Modfied_8&ExtrusionFuse_2_1/Modfied_11"))
+SketchPoint_2 = Sketch_3.addPoint(model.selection("VERTEX", "ExtrusionFuse_2_1/Modfied_7&ExtrusionFuse_2_1/Modfied_6&ExtrusionFuse_2_1/Modfied_8&ExtrusionFuse_2_1/Modfied_9"))
 SketchConstraintCoincidence_23 = Sketch_3.setCoincident(SketchLine_16.endPoint(), SketchPoint_2.result())
 SketchLine_17 = Sketch_3.addLine(0, 0, 0, -20)
 SketchLine_17.setName("SketchLine_16")
@@ -175,6 +177,7 @@ SketchConstraintParallel_1 = Sketch_3.setParallel(SketchLine_17.result(), Sketch
 SketchConstraintDistance_7 = Sketch_3.setDistance(SketchLine_21.startPoint(), SketchLine_18.result(), 3)
 model.do()
 RevolutionFuse_1 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection("EDGE", "Sketch_3/Edge-SketchLine_21"), 71, 0, [model.selection("SOLID", "ExtrusionFuse_2_1")])
+RevolutionFuse_1.result().setName("RevolutionFuse_1_1")
 Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "RevolutionFuse_1_1/Modfied_7"))
 SketchLine_22 = Sketch_4.addLine(-3, -20, 17.00000452949485, -20)
 SketchLine_22.setName("SketchLine_26")
@@ -224,6 +227,7 @@ SketchConstraintParallel_2 = Sketch_4.setParallel(SketchLine_25.result(), Sketch
 SketchConstraintDistance_11 = Sketch_4.setDistance(SketchLine_23.startPoint(), SketchLine_29.result(), 3)
 model.do()
 RevolutionFuse_2 = model.addRevolutionFuse(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchLine_26f-SketchLine_22f-SketchLine_23f-SketchLine_27f-SketchArc_4_2f")], model.selection("EDGE", "Sketch_4/Edge-SketchLine_29"), 0, 71, [model.selection("SOLID", "RevolutionFuse_1_1")])
+RevolutionFuse_2.result().setName("RevolutionFuse_2_1")
 Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
 SketchLine_30 = Sketch_5.addLine(0, 0, 0, 82)
 SketchLine_31 = Sketch_5.addLine(model.selection("EDGE", "PartSet/OZ"))
@@ -305,6 +309,7 @@ SketchConstraintDistance_15 = Sketch_5.setDistance(SketchLine_37.startPoint(), S
 SketchConstraintDistance_15.setName("SketchConstraintDistance_16")
 model.do()
 RevolutionFuse_3 = model.addRevolutionFuse(Part_1_doc, [model.selection("WIRE", "Sketch_5/Wire-SketchLine_30r-SketchLine_39r-SketchLine_32r-SketchLine_40r-SketchLine_38r-SketchArc_6_2f-SketchArc_7_2r")], model.selection("EDGE", "PartSet/OZ"), 45, 315, [model.selection("SOLID", "RevolutionFuse_2_1")])
+RevolutionFuse_3.result().setName("RevolutionFuse_3_1")
 Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
 SketchLine_38 = Sketch_6.addLine(19.99999999999999, 60, -20, 60)
 SketchLine_38.setName("SketchLine_48")
@@ -411,6 +416,7 @@ SketchConstraintCoincidence_84 = Sketch_6.setCoincident(SketchLine_41.startPoint
 SketchConstraintCoincidence_84.setName("SketchConstraintCoincidence_156")
 model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), 100, 0, [model.selection("SOLID", "RevolutionFuse_3_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
 SketchLine_50 = Sketch_7.addLine(65, 23.09999999999939, 65, 23.00000523211526)
 SketchLine_50.setName("SketchLine_61")
@@ -494,6 +500,7 @@ SketchConstraintDistance_21 = Sketch_7.setDistance(SketchLine_50.startPoint(), S
 SketchConstraintDistance_21.setName("SketchConstraintDistance_23")
 model.do()
 RevolutionFuse_4 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection("EDGE", "PartSet/OZ"), 14.4, 14.4, [model.selection("SOLID", "ExtrusionCut_1_1")])
+RevolutionFuse_4.result().setName("RevolutionFuse_4_1")
 Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
 SketchCircle_1 = Sketch_8.addCircle(0, 45, 12.5)
 SketchLine_60 = Sketch_8.addLine(model.selection("EDGE", "Sketch_5/Edge-SketchLine_30"))
@@ -510,6 +517,7 @@ SketchConstraintRadius_8 = Sketch_8.setRadius(SketchCircle_1.results()[1], 12.5)
 SketchConstraintRadius_8.setName("SketchConstraintRadius_13")
 model.do()
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchCircle_1_2f")], model.selection(), 100, 100, [model.selection("SOLID", "RevolutionFuse_4_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Sketch_9 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
 SketchLine_62 = Sketch_9.addLine(0, 84, 0, -2)
 SketchLine_62.setName("SketchLine_65")
@@ -648,7 +656,7 @@ Sketch_10 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
 SketchLine_77 = Sketch_10.addLine(64, 20, 89, 20)
 SketchLine_77.setName("SketchLine_76")
 SketchLine_77.result().setName("SketchLine_76")
-SketchPoint_4 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_2_1/Modfied_11&RevolutionFuse_2_1/Modfied_13&RevolutionFuse_3_1/Modfied_15&RevolutionFuse_3_1/Modfied_4"))
+SketchPoint_4 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_2_1/Modfied_11&RevolutionFuse_2_1/Modfied_15&RevolutionFuse_3_1/Modfied_15&RevolutionFuse_3_1/Modfied_4"))
 SketchConstraintCoincidence_122 = Sketch_10.setCoincident(SketchLine_77.startPoint(), SketchPoint_4.result())
 SketchConstraintCoincidence_122.setName("SketchConstraintCoincidence_120")
 SketchPoint_5 = Sketch_10.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_8e-SketchLine_4e"))
@@ -657,10 +665,10 @@ SketchConstraintCoincidence_123.setName("SketchConstraintCoincidence_121")
 SketchLine_78 = Sketch_10.addLine(64, -20, 89, -20)
 SketchLine_78.setName("SketchLine_77")
 SketchLine_78.result().setName("SketchLine_77")
-SketchPoint_6 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_1_1/Modfied_4&RevolutionFuse_1_1/Modfied_9&RevolutionFuse_3_1/Modfied_17&RevolutionFuse_3_1/Modfied_8"))
+SketchPoint_6 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_1_1/Modfied_4&RevolutionFuse_1_1/Modfied_10&RevolutionFuse_3_1/Modfied_17&RevolutionFuse_3_1/Modfied_8"))
 SketchConstraintCoincidence_124 = Sketch_10.setCoincident(SketchLine_78.startPoint(), SketchPoint_6.result())
 SketchConstraintCoincidence_124.setName("SketchConstraintCoincidence_122")
-SketchPoint_7 = Sketch_10.addPoint(model.selection("VERTEX", "ExtrusionFuse_2_1/Modfied_2&RevolutionFuse_1_1/Modfied_4&ExtrusionFuse_2_1/Modfied_1&RevolutionFuse_3_1/Modfied_17"))
+SketchPoint_7 = Sketch_10.addPoint(model.selection("VERTEX", "ExtrusionFuse_2_1/Modfied_3&RevolutionFuse_1_1/Modfied_4&ExtrusionFuse_2_1/Modfied_4&RevolutionFuse_3_1/Modfied_17"))
 SketchConstraintCoincidence_125 = Sketch_10.setCoincident(SketchLine_78.endPoint(), SketchPoint_7.result())
 SketchConstraintCoincidence_125.setName("SketchConstraintCoincidence_123")
 SketchArc_10 = Sketch_10.addArc(89.00000104846708, 1.669244441022778e-015, 89, -20, 89, 20, False)
@@ -683,7 +691,7 @@ SketchConstraintCoincidence_129 = Sketch_10.setCoincident(SketchArc_11.startPoin
 SketchConstraintCoincidence_129.setName("SketchConstraintCoincidence_127")
 SketchConstraintTangent_19 = Sketch_10.setTangent(SketchArc_11.results()[1], SketchLine_78.result())
 SketchConstraintTangent_19.setName("SketchConstraintTangent_24")
-SketchPoint_8 = Sketch_10.addPoint(model.selection("VERTEX", "ExtrusionCut_2_1/Modfied_9&RevolutionFuse_3_1/Modfied_7&RevolutionFuse_3_1/Modfied_8&RevolutionFuse_3_1/Modfied_24&RevolutionFuse_3_1/Modfied_9"))
+SketchPoint_8 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_3_1/Modfied_9&RevolutionFuse_3_1/Modfied_8&ExtrusionCut_2_1/Modfied_5&RevolutionFuse_3_1/Modfied_7&RevolutionFuse_3_1/Modfied_24"))
 SketchConstraintCoincidence_130 = Sketch_10.setCoincident(SketchArc_11.endPoint(), SketchPoint_8.result())
 SketchConstraintCoincidence_130.setName("SketchConstraintCoincidence_128")
 SketchArc_12 = Sketch_10.addArc(64.00001789135865, 23.01137360115889, 64, 20, 61.15622559702543, 22.02080994708722, True)
@@ -694,7 +702,7 @@ SketchConstraintCoincidence_131 = Sketch_10.setCoincident(SketchArc_12.startPoin
 SketchConstraintCoincidence_131.setName("SketchConstraintCoincidence_129")
 SketchConstraintTangent_20 = Sketch_10.setTangent(SketchArc_12.results()[1], SketchLine_77.result())
 SketchConstraintTangent_20.setName("SketchConstraintTangent_25")
-SketchPoint_9 = Sketch_10.addPoint(model.selection("VERTEX", "ExtrusionCut_2_1/Modfied_9&RevolutionFuse_3_1/Modfied_3&RevolutionFuse_3_1/Modfied_4&RevolutionFuse_3_1/Modfied_24&RevolutionFuse_3_1/Modfied_5"))
+SketchPoint_9 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_3_1/Modfied_5&RevolutionFuse_3_1/Modfied_4&ExtrusionCut_2_1/Modfied_5&RevolutionFuse_3_1/Modfied_3&RevolutionFuse_3_1/Modfied_24"))
 SketchConstraintCoincidence_132 = Sketch_10.setCoincident(SketchArc_12.endPoint(), SketchPoint_9.result())
 SketchConstraintCoincidence_132.setName("SketchConstraintCoincidence_130")
 SketchLine_79 = Sketch_10.addLine(61.15622559702543, 22.02080994708722, 59.81204392543111, 22.0208099470871)
@@ -763,6 +771,7 @@ SketchArc_13.result().setName("SketchArc_16")
 SketchArc_13.results()[1].setName("SketchArc_16_2")
 model.do()
 ExtrusionFuse_3 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_10/Face-SketchArc_16_2f-SketchLine_81r-SketchLine_82f-SketchArc_17_2r-SketchLine_83f-SketchLine_84f-SketchLine_85r-SketchArc_18_2r"), model.selection("FACE", "Sketch_10/Face-SketchArc_19_2f-SketchLine_86r-SketchLine_87f-SketchArc_20_2r-SketchLine_88f-SketchLine_89f-SketchLine_90r-SketchArc_21_2r")], model.selection(), 20, 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+ExtrusionFuse_3.result().setName("ExtrusionFuse_3_1")
 Sketch_11 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
 SketchCircle_2 = Sketch_11.addCircle(89, 0, 6)
 SketchPoint_11 = Sketch_11.addPoint(model.selection("VERTEX", "Sketch_2/Vertex-SketchPoint_1-SketchLine_10s-SketchLine_9e"))
@@ -782,8 +791,11 @@ SketchMultiRotation_2 = Sketch_11.addRotation([SketchCircle_3.results()[1], Sket
 [SketchCircle_4, SketchCircle_5, SketchCircle_6, SketchCircle_7] = SketchMultiRotation_2.rotated()
 model.do()
 RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "PartSet/OZ"), 0, 360, [model.selection("SOLID", "ExtrusionFuse_3_1")])
+RevolutionCut_1.result().setName("RevolutionCut_1_1")
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_11/Wire-SketchCircle_4_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_3_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_5_2f")], model.selection(), 30, -15, [model.selection("SOLID", "RevolutionCut_1_1")])
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
 ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_11/Wire-SketchCircle_2_2f"), model.selection("FACE", "Sketch_11/Face-SketchCircle_6_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_7_2f")], model.selection(), 30, 2, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
 
 # Test reexecution after parameter change
 Parameter_R.setValue(5)
index 9e13a063c4bcaf3f2f548f22e37b4ca9a3cf037f..368df3b77d10c96c80931b4ab85891efcdb35e72 100644 (file)
@@ -147,7 +147,7 @@ SketchLine_14.result().setName("SketchLine_16")
 SketchConstraintCoincidence_20 = Sketch_2.setCoincident(SketchArc_3.endPoint(), SketchLine_14.result())
 SketchConstraintCoincidence_20.setName("SketchConstraintCoincidence_24")
 SketchConstraintRadius_2 = Sketch_2.setRadius(SketchArc_3.results()[1], 6)
-SketchLine_15 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_13&Extrusion_1_1/Generated_Face_1"))
+SketchLine_15 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_13&Extrusion_1_1/Generated_Face_12"))
 SketchLine_15.setName("SketchLine_17")
 SketchLine_15.result().setName("SketchLine_17")
 SketchConstraintDistance_8 = Sketch_2.setDistance(SketchArc_3.startPoint(), SketchLine_15.result(), 6)
@@ -181,12 +181,13 @@ SketchConstraintCoincidence_26 = Sketch_2.setCoincident(SketchArc_3.endPoint(),
 SketchConstraintCoincidence_26.setName("SketchConstraintCoincidence_30")
 model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_3_2r-SketchLine_18r-SketchLine_19r-SketchLine_20r-SketchLine_21r-SketchLine_22r")], model.selection(), 7, 15, [model.selection("SOLID", "Extrusion_1_1")])
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_9"))
 SketchLine_21 = Sketch_3.addLine(28, -6, -4.270492394552598, -6.000000000000001)
 SketchLine_21.setName("SketchLine_23")
 SketchLine_21.result().setName("SketchLine_23")
 SketchLine_21.setAuxiliary(True)
-SketchLine_22 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"))
+SketchLine_22 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_9"))
 SketchLine_22.setName("SketchLine_24")
 SketchLine_22.result().setName("SketchLine_24")
 SketchConstraintCoincidence_27 = Sketch_3.setCoincident(SketchLine_21.startPoint(), SketchLine_22.result())
@@ -304,26 +305,27 @@ SketchConstraintCoincidence_51.setName("SketchConstraintCoincidence_55")
 SketchConstraintMiddle_2 = Sketch_3.setMiddlePoint(SketchLine_34.result(), SketchPoint_4.coordinates())
 SketchConstraintCoincidence_52 = Sketch_3.setCoincident(SketchPoint_4.coordinates(), SketchLine_21.result())
 SketchConstraintCoincidence_52.setName("SketchConstraintCoincidence_56")
-SketchLine_35 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&ExtrusionCut_1_1/Modfied_4"))
+SketchLine_35 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&ExtrusionCut_1_1/Modfied_3"))
 SketchLine_35.setName("SketchLine_37")
 SketchLine_35.result().setName("SketchLine_37")
 SketchConstraintCoincidence_53 = Sketch_3.setCoincident(SketchLine_25.startPoint(), SketchLine_35.result())
 SketchConstraintCoincidence_53.setName("SketchConstraintCoincidence_57")
 SketchConstraintLength_10 = Sketch_3.setLength(SketchLine_24.result(), 31)
 SketchConstraintLength_10.setName("SketchConstraintLength_11")
-SketchLine_36 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"))
+SketchLine_36 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_5"))
 SketchLine_36.setName("SketchLine_38")
 SketchLine_36.result().setName("SketchLine_38")
 SketchConstraintCoincidence_54 = Sketch_3.setCoincident(SketchLine_30.startPoint(), SketchLine_36.result())
 SketchConstraintCoincidence_54.setName("SketchConstraintCoincidence_58")
 SketchConstraintEqual_2 = Sketch_3.setEqual(SketchLine_30.result(), SketchLine_25.result())
 model.do()
-ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_3"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
 SketchLine_37 = Sketch_4.addLine(0.4324637622511017, 3.581086955422081, 1.55585595716119, 2.812450190483599)
 SketchLine_37.setName("SketchLine_39")
 SketchLine_37.result().setName("SketchLine_39")
-SketchLine_38 = Sketch_4.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_11"))
+SketchLine_38 = Sketch_4.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_2"))
 SketchLine_38.setName("SketchLine_40")
 SketchLine_38.result().setName("SketchLine_40")
 SketchConstraintCoincidence_55 = Sketch_4.setCoincident(SketchLine_37.startPoint(), SketchLine_38.result())
@@ -370,7 +372,8 @@ SketchLine_41.setName("SketchLine_43")
 SketchLine_41.result().setName("SketchLine_43")
 model.do()
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_12"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_1"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
 Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
 SketchArc_4 = Sketch_5.addArc(25.00007393928819, -7.521062532210847, 22.00014787857639, -7.5, 28, -7.5, True)
 SketchPoint_5 = Sketch_5.addPoint(22.00014787857639, -7.5)
@@ -413,7 +416,9 @@ model.do()
 Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_3"), 6, True)
 Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 3, True)
 ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), 3, 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
 ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), model.selection("FACE", "Plane_3"), 0, model.selection("FACE", "Plane_2"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
+ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
 Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_6"))
 SketchArc_5 = Sketch_6.addArc(45.99999999999999, 0, 45.49999999999999, 8.91700958118717e-020, 46.49999999999999, 8.280962276646116e-019, False)
 SketchLine_53 = Sketch_6.addLine(0, 0, 54, 0)
@@ -465,6 +470,7 @@ SketchLine_56.setName("SketchLine_58")
 SketchLine_56.result().setName("SketchLine_58")
 model.do()
 ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
+ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
 Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_12"))
 SketchLine_64 = Sketch_7.addLine(50.25000000000001, -4.5, 31.24999999998802, -4.499999999999997)
 SketchLine_64.setName("SketchLine_76")
@@ -636,6 +642,7 @@ SketchConstraintRadius_7 = Sketch_7.setRadius(SketchArc_15.results()[1], 0.25)
 SketchConstraintRadius_8 = Sketch_7.setRadius(SketchArc_17.results()[1], 0.25)
 model.do()
 ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionFuse_1_1")])
+ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
 Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_17"))
 SketchPoint_12 = Sketch_8.addPoint(53.99994409538203, -1.615587133892632e-027)
 SketchPoint_13 = Sketch_8.addPoint(53.99994409538203, -1.615587133892632e-027)
@@ -784,6 +791,7 @@ SketchConstraintCoincidence_141 = Sketch_8.setCoincident(SketchPoint_21.coordina
 SketchConstraintCoincidence_141.setName("SketchConstraintCoincidence_145")
 model.do()
 ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_6_1")])
+ExtrusionCut_7.result().setName("ExtrusionCut_7_1")
 Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_56"))
 SketchLine_94 = Sketch_9.addLine(21.00014787857639, 4.163450069699051, 21.00014787857639, 0)
 SketchLine_94.setName("SketchLine_107")
@@ -927,6 +935,7 @@ model.do()
 Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 4, False)
 Plane_8 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 4, True)
 ExtrusionCut_8 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection(), model.selection("FACE", "Plane_5"), 0, model.selection("FACE", "Plane_4"), 0, [model.selection("SOLID", "ExtrusionCut_7_1")])
+ExtrusionCut_8.result().setName("ExtrusionCut_8_1")
 Sketch_10 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_8_1/Modfied_5"))
 SketchCircle_1 = Sketch_10.addCircle(12, 6, 1)
 SketchConstraintRadius_11 = Sketch_10.setRadius(SketchCircle_1.results()[1], 1)
@@ -953,6 +962,7 @@ SketchConstraintCoincidence_173.setName("SketchConstraintCoincidence_178")
 SketchConstraintDistance_17 = Sketch_10.setDistance(SketchLine_105.result(), SketchCircle_1.center(), 12)
 model.do()
 ExtrusionCut_9 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_10/Wire-SketchCircle_1_2f")], model.selection(), 0, 0.75, [model.selection("SOLID", "ExtrusionCut_8_1")])
+ExtrusionCut_9.result().setName("ExtrusionCut_9_1")
 model.do()
 Part_2 = model.addPart(partSet)
 Part_2_doc = Part_2.document()
@@ -1078,7 +1088,7 @@ SketchLine_120.result().setName("SketchLine_16")
 SketchConstraintCoincidence_193 = Sketch_12.setCoincident(SketchArc_26.endPoint(), SketchLine_120.result())
 SketchConstraintCoincidence_193.setName("SketchConstraintCoincidence_24")
 SketchConstraintRadius_13 = Sketch_12.setRadius(SketchArc_26.results()[1], 6)
-SketchLine_121 = Sketch_12.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_13&Extrusion_1_1/Generated_Face_1"))
+SketchLine_121 = Sketch_12.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_13&Extrusion_1_1/Generated_Face_12"))
 SketchLine_121.setName("SketchLine_17")
 SketchLine_121.result().setName("SketchLine_17")
 SketchConstraintDistance_25 = Sketch_12.setDistance(SketchArc_26.startPoint(), SketchLine_121.result(), 6)
@@ -1112,12 +1122,13 @@ SketchConstraintCoincidence_199 = Sketch_12.setCoincident(SketchArc_26.endPoint(
 SketchConstraintCoincidence_199.setName("SketchConstraintCoincidence_30")
 model.do()
 ExtrusionCut_10 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_3_2r-SketchLine_18r-SketchLine_19r-SketchLine_20r-SketchLine_21r-SketchLine_22r")], model.selection(), 7, 15, [model.selection("SOLID", "Extrusion_1_1")])
-Sketch_13 = model.addSketch(Part_2_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+ExtrusionCut_10.result().setName("ExtrusionCut_1_1")
+Sketch_13 = model.addSketch(Part_2_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_9"))
 SketchLine_127 = Sketch_13.addLine(28, -6, -4.270492394552598, -6.000000000000001)
 SketchLine_127.setName("SketchLine_23")
 SketchLine_127.result().setName("SketchLine_23")
 SketchLine_127.setAuxiliary(True)
-SketchLine_128 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"))
+SketchLine_128 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_9"))
 SketchLine_128.setName("SketchLine_24")
 SketchLine_128.result().setName("SketchLine_24")
 SketchConstraintCoincidence_200 = Sketch_13.setCoincident(SketchLine_127.startPoint(), SketchLine_128.result())
@@ -1235,26 +1246,27 @@ SketchConstraintCoincidence_224.setName("SketchConstraintCoincidence_55")
 SketchConstraintMiddle_10 = Sketch_13.setMiddlePoint(SketchLine_140.result(), SketchPoint_28.coordinates())
 SketchConstraintCoincidence_225 = Sketch_13.setCoincident(SketchPoint_28.coordinates(), SketchLine_127.result())
 SketchConstraintCoincidence_225.setName("SketchConstraintCoincidence_56")
-SketchLine_141 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&ExtrusionCut_1_1/Modfied_4"))
+SketchLine_141 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&ExtrusionCut_1_1/Modfied_3"))
 SketchLine_141.setName("SketchLine_37")
 SketchLine_141.result().setName("SketchLine_37")
 SketchConstraintCoincidence_226 = Sketch_13.setCoincident(SketchLine_131.startPoint(), SketchLine_141.result())
 SketchConstraintCoincidence_226.setName("SketchConstraintCoincidence_57")
 SketchConstraintLength_27 = Sketch_13.setLength(SketchLine_130.result(), 31)
 SketchConstraintLength_27.setName("SketchConstraintLength_11")
-SketchLine_142 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"))
+SketchLine_142 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_5"))
 SketchLine_142.setName("SketchLine_38")
 SketchLine_142.result().setName("SketchLine_38")
 SketchConstraintCoincidence_227 = Sketch_13.setCoincident(SketchLine_136.startPoint(), SketchLine_142.result())
 SketchConstraintCoincidence_227.setName("SketchConstraintCoincidence_58")
 SketchConstraintEqual_5 = Sketch_13.setEqual(SketchLine_136.result(), SketchLine_131.result())
 model.do()
-ExtrusionCut_11 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_3"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_11 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_11.result().setName("ExtrusionCut_2_1")
 Sketch_14 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
 SketchLine_143 = Sketch_14.addLine(0.4324637622511017, 3.581086955422081, 1.55585595716119, 2.812450190483599)
 SketchLine_143.setName("SketchLine_39")
 SketchLine_143.result().setName("SketchLine_39")
-SketchLine_144 = Sketch_14.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_11"))
+SketchLine_144 = Sketch_14.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_2"))
 SketchLine_144.setName("SketchLine_40")
 SketchLine_144.result().setName("SketchLine_40")
 SketchConstraintCoincidence_228 = Sketch_14.setCoincident(SketchLine_143.startPoint(), SketchLine_144.result())
@@ -1301,7 +1313,8 @@ SketchLine_147.setName("SketchLine_43")
 SketchLine_147.result().setName("SketchLine_43")
 model.do()
 ExtrusionCut_12 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-Plane_9 = model.addPlane(Part_2_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_12"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
+ExtrusionCut_12.result().setName("ExtrusionCut_3_1")
+Plane_9 = model.addPlane(Part_2_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_1"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
 Sketch_15 = model.addSketch(Part_2_doc, model.selection("FACE", "Plane_1"))
 SketchArc_27 = Sketch_15.addArc(25.00007393928819, -7.521062532210847, 22.00014787857639, -7.5, 28, -7.5, True)
 SketchPoint_29 = Sketch_15.addPoint(22.00014787857639, -7.5)
@@ -1344,7 +1357,9 @@ model.do()
 Plane_10 = model.addPlane(Part_2_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_3"), 6, True)
 Plane_11 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 3, True)
 ExtrusionCut_13 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), 3, 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_13.result().setName("ExtrusionCut_4_1")
 ExtrusionCut_14 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), model.selection("FACE", "Plane_3"), 0, model.selection("FACE", "Plane_2"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
+ExtrusionCut_14.result().setName("ExtrusionCut_5_1")
 Sketch_16 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_6"))
 SketchArc_28 = Sketch_16.addArc(45.99999999999999, 0, 45.49999999999999, 8.91700958118717e-020, 46.49999999999999, 8.280962276646116e-019, False)
 SketchLine_159 = Sketch_16.addLine(0, 0, 54, 0)
@@ -1396,6 +1411,7 @@ SketchLine_162.setName("SketchLine_58")
 SketchLine_162.result().setName("SketchLine_58")
 model.do()
 ExtrusionFuse_2 = model.addExtrusionFuse(Part_2_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
+ExtrusionFuse_2.result().setName("ExtrusionFuse_1_1")
 Sketch_17 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_12"))
 SketchLine_170 = Sketch_17.addLine(50.25000000000001, -4.5, 31.24999999998802, -4.499999999999997)
 SketchLine_170.setName("SketchLine_76")
@@ -1567,6 +1583,7 @@ SketchConstraintRadius_18 = Sketch_17.setRadius(SketchArc_38.results()[1], 0.25)
 SketchConstraintRadius_19 = Sketch_17.setRadius(SketchArc_40.results()[1], 0.25)
 model.do()
 ExtrusionCut_15 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionFuse_1_1")])
+ExtrusionCut_15.result().setName("ExtrusionCut_6_1")
 Sketch_18 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_17"))
 SketchPoint_36 = Sketch_18.addPoint(53.99994409538203, -1.615587133892632e-027)
 SketchPoint_37 = Sketch_18.addPoint(53.99994409538203, -1.615587133892632e-027)
@@ -1715,6 +1732,7 @@ SketchConstraintCoincidence_314 = Sketch_18.setCoincident(SketchPoint_45.coordin
 SketchConstraintCoincidence_314.setName("SketchConstraintCoincidence_145")
 model.do()
 ExtrusionCut_16 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_6_1")])
+ExtrusionCut_16.result().setName("ExtrusionCut_7_1")
 Sketch_19 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_56"))
 SketchLine_200 = Sketch_19.addLine(21.00014787857639, 4.163450069699051, 21.00014787857639, 0)
 SketchLine_200.setName("SketchLine_107")
@@ -1858,6 +1876,7 @@ model.do()
 Plane_12 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 4, False)
 Plane_13 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 4, True)
 ExtrusionCut_17 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection(), model.selection("FACE", "Plane_5"), 0, model.selection("FACE", "Plane_4"), 0, [model.selection("SOLID", "ExtrusionCut_7_1")])
+ExtrusionCut_17.result().setName("ExtrusionCut_8_1")
 Sketch_20 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_8_1/Modfied_5"))
 SketchCircle_2 = Sketch_20.addCircle(12, 6, 1)
 SketchConstraintRadius_22 = Sketch_20.setRadius(SketchCircle_2.results()[1], 1)
@@ -1884,6 +1903,7 @@ SketchConstraintCoincidence_346.setName("SketchConstraintCoincidence_178")
 SketchConstraintDistance_34 = Sketch_20.setDistance(SketchLine_211.result(), SketchCircle_2.center(), 12)
 model.do()
 ExtrusionCut_18 = model.addExtrusionCut(Part_2_doc, [model.selection("WIRE", "Sketch_10/Wire-SketchCircle_1_2f")], model.selection(), 0, 0.75, [model.selection("SOLID", "ExtrusionCut_8_1")])
+ExtrusionCut_18.result().setName("ExtrusionCut_9_1")
 model.do()
 Rotation_1 = model.addRotation(partSet, [model.selection("COMPOUND", "Part_2/")], model.selection("EDGE", "Part_1/ExtrusionCut_9_1/Modfied_1&ExtrusionCut_7_1/Modfied_57"), 180)
 Placement_1 = model.addPlacement(partSet, [model.selection("COMPOUND", "Rotation_1/")], model.selection("FACE", "Rotation_1/ExtrusionCut_5_1/Modfied_1"), model.selection("FACE", "Part_1/ExtrusionCut_5_1/Modfied_1"), False, True)
index 2a2fdae039ebe07d6d2c0f251a83db20c0195315..8f5c6417c76764f524391ca60044cb8b6cf8655b 100644 (file)
@@ -117,9 +117,10 @@ SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_5.result(), S
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_10f-SketchLine_11f-SketchLine_12f-SketchLine_13f-SketchLine_4f-SketchLine_8f-SketchLine_9f-SketchArc_1_2r-SketchArc_2_2f")], model.selection(), "307/2.", "307/2.")
 Extrusion_1.setName("Profil")
-Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_7"))
+Extrusion_1.result().setName("Extrusion_1_1")
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
 SketchLine_14 = Sketch_2.addLine(149.5, -2.3, 153.5, -2.3)
-SketchPoint_1 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_1"))
+SketchPoint_1 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"))
 SketchConstraintCoincidence_24 = Sketch_2.setCoincident(SketchLine_14.endPoint(), SketchPoint_1.result())
 SketchLine_15 = Sketch_2.addLine(153.5, -2.3, 153.5, 7.7)
 SketchLine_16 = Sketch_2.addLine(153.5, 7.7, 149.5, 7.7)
@@ -149,24 +150,25 @@ SketchConstraintLength_5 = Sketch_2.setLength(SketchLine_21.result(), 10)
 SketchConstraintLength_5.setName("SketchConstraintLength_6")
 SketchConstraintDistance_2 = Sketch_2.setDistance(SketchLine_16.endPoint(), SketchLine_21.result(), 299)
 SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_16.result(), SketchLine_20.result())
-SketchPoint_2 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_1"))
+SketchPoint_2 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"))
 SketchPoint_2.setName("SketchPoint_4")
 SketchPoint_2.result().setName("SketchPoint_4")
 SketchConstraintCoincidence_34 = Sketch_2.setCoincident(SketchLine_19.startPoint(), SketchPoint_2.coordinates())
 SketchConstraintCoincidence_34.setName("SketchConstraintCoincidence_39")
 model.do()
-ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_6"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_1_1")])
 ExtrusionCut_1.setName("Decoupe_Angle")
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_8"))
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"))
 SketchLine_22 = Sketch_3.addLine(153.5, -10.3, 153.5, -8.3)
 SketchLine_22.setName("SketchLine_29")
 SketchLine_22.result().setName("SketchLine_29")
-SketchPoint_3 = Sketch_3.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_9&ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_8"))
+SketchPoint_3 = Sketch_3.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_2"))
 SketchPoint_3.setName("SketchPoint_5")
 SketchPoint_3.result().setName("SketchPoint_5")
 SketchConstraintCoincidence_35 = Sketch_3.setCoincident(SketchLine_22.startPoint(), SketchPoint_3.result())
 SketchConstraintCoincidence_35.setName("SketchConstraintCoincidence_40")
-SketchLine_23 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_8"))
+SketchLine_23 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_2"))
 SketchLine_23.setName("SketchLine_30")
 SketchLine_23.result().setName("SketchLine_30")
 SketchConstraintCoincidence_36 = Sketch_3.setCoincident(SketchLine_22.endPoint(), SketchLine_23.result())
@@ -204,16 +206,17 @@ Sketch_3.setName("Sketch_4")
 Sketch_3.result().setName("Sketch_4")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_1_1")])
 ExtrusionCut_2.setName("Chamfrein_1")
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_7"))
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_5"))
 SketchLine_30 = Sketch_4.addLine(-149.5, 10.3, -149.5, 8.3)
 SketchLine_30.setName("SketchLine_35")
 SketchLine_30.result().setName("SketchLine_35")
-SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_11&ExtrusionCut_1_1/Modfied_7&ExtrusionCut_1_1/Modfied_6"))
+SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_11&ExtrusionCut_1_1/Modfied_5&ExtrusionCut_1_1/Modfied_6"))
 SketchPoint_4.setName("SketchPoint_6")
 SketchPoint_4.result().setName("SketchPoint_6")
 SketchConstraintCoincidence_42 = Sketch_4.setCoincident(SketchLine_30.startPoint(), SketchPoint_4.result())
 SketchConstraintCoincidence_42.setName("SketchConstraintCoincidence_43")
-SketchLine_31 = Sketch_4.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_11&ExtrusionCut_1_1/Modfied_7"))
+SketchLine_31 = Sketch_4.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_11&ExtrusionCut_1_1/Modfied_5"))
 SketchLine_31.setName("SketchLine_36")
 SketchLine_31.result().setName("SketchLine_36")
 SketchConstraintCoincidence_43 = Sketch_4.setCoincident(SketchLine_30.endPoint(), SketchLine_31.result())
@@ -288,15 +291,16 @@ SketchConstraintCoincidence_54.setName("SketchConstraintCoincidence_59")
 model.do()
 Sketch_4.setName("Sketch_5")
 Sketch_4.result().setName("Sketch_5")
-ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_5")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_5"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_9"))
+ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_5")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_7"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_3"))
 SketchLine_40 = Sketch_5.addLine(152.2999838762584, -21.04999053274691, 153.5, -21.04999053274714)
 SketchLine_40.setName("SketchLine_58")
 SketchLine_40.result().setName("SketchLine_58")
 SketchLine_41 = Sketch_5.addLine(152.2999838292651, -45.04999053274704, 153.5, -45.04999053274702)
 SketchLine_41.setName("SketchLine_57")
 SketchLine_41.result().setName("SketchLine_57")
-SketchLine_42 = Sketch_5.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&ExtrusionCut_1_1/Modfied_9"))
+SketchLine_42 = Sketch_5.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&ExtrusionCut_1_1/Modfied_3"))
 SketchLine_42.setName("SketchLine_46")
 SketchLine_42.result().setName("SketchLine_46")
 SketchLine_43 = Sketch_5.addLine(150.8, -45.04999053274702, 153.5, -45.04999053274702)
@@ -507,6 +511,7 @@ model.do()
 Sketch_5.setName("Sketch_6")
 Sketch_5.result().setName("Sketch_6")
 ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_6/Wire-SketchArc_9_2f-SketchArc_10_2f-SketchLine_73r-SketchLine_74r-SketchLine_75r-SketchLine_76r"), model.selection("WIRE", "Sketch_6/Wire-SketchLine_58f-SketchLine_61f-SketchLine_60f-SketchLine_51f-SketchArc_4_2f-SketchArc_5_2f"), model.selection("WIRE", "Sketch_6/Wire-SketchLine_57f-SketchLine_47f-SketchLine_62f-SketchLine_63f-SketchArc_3_2f-SketchArc_6_2f")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
 Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_1"))
 SketchArc_11 = Sketch_6.addArc(44.89, -23.54999053274703, 43.89, -23.54999053274703, 44.89, -22.54999053274703, False)
 SketchArc_12 = Sketch_6.addArc(44.89, -13.54999053274703, 44.89, -14.54999053274703, 43.89, -13.54999053274703, False)
@@ -843,6 +848,7 @@ model.do()
 Sketch_6.setName("Sketch_7")
 Sketch_6.result().setName("Sketch_7")
 ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchArc_20_2f-SketchArc_21_2f-SketchArc_22_2f-SketchArc_23_2f-SketchLine_91r-SketchLine_92f-SketchLine_93r-SketchLine_94f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_52_2f-SketchArc_53_2f-SketchArc_56_2f-SketchArc_57_2f-SketchLine_114r-SketchLine_115f-SketchLine_116r-SketchLine_121f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_44_2f-SketchArc_45_2f-SketchArc_48_2f-SketchArc_49_2f-SketchLine_107f-SketchLine_113f-SketchLine_117r-SketchLine_123r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_16_2f-SketchArc_17_2f-SketchArc_18_2f-SketchArc_19_2f-SketchLine_87f-SketchLine_88f-SketchLine_89r-SketchLine_90r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_11_2f-SketchArc_12_2f-SketchArc_14_2f-SketchLine_81f-SketchLine_82r-SketchLine_83f-SketchLine_84r-SketchArc_15_2f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_36_2f-SketchArc_38_2f-SketchArc_40_2f-SketchArc_41_2f-SketchLine_108r-SketchLine_119r-SketchLine_127f-SketchLine_129f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_37_2f-SketchArc_39_2f-SketchArc_42_2f-SketchArc_43_2f-SketchLine_118r-SketchLine_120f-SketchLine_122r-SketchLine_130f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_24_2f-SketchArc_25_2f-SketchArc_26_2f-SketchArc_27_2f-SketchLine_98f-SketchLine_100r-SketchLine_101f-SketchLine_103r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_30_2f-SketchArc_31_2f-SketchArc_34_2f-SketchArc_35_2f-SketchLine_95f-SketchLine_96r-SketchLine_97f-SketchLine_105r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_46_2f-SketchArc_47_2f-SketchArc_50_2f-SketchArc_51_2f-SketchLine_124f-SketchLine_125r-SketchLine_126f-SketchLine_128r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_54_2f-SketchArc_55_2f-SketchArc_58_2f-SketchArc_59_2f-SketchLine_109f-SketchLine_110r-SketchLine_111r-SketchLine_112f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_28_2f-SketchArc_29_2f-SketchArc_32_2f-SketchArc_33_2f-SketchLine_99r-SketchLine_102f-SketchLine_104f-SketchLine_106r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_4_1")])
+ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
 Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_5_1/Modfied_1"))
 SketchLine_126 = Sketch_7.addLine(-153.5, -37.049990532747, -152.3000099350335, -37.0499905327475)
 SketchLine_126.setName("SketchLine_135")
@@ -936,6 +942,7 @@ model.do()
 Sketch_7.setName("Sketch_8")
 Sketch_7.result().setName("Sketch_8")
 ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_5_1")])
+ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
 Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_2"))
 SketchLine_134 = Sketch_8.addLine(0.85, 50.75, -0.85, 50.75)
 SketchLine_134.setName("SketchLine_139")
@@ -1060,6 +1067,7 @@ model.do()
 Sketch_8.setName("Sketch_9")
 Sketch_8.result().setName("Sketch_9")
 ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchLine_147f-SketchLine_148f-SketchArc_64_2f-SketchArc_65_2f"), model.selection("FACE", "Sketch_9/Face-SketchLine_139f-SketchLine_141f-SketchArc_63_2f-SketchArc_62_2f"), model.selection("FACE", "Sketch_9/Face-SketchArc_66_2f-SketchArc_67_2f-SketchLine_149r-SketchLine_150r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_6_1")])
+ExtrusionCut_7.result().setName("ExtrusionCut_7_1")
 model.do()
 
 # Test reexecution after parameter change
index 540cc8535229c313f1b9be617fe212980769115b..2ab00bd2eba47eceffc3cf5f546b0c9056e9aaae 100644 (file)
@@ -83,6 +83,7 @@ SketchConstraintCoincidence_16 = Sketch_2.setCoincident(SketchArc_9.endPoint(),
 model.do()
 Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_9_2f-SketchLine_11f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
 Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Revolution_1_1")])
+Boolean_1.result().setName("Boolean_1_1")
 Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
 SketchLine_12 = Sketch_3.addLine(2.220446049250313e-016, 106, -4, 106)
 SketchLine_13 = Sketch_3.addLine(-4, 106, -4, 67.34428877022477)
@@ -121,6 +122,7 @@ SketchConstraintCoincidence_21.setName("SketchConstraintCoincidence_22")
 model.do()
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_12f-SketchLine_13f-SketchLine_17r-SketchLine_18r-SketchArc_10_2f")], model.selection(), "172/2", "172/2")
 Boolean_2 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
+Boolean_2.result().setName("Boolean_2_1")
 Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
 SketchLine_18 = Sketch_4.addLine(-65, 16, -65, -16)
 SketchLine_18.setName("SketchLine_19")
@@ -169,6 +171,8 @@ SketchConstraintTangent_7 = Sketch_4.setTangent(SketchArc_12.results()[1], Sketc
 model.do()
 Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchArc_11_2f-SketchArc_12_2f-SketchLine_21f-SketchLine_22r")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), 0)
 MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], model.selection("EDGE", "Extrusion_1_1/To_Face_1&Extrusion_1_1/Generated_Face_2"), -130, 2)
+MultiTranslation_1.result().setName("MultiTranslation_1_1")
 Boolean_3 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_2_1")], [model.selection("COMPOUND", "MultiTranslation_1_1")])
+Boolean_3.result().setName("Boolean_3_1")
 model.do()
 model.end()
index 95a5d98cb6d9b6e8a7ca3a7f29de252894e26219..065a84dbf35bdfd5599268b9730e6e39eef7fda6 100644 (file)
@@ -164,7 +164,7 @@ SketchConstraintLength_9 = Sketch_3.setLength(SketchLine_84.result(), "2*R_fille
 SketchConstraintLength_10 = Sketch_3.setLength(SketchLine_83.result(), "2*R_fillet")
 model.do()
 Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "PartSet/Sketch_1")], model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_1"), 360, 0)
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_5"))
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_1"))
 SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "PartSet/Origin"))
 SketchLine_86 = Sketch_4.addLine(0, -13.49999999999519, 3.1, -13.49999999999519)
 SketchLine_87 = Sketch_4.addLine(model.selection("EDGE", "PartSet/OZ"))
@@ -196,9 +196,12 @@ SketchConstraintCoincidence_61 = Sketch_4.setCoincident(SketchPoint_6.coordinate
 SketchConstraintCoincidence_62 = Sketch_4.setCoincident(SketchPoint_6.coordinates(), SketchLine_89.result())
 SketchConstraintDistance_6 = Sketch_4.setDistance(SketchPoint_6.coordinates(), SketchLine_86.result(), 24.5)
 model.do()
-ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_5"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection("EDGE", "PartSet/OX"), 0, 360, [model.selection("SOLID", "ExtrusionCut_1_1")])
+RevolutionCut_1.result().setName("RevolutionCut_1_1")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 0, 5, [model.selection("SOLID", "RevolutionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 model.do()
 
 # Test reexecution after parameter change
index 2b08107f3cc0593d37b3adaed69108161858dccb..d3880bd7973daa5a1d2a9f74d3804bee973b9f07 100644 (file)
@@ -165,7 +165,11 @@ Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-Sketc
 Face_2 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_2_2")])
 Face_3 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1")], model.selection(), 2, 0)
+Extrusion_2.result().setName("Extrusion_2_1")
+Extrusion_2.results()[1].setName("Extrusion_2_2")
+Extrusion_2.results()[2].setName("Extrusion_2_3")
 Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2"), model.selection("SOLID", "Extrusion_2_3")], [])
+Boolean_1.result().setName("Boolean_1_1")
 model.do()
 
 # Test reexecution after parameter change
index bbcbdf6a55877d870507d4cc8fb5678f5a9c62b2..e9a036f831b45550b4701d9a5437b72eb7b4712e 100644 (file)
@@ -72,26 +72,26 @@ SketchConstraintTangent_8 = Sketch_1.setTangent(SketchArc_4.results()[1], Sketch
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_3f-SketchLine_5r-SketchLine_6r-SketchArc_1_2f-SketchArc_2_2f-SketchArc_3_2f-SketchArc_4_2f")], model.selection(), 76, 0)
 Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"))
-SketchLine_7 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/To_Face_1"))
+SketchLine_7 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"))
 SketchLine_7.setName("SketchLine_8")
 SketchLine_7.result().setName("SketchLine_8")
 SketchLine_8 = Sketch_2.addLine(21, 45.99999999998655, 20.99999999998684, 0)
 SketchLine_8.setName("SketchLine_9")
 SketchLine_8.result().setName("SketchLine_9")
 SketchLine_8.setAuxiliary(True)
-SketchLine_9 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_1"))
+SketchLine_9 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"))
 SketchLine_9.setName("SketchLine_10")
 SketchLine_9.result().setName("SketchLine_10")
 SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchLine_8.startPoint(), SketchLine_9.result())
 SketchConstraintCoincidence_17.setName("SketchConstraintCoincidence_18")
-SketchLine_10 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"))
+SketchLine_10 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/To_Face_1"))
 SketchLine_10.setName("SketchLine_11")
 SketchLine_10.result().setName("SketchLine_11")
 SketchConstraintCoincidence_18 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_10.result())
 SketchConstraintCoincidence_18.setName("SketchConstraintCoincidence_19")
 SketchConstraintMiddle_1 = Sketch_2.setMiddlePoint(SketchLine_8.startPoint(), SketchLine_9.result())
 SketchConstraintMiddle_2 = Sketch_2.setMiddlePoint(SketchLine_8.endPoint(), SketchLine_10.result())
-SketchLine_11 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"))
+SketchLine_11 = Sketch_2.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_1"))
 SketchLine_11.setName("SketchLine_12")
 SketchLine_11.result().setName("SketchLine_12")
 SketchPoint_1 = Sketch_2.addPoint(20.99999999999342, 22.99999999999327)
@@ -129,7 +129,9 @@ SketchConstraintRadius_3 = Sketch_2.setRadius(SketchCircle_2.results()[1], 2.5)
 SketchConstraintDistance_3 = Sketch_2.setDistance(SketchLine_12.result(), SketchCircle_4.center(), 8)
 model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_1_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchCircle_2_2r"), model.selection("WIRE", "Sketch_2/Wire-SketchCircle_3_2f")], model.selection(), 0, 15, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_4_2f")], model.selection(), model.selection("FACE", "Extrusion_1_1/From_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
 SketchCircle_5 = Sketch_3.addCircle(20.99999999999342, 22.99999999999327, 19)
 SketchConstraintRadius_4 = Sketch_3.setRadius(SketchCircle_5.results()[1], 19)
@@ -137,12 +139,12 @@ SketchLine_13 = Sketch_3.addLine(41.99999999999999, 22.99999999998655, 0, 22.999
 SketchLine_13.setName("SketchLine_14")
 SketchLine_13.result().setName("SketchLine_14")
 SketchLine_13.setAuxiliary(True)
-SketchLine_14 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&Extrusion_1_1/Generated_Face_3"))
+SketchLine_14 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&Extrusion_1_1/Generated_Face_5"))
 SketchLine_14.setName("SketchLine_15")
 SketchLine_14.result().setName("SketchLine_15")
 SketchConstraintCoincidence_26 = Sketch_3.setCoincident(SketchLine_13.startPoint(), SketchLine_14.result())
 SketchConstraintCoincidence_26.setName("SketchConstraintCoincidence_27")
-SketchLine_15 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&ExtrusionCut_2_1/Modfied_2"))
+SketchLine_15 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_2_1/Modfied_2"))
 SketchLine_15.setName("SketchLine_16")
 SketchLine_15.result().setName("SketchLine_16")
 SketchConstraintCoincidence_27 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchLine_15.result())
@@ -151,7 +153,7 @@ SketchLine_16 = Sketch_3.addLine(21, 45.99999999998655, 20.99999999998684, 0)
 SketchLine_16.setName("SketchLine_17")
 SketchLine_16.result().setName("SketchLine_17")
 SketchLine_16.setAuxiliary(True)
-SketchLine_17 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&Extrusion_1_1/Generated_Face_5"))
+SketchLine_17 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&Extrusion_1_1/Generated_Face_3"))
 SketchLine_17.setName("SketchLine_18")
 SketchLine_17.result().setName("SketchLine_18")
 SketchConstraintCoincidence_28 = Sketch_3.setCoincident(SketchLine_16.startPoint(), SketchLine_17.result())
@@ -183,24 +185,25 @@ SketchConstraintDistance_4 = Sketch_3.setDistance(SketchCircle_6.center(), Sketc
 SketchConstraintDistance_5 = Sketch_3.setDistance(SketchCircle_6.center(), SketchLine_16.result(), 8)
 model.do()
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_5_2f-SketchCircle_6_2r-SketchCircle_7_2r")], model.selection(), 15, 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_5"))
-SketchProjection_1 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"))
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+SketchProjection_1 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/Generated_Face_2"))
 SketchLine_19 = SketchProjection_1.createdFeature()
 SketchLine_19.setName("SketchLine_20")
 SketchLine_19.result().setName("SketchLine_20")
-SketchProjection_2 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_4"))
+SketchProjection_2 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"))
 SketchLine_20 = SketchProjection_2.createdFeature()
 SketchLine_20.setName("SketchLine_21")
 SketchLine_20.result().setName("SketchLine_21")
 SketchLine_21 = Sketch_4.addLine(4.999999999999999, -28, 37, -28)
 SketchLine_21.setName("SketchLine_22")
 SketchLine_21.result().setName("SketchLine_22")
-SketchLine_22 = Sketch_4.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5"))
+SketchLine_22 = Sketch_4.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_3"))
 SketchLine_22.setName("SketchLine_23")
 SketchLine_22.result().setName("SketchLine_23")
 SketchConstraintCoincidence_34 = Sketch_4.setCoincident(SketchLine_21.startPoint(), SketchLine_22.result())
 SketchConstraintCoincidence_34.setName("SketchConstraintCoincidence_35")
-SketchLine_23 = Sketch_4.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"))
+SketchLine_23 = Sketch_4.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_4"))
 SketchLine_23.setName("SketchLine_24")
 SketchLine_23.result().setName("SketchLine_24")
 SketchConstraintCoincidence_35 = Sketch_4.setCoincident(SketchLine_21.endPoint(), SketchLine_23.result())
@@ -289,19 +292,19 @@ SketchConstraintVertical_2 = Sketch_5.setVertical(SketchLine_30.result())
 SketchConstraintVertical_3 = Sketch_5.setVertical(SketchLine_31.result())
 SketchConstraintEqual_8 = Sketch_5.setEqual(SketchLine_29.result(), SketchLine_28.result())
 SketchConstraintEqual_9 = Sketch_5.setEqual(SketchLine_31.result(), SketchLine_30.result())
-SketchLine_32 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_1"))
+SketchLine_32 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_7&Extrusion_2_1/To_Face_1"))
 SketchLine_32.setName("SketchLine_33")
 SketchLine_32.result().setName("SketchLine_33")
 SketchConstraintDistance_7 = Sketch_5.setDistance(SketchLine_30.endPoint(), SketchLine_32.result(), 2)
-SketchLine_33 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_5&Extrusion_2_1/To_Face_1"))
+SketchLine_33 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_3&Extrusion_2_1/To_Face_1"))
 SketchLine_33.setName("SketchLine_34")
 SketchLine_33.result().setName("SketchLine_34")
 SketchConstraintDistance_8 = Sketch_5.setDistance(SketchLine_31.startPoint(), SketchLine_33.result(), 2)
-SketchLine_34 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_7&Extrusion_2_1/To_Face_1"))
+SketchLine_34 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_1"))
 SketchLine_34.setName("SketchLine_35")
 SketchLine_34.result().setName("SketchLine_35")
 SketchConstraintDistance_9 = Sketch_5.setDistance(SketchLine_29.startPoint(), SketchLine_34.result(), 2)
-SketchLine_35 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_3&Extrusion_2_1/To_Face_1"))
+SketchLine_35 = Sketch_5.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_5&Extrusion_2_1/To_Face_1"))
 SketchLine_35.setName("SketchLine_36")
 SketchLine_35.result().setName("SketchLine_36")
 SketchConstraintDistance_10 = Sketch_5.setDistance(SketchLine_28.startPoint(), SketchLine_35.result(), 2)
@@ -367,7 +370,11 @@ SketchConstraintMiddle_16 = Sketch_5.setMiddlePoint(SketchLine_37.endPoint(), Sk
 SketchConstraintDistance_12 = Sketch_5.setDistance(SketchCircle_8.center(), SketchLine_37.result(), 8)
 model.do()
 ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_5/Wire-SketchLine_29f-SketchLine_30r-SketchLine_31r-SketchLine_32r-SketchArc_9_2f-SketchArc_10_2f-SketchArc_11_2f-SketchArc_12_2f")], model.selection(), 0, 15, [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
+ExtrusionCut_4.results()[1].setName("ExtrusionCut_4_2")
 ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchCircle_8_2f"), model.selection("FACE", "Sketch_5/Face-SketchCircle_9_2f")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionCut_4_1"), model.selection("SOLID", "ExtrusionCut_4_2")])
+ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
+ExtrusionCut_5.results()[1].setName("ExtrusionCut_5_2")
 Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
 SketchLine_38 = Sketch_6.addLine(-59, 44, -59, 2)
 SketchLine_38.setName("SketchLine_39")
@@ -423,28 +430,29 @@ SketchConstraintLength_3 = Sketch_6.setLength(SketchLine_38.result(), 42)
 SketchConstraintLength_4 = Sketch_6.setLength(SketchLine_43.result(), 20)
 SketchConstraintLength_5 = Sketch_6.setLength(SketchLine_44.result(), 15)
 SketchConstraintLength_6 = Sketch_6.setLength(SketchLine_39.result(), 42)
-SketchProjection_3 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/Generated_Face_2"))
+SketchProjection_3 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"))
 SketchLine_46 = SketchProjection_3.createdFeature()
 SketchLine_46.setName("SketchLine_47")
 SketchLine_46.result().setName("SketchLine_47")
-SketchProjection_4 = Sketch_6.addProjection(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_3&Extrusion_1_1/Generated_Face_3"))
+SketchProjection_4 = Sketch_6.addProjection(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_3&Extrusion_1_1/Generated_Face_5"))
 SketchLine_47 = SketchProjection_4.createdFeature()
 SketchLine_47.setName("SketchLine_48")
 SketchLine_47.result().setName("SketchLine_48")
-SketchProjection_5 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/Generated_Face_2"))
+SketchProjection_5 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"))
 SketchLine_48 = SketchProjection_5.createdFeature()
 SketchLine_48.setName("SketchLine_49")
 SketchLine_48.result().setName("SketchLine_49")
 SketchConstraintDistance_13 = Sketch_6.setDistance(SketchLine_38.endPoint(), SketchLine_46.result(), 2)
 SketchConstraintDistance_14 = Sketch_6.setDistance(SketchLine_38.startPoint(), SketchLine_47.result(), 17)
 model.do()
-ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), -2, model.selection(), -2, [model.selection("SOLID", "ExtrusionCut_5_2")])
-Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_7"))
+ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_5"), -2, model.selection(), -2, [model.selection("SOLID", "ExtrusionCut_5_2")])
+ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
 SketchLine_49 = Sketch_7.addLine(0, -22.99999999998656, -76, -22.99999999998655)
 SketchLine_49.setName("SketchLine_50")
 SketchLine_49.result().setName("SketchLine_50")
 SketchLine_49.setAuxiliary(True)
-SketchLine_50 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&ExtrusionCut_3_1/Modfied_4"))
+SketchLine_50 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_3_1/Modfied_4"))
 SketchLine_50.setName("SketchLine_51")
 SketchLine_50.result().setName("SketchLine_51")
 SketchConstraintCoincidence_74 = Sketch_7.setCoincident(SketchLine_49.startPoint(), SketchLine_50.result())
@@ -457,12 +465,12 @@ SketchLine_51 = Sketch_7.addLine(-38, -40.99999999998656, -38, -4.99999999998656
 SketchLine_51.setName("SketchLine_52")
 SketchLine_51.result().setName("SketchLine_52")
 SketchLine_51.setAuxiliary(True)
-SketchLine_52 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&ExtrusionCut_4_2/Modfied_4"))
+SketchLine_52 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_4_2/Modfied_4"))
 SketchLine_52.setName("SketchLine_53")
 SketchLine_52.result().setName("SketchLine_53")
 SketchConstraintCoincidence_76 = Sketch_7.setCoincident(SketchLine_51.startPoint(), SketchLine_52.result())
 SketchConstraintCoincidence_76.setName("SketchConstraintCoincidence_77")
-SketchLine_53 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_7"))
+SketchLine_53 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_1"))
 SketchLine_53.setName("SketchLine_54")
 SketchLine_53.result().setName("SketchLine_54")
 SketchConstraintCoincidence_77 = Sketch_7.setCoincident(SketchLine_51.endPoint(), SketchLine_53.result())
@@ -484,7 +492,7 @@ SketchProjection_6 = Sketch_8.addProjection(model.selection("EDGE", "Sketch_2/Ed
 SketchLine_54 = SketchProjection_6.createdFeature()
 SketchLine_54.setName("SketchLine_55")
 SketchLine_54.result().setName("SketchLine_55")
-SketchProjection_7 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&ExtrusionCut_3_1/Modfied_4"))
+SketchProjection_7 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_3_1/Modfied_4"))
 SketchLine_55 = SketchProjection_7.createdFeature()
 SketchLine_55.setName("SketchLine_56")
 SketchLine_55.result().setName("SketchLine_56")
@@ -509,11 +517,11 @@ SketchConstraintMiddle_23 = Sketch_8.setMiddlePoint(SketchLine_56.result(), Sket
 SketchConstraintCoincidence_83 = Sketch_8.setCoincident(SketchLine_57.result(), SketchPoint_5.coordinates())
 SketchConstraintCoincidence_83.setName("SketchConstraintCoincidence_84")
 SketchConstraintPerpendicular_1 = Sketch_8.setPerpendicular(SketchLine_57.result(), SketchLine_56.result())
-SketchProjection_8 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&ExtrusionCut_4_2/Modfied_4"))
+SketchProjection_8 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_4_2/Modfied_4"))
 SketchLine_58 = SketchProjection_8.createdFeature()
 SketchLine_58.setName("SketchLine_59")
 SketchLine_58.result().setName("SketchLine_59")
-SketchProjection_9 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_1"))
+SketchProjection_9 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_7"))
 SketchLine_59 = SketchProjection_9.createdFeature()
 SketchLine_59.setName("SketchLine_60")
 SketchLine_59.result().setName("SketchLine_60")
@@ -578,6 +586,7 @@ SketchConstraintCoincidence_94 = Sketch_9.setCoincident(SketchLine_60.endPoint()
 SketchConstraintCoincidence_94.setName("SketchConstraintCoincidence_95")
 model.do()
 RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "Sketch_9/Edge-SketchLine_65"), 360, 0, [model.selection("SOLID", "Extrusion_3_1")])
+RevolutionCut_1.result().setName("RevolutionCut_1_1")
 model.do()
 
 from GeomAPI import  GeomAPI_Shape
index 23c5a22c3296cb5d65b17d62733e17868820045c..969bfacd3aa66644f548a112c670f865715b94d6 100644 (file)
@@ -149,11 +149,11 @@ SketchConstraintDistance_6 = Sketch_1.setDistance(SketchLine_1.result(), SketchA
 SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_10.result(), "d1*coeff")
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchArc_1_2f-SketchLine_3f-SketchArc_2_2r-SketchLine_4f-SketchArc_3_2r-SketchLine_5f-SketchArc_4_2f-SketchLine_6f-SketchLine_7r-SketchLine_8r-SketchArc_5_2r-SketchLine_9r-SketchArc_6_2f-SketchLine_10r-SketchArc_7_2f-SketchLine_11r-SketchArc_8_2r-SketchLine_12r-SketchLine_13r")], model.selection(), "epaisseur_plat*coeff", 0)
-Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_19"), "d2*coeff", True)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), "d2*coeff", True)
 Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
-SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_14&Extrusion_1_1/Generated_Face_13"))
+SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), False)
 SketchLine_14 = SketchProjection_1.createdFeature()
-SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_12&Extrusion_1_1/To_Face_1"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/To_Face_1"), False)
 SketchLine_15 = SketchProjection_2.createdFeature()
 SketchLine_16 = Sketch_2.addLine(-24.99999999999999, -35.00000000000001, -31.24999999999999, -35.00000000000001)
 SketchConstraintCoincidence_25 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_14).endPoint(), SketchLine_16.startPoint())
@@ -215,9 +215,9 @@ SketchConstraintDistance_13 = Sketch_2.setDistance(SketchArc_10.startPoint(), Sk
 #SketchConstraintDistance_14 = Sketch_2.setDistance(SketchLine_17.startPoint(), SketchLine_23.result(), "(e3-epaisseur_plat)*coeff")
 model.do()
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_16r-SketchArc_9_2f-SketchLine_17r-SketchArc_10_2f-SketchLine_18r-SketchLine_19r-SketchLine_20r-SketchArc_11_2r-SketchLine_21r-SketchArc_12_2r-SketchLine_22r-SketchLine_23f")], model.selection(), "d6*coeff", 0)
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/Generated_Face_9"))
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/Generated_Face_3"))
 SketchLine_24 = Sketch_3.addLine(46.25, 22.91561885925604, 51.3, 20.00000000000001)
-SketchLine_25 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_9&Extrusion_2_1/To_Face_1"))
+SketchLine_25 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_2_1/Generated_Face_3&Extrusion_2_1/To_Face_1"))
 #SketchConstraintCoincidence_41 = Sketch_3.setCoincident(SketchLine_24.startPoint(), SketchLine_25.result())
 SketchLine_26 = Sketch_3.addLine(51.3, 20.00000000000001, 62.50000000000001, 20.00000000000001)
 SketchConstraintCoincidence_42 = Sketch_3.setCoincident(SketchLine_24.endPoint(), SketchLine_26.startPoint())
@@ -245,9 +245,9 @@ SketchConstraintVertical_12 = Sketch_3.setVertical(SketchLine_27.result())
 SketchConstraintVertical_13 = Sketch_3.setVertical(SketchLine_33.result())
 SketchConstraintVertical_14 = Sketch_3.setVertical(SketchLine_31.result())
 SketchConstraintAngle_1 = Sketch_3.setAngleComplementary(SketchLine_26.result(), SketchLine_24.result(), "angle")
-SketchProjection_3 = Sketch_3.addProjection(model.selection("EDGE", "Extrusion_2_1/Generated_Face_8&Extrusion_2_1/Generated_Face_7"))
+SketchProjection_3 = Sketch_3.addProjection(model.selection("EDGE", "Extrusion_2_1/Generated_Face_5&Extrusion_2_1/Generated_Face_4"))
 SketchLine_34 = SketchProjection_3.createdFeature()
-SketchProjection_4 = Sketch_3.addProjection(model.selection("EDGE", "Extrusion_2_1/Generated_Face_11&Extrusion_2_1/Generated_Face_10"))
+SketchProjection_4 = Sketch_3.addProjection(model.selection("EDGE", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/Generated_Face_1"))
 SketchLine_35 = SketchProjection_4.createdFeature()
 SketchConstraintCoincidence_51 = Sketch_3.setCoincident(SketchLine_28.endPoint(), SketchLine_34.result())
 SketchConstraintDistance_15 = Sketch_3.setDistance(SketchLine_31.result(), SketchLine_33.endPoint(), "(d6-d5)*coeff")
@@ -260,14 +260,16 @@ SketchConstraintDistance_17 = Sketch_3.setDistance(SketchLine_26.result(), Sketc
 SketchConstraintLength_4 = Sketch_3.setLength(SketchLine_26.result(), "d7*coeff")
 model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_24r-SketchLine_26r-SketchLine_27r-SketchLine_28r-SketchLine_29r")], model.selection(), model.selection("FACE", "Extrusion_2_1/Generated_Face_6"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_2_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_30r-SketchLine_31r-SketchLine_32r-SketchLine_33r")], model.selection(), model.selection("FACE", "Extrusion_1_1/To_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_19"), "d3*coeff", True)
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), "d3*coeff", True)
 Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
-SketchProjection_5 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_16&Extrusion_1_1/To_Face_1"))
+SketchProjection_5 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1"))
 SketchLine_36 = SketchProjection_5.createdFeature()
 SketchProjection_6 = Sketch_4.addProjection(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_8&ExtrusionCut_2_1/Modfied_9"))
 SketchLine_37 = SketchProjection_6.createdFeature()
-SketchProjection_7 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_15&Extrusion_1_1/Generated_Face_14"))
+SketchProjection_7 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5"))
 SketchLine_38 = SketchProjection_7.createdFeature()
 SketchLine_39 = Sketch_4.addLine(-25, -35.00000000000001, -31.24999999999999, -35.00000000000001)
 SketchConstraintCoincidence_55 = Sketch_4.setCoincident(SketchAPI_Line(SketchLine_37).startPoint(), SketchLine_39.startPoint())
@@ -303,22 +305,23 @@ SketchConstraintDistance_19 = Sketch_4.setDistance(SketchLine_41.endPoint(), Ske
 SketchConstraintDistance_20 = Sketch_4.setDistance(SketchLine_41.startPoint(), SketchLine_39.result(), "h2")
 model.do()
 Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchLine_39r-SketchArc_13_2f-SketchLine_40r-SketchLine_41r-SketchLine_42r-SketchArc_14_2r-SketchLine_43r-SketchLine_44f")], model.selection(), 0, "e1*coeff")
-Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_6"))
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"))
 SketchCircle_1 = Sketch_5.addCircle(70, 17.5, 3.125)
-SketchLine_45 = Sketch_5.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_5"))
+SketchLine_45 = Sketch_5.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_1_1/Modfied_4"))
 SketchConstraintDistance_21 = Sketch_5.setDistance(SketchCircle_1.center(), SketchLine_45.result(), "d9*coeff")
-SketchProjection_8 = Sketch_5.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"))
+SketchProjection_8 = Sketch_5.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_12&Extrusion_1_1/Generated_Face_11"))
 SketchLine_46 = SketchProjection_8.createdFeature()
-SketchProjection_9 = Sketch_5.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_20&Extrusion_1_1/Generated_Face_19"))
+SketchProjection_9 = Sketch_5.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_20&Extrusion_1_1/Generated_Face_1"))
 SketchLine_47 = SketchProjection_9.createdFeature()
 SketchConstraintDistance_22 = Sketch_5.setDistance(SketchCircle_1.center(), SketchLine_47.result(), "d1*coeff")
 SketchConstraintRadius_7 = Sketch_5.setRadius(SketchCircle_1.results()[1], "r_trou")
 model.do()
-ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchCircle_1_2f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_14"))
+ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchCircle_1_2f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_6"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
+Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_6"))
 SketchCircle_2 = Sketch_6.addCircle(70, -17.5, 5)
-SketchLine_48 = Sketch_6.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_14&Extrusion_1_1/To_Face_1"))
-SketchProjection_10 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_19&Extrusion_1_1/Generated_Face_18"))
+SketchLine_48 = Sketch_6.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_1"))
+SketchProjection_10 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1"))
 SketchLine_49 = SketchProjection_10.createdFeature()
 SketchConstraintDistance_23 = Sketch_6.setDistance(SketchCircle_2.center(), SketchLine_49.result(), "d1*coeff")
 SketchConstraintDistance_23.setName("SketchConstraintDistance_24")
@@ -327,14 +330,15 @@ SketchLine_50 = Sketch_6.addLine(model.selection("EDGE", "Sketch_1/Edge-SketchLi
 SketchConstraintDistance_24 = Sketch_6.setDistance(SketchCircle_2.center(), SketchLine_50.result(), "d_trou")
 SketchConstraintDistance_24.setName("SketchConstraintDistance_25")
 model.do()
-ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchCircle_2_2f")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_1_1")])
-Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_8"))
+ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchCircle_2_2f")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_16"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"))
 SketchLine_51 = Sketch_7.addLine(110, 21.46600893000899, 110, 7.22841614740048)
 SketchLine_51.setAuxiliary(True)
-SketchLine_52 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"))
+SketchLine_52 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_12&Extrusion_1_1/Generated_Face_11"))
 SketchConstraintCoincidence_65 = Sketch_7.setCoincident(SketchLine_51.startPoint(), SketchLine_52.result())
 SketchConstraintCoincidence_66 = Sketch_7.setCoincident(SketchLine_51.endPoint(), SketchLine_52.result())
-SketchLine_53 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/From_Face_1&Extrusion_1_1/Generated_Face_8"))
+SketchLine_53 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/From_Face_1&Extrusion_1_1/Generated_Face_12"))
 SketchArc_15 = Sketch_7.addArc(102.5, 7.22841614740048, 110, 7.22841614740048, 104.5, 0, True)
 SketchConstraintCoincidence_67 = Sketch_7.setCoincident(SketchLine_51.endPoint(), SketchArc_15.startPoint())
 SketchConstraintTangent_29 = Sketch_7.setTangent(SketchLine_51.result(), SketchArc_15.results()[1])
@@ -351,11 +355,11 @@ SketchConstraintLength_5 = Sketch_7.setLength(SketchLine_54.result(), "5.5*coeff
 SketchLine_56 = Sketch_7.addLine(110, 12.5, 0, 12.5)
 SketchLine_56.setAuxiliary(True)
 SketchConstraintCoincidence_73 = Sketch_7.setCoincident(SketchLine_56.startPoint(), SketchLine_52.result())
-SketchLine_57 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_20&Extrusion_1_1/Generated_Face_19"))
+SketchLine_57 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_20&Extrusion_1_1/Generated_Face_1"))
 SketchConstraintCoincidence_74 = Sketch_7.setCoincident(SketchLine_56.endPoint(), SketchLine_57.result())
 SketchConstraintMiddle_1 = Sketch_7.setMiddlePoint(SketchLine_56.endPoint(), SketchLine_57.result())
 SketchConstraintMiddle_2 = Sketch_7.setMiddlePoint(SketchLine_56.startPoint(), SketchLine_52.result())
-SketchProjection_11 = Sketch_7.addProjection(model.selection("EDGE", "Extrusion_1_1/To_Face_1&ExtrusionCut_4_1/Modfied_1"))
+SketchProjection_11 = Sketch_7.addProjection(model.selection("EDGE", "Extrusion_1_1/To_Face_1&ExtrusionCut_4_1/Modfied_2"))
 SketchLine_58 = SketchProjection_11.createdFeature()
 SketchLine_59 = Sketch_7.addLine(55.00000000000002, 0, 55.00000000000002, 25)
 SketchLine_59.setAuxiliary(True)
@@ -372,7 +376,9 @@ SketchConstraintMirror_2 = Sketch_7.addMirror(SketchLine_59.result(), SketchCons
 [SketchArc_17, SketchLine_63, SketchLine_64, SketchArc_18, SketchLine_65, SketchLine_66] = SketchConstraintMirror_2.mirrored()
 model.do()
 ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchArc_16_2r-SketchLine_61f-SketchLine_62r"), model.selection("FACE", "Sketch_7/Face-SketchArc_18_2r-SketchLine_65f-SketchLine_66r"), model.selection("FACE", "Sketch_7/Face-SketchArc_17_2r-SketchLine_64r-SketchLine_66r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_15_2r-SketchLine_54f-SketchLine_55r")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_10"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
+ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
 Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "ExtrusionCut_5_1")], [model.selection("SOLID", "Extrusion_3_1"), model.selection("SOLID", "ExtrusionCut_3_1")])
+Boolean_1.result().setName("Boolean_1_1")
 model.do()
 
 from GeomAPI import  GeomAPI_Shape
index 372a26a4c88e387f3e115f87be926153e7fb20be..f4159d38f069bd1a5ea1572e64cc53f86ceeef3a 100644 (file)
@@ -343,13 +343,18 @@ SketchConstraintRadius_9.setName("SketchConstraintRadius_6")
 model.do()
 Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), "10*coeff", 0)
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_3_2f")], model.selection(), "p_trou1*coeff", 0, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_1_2r")], model.selection(), "p2_trou1*coeff", 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_4_2f")], model.selection(), "p_trou2*coeff", 0, [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "ExtrusionCut_2_1")])
+ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
+ExtrusionCut_3.results()[1].setName("ExtrusionCut_3_2")
 ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_2_2r")], model.selection(), "p2_trou*coeff", 0, [model.selection("SOLID", "ExtrusionCut_3_2")])
+ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
 Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), "22.5*coeff", False)
 Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), "45*coeff", True)
 Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
-SketchProjection_3 = Sketch_3.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3"))
+SketchProjection_3 = Sketch_3.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1"))
 SketchLine_18 = SketchProjection_3.createdFeature()
 SketchLine_18.setName("SketchLine_4")
 SketchLine_18.result().setName("SketchLine_4")
@@ -430,10 +435,13 @@ SketchConstraintDistance_13.setName("SketchConstraintDistance_11")
 SketchConstraintDistance_14 = Sketch_3.setDistance(SketchLine_23.result(), SketchLine_25.startPoint(), "2.5*coeff")
 SketchConstraintDistance_14.setName("SketchConstraintDistance_12")
 model.do()
-Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_9r-SketchLine_12r-SketchLine_14r-SketchLine_26r-SketchLine_27r-SketchLine_28r")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), 0, model.selection(), 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_9r-SketchLine_12r-SketchLine_14r-SketchLine_26r-SketchLine_27r-SketchLine_28r")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), 0, model.selection(), 0)
 Boolean_1 = model.addSmash(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], [model.selection("SOLID", "ExtrusionCut_4_1")])
+Boolean_1.result().setName("Boolean_1_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_5.result().setName("ExtrusionCut_5_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")])
+ExtrusionCut_6.result().setName("ExtrusionCut_6_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"))
@@ -518,10 +526,13 @@ SketchConstraintDistance_16.setName("SketchConstraintDistance_10")
 SketchConstraintLength_10 = Sketch_4.setLength(SketchLine_36.result(), 12.975642079145)
 SketchConstraintLength_10.setName("SketchConstraintLength_7")
 model.do()
-Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchLine_19f-SketchLine_20f-SketchLine_24f-SketchLine_21f-SketchLine_22f-SketchLine_23f")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), 0, model.selection(), 0)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchLine_19f-SketchLine_20f-SketchLine_24f-SketchLine_21f-SketchLine_22f-SketchLine_23f")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), 0, model.selection(), 0)
 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")])
+Boolean_2.result().setName("Boolean_2_1")
 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_7.result().setName("ExtrusionCut_7_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")])
+ExtrusionCut_8.result().setName("ExtrusionCut_8_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")
@@ -624,12 +635,12 @@ SketchConstraintRadius_13 = Sketch_6.setRadius(SketchArc_20.results()[1], "r1*co
 SketchConstraintRadius_13.setName("SketchConstraintRadius_10")
 model.do()
 Extrusion_6 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchLine_33r-SketchArc_6_2r-SketchLine_36r-SketchLine_37f")], model.selection(), "77*coeff-h_p*coeff", 0)
-Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_6_1/Generated_Face_3"))
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_6_1/Generated_Face_1"))
 SketchLine_46 = Sketch_7.addLine(37, -8.881784197001252e-16, -22, 1.665334536937735e-15)
 SketchLine_46.setName("SketchLine_38")
 SketchLine_46.result().setName("SketchLine_38")
 SketchLine_46.setAuxiliary(True)
-SketchLine_47 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_6_1/Generated_Face_3&Extrusion_6_1/To_Face_1"))
+SketchLine_47 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_6_1/Generated_Face_1&Extrusion_6_1/To_Face_1"))
 SketchLine_47.setName("SketchLine_39")
 SketchLine_47.result().setName("SketchLine_39")
 SketchConstraintCoincidence_69 = Sketch_7.setCoincident(SketchLine_46.startPoint(), SketchLine_47.result())
@@ -664,20 +675,21 @@ SketchConstraintRadius_14 = Sketch_7.setRadius(SketchCircle_11.results()[1], "r3
 SketchConstraintRadius_14.setName("SketchConstraintRadius_12")
 model.do()
 ExtrusionCut_9 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchCircle_10_2f")], model.selection(), 0, "10*coeff", [model.selection("SOLID", "Extrusion_6_1")])
+ExtrusionCut_9.result().setName("ExtrusionCut_9_1")
 ExtrusionCut_10 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_7_2r-SketchArc_10_2f-SketchLine_44r-SketchArc_12_2r-SketchArc_13_2r-SketchLine_48r-SketchLine_43f-SketchArc_14_2f"), model.selection("FACE", "Sketch_1/Face-SketchCircle_11_2f"), model.selection("WIRE", "Sketch_1/Wire-SketchLine_50f-SketchArc_15_2f-SketchArc_16_2r-SketchLine_51r-SketchArc_17_2r-SketchLine_52f"), model.selection("FACE", "Sketch_1/Face-SketchLine_53f-SketchArc_18_2r-SketchLine_54f-SketchArc_19_2r-SketchArc_20_2f-SketchLine_55r-SketchArc_21_2f-SketchArc_22_2r"), model.selection("FACE", "Sketch_1/Face-SketchArc_8_2r-SketchArc_9_2f-SketchLine_42r-SketchLine_45f-SketchLine_46r-SketchArc_11_2r")], model.selection(), model.selection("FACE", "ExtrusionCut_3_2/Modfied_1"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_8_1_2")])
-Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_9_1/Modfied_2"))
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_9_1/Modfied_1"))
 SketchLine_50 = Sketch_8.addLine(37, 14.80042035331162, 37, -14)
 SketchLine_50.setName("SketchLine_56")
 SketchLine_50.result().setName("SketchLine_56")
 SketchLine_50.setAuxiliary(True)
-SketchLine_51 = Sketch_8.addLine(model.selection("EDGE", "ExtrusionCut_9_1/Modfied_2&Extrusion_6_1/To_Face_1"))
+SketchLine_51 = Sketch_8.addLine(model.selection("EDGE", "ExtrusionCut_9_1/Modfied_1&Extrusion_6_1/To_Face_1"))
 SketchLine_51.setName("SketchLine_57")
 SketchLine_51.result().setName("SketchLine_57")
 SketchConstraintCoincidence_73 = Sketch_8.setCoincident(SketchLine_50.startPoint(), SketchLine_51.result())
 SketchConstraintCoincidence_73.setName("SketchConstraintCoincidence_81")
 SketchConstraintCoincidence_74 = Sketch_8.setCoincident(SketchLine_50.endPoint(), SketchLine_51.result())
 SketchConstraintCoincidence_74.setName("SketchConstraintCoincidence_82")
-SketchLine_52 = Sketch_8.addLine(model.selection("EDGE", "Extrusion_6_1/Generated_Face_4&ExtrusionCut_9_1/Modfied_2"))
+SketchLine_52 = Sketch_8.addLine(model.selection("EDGE", "Extrusion_6_1/Generated_Face_4&ExtrusionCut_9_1/Modfied_1"))
 SketchLine_52.setName("SketchLine_58")
 SketchLine_52.result().setName("SketchLine_58")
 SketchArc_21 = Sketch_8.addArc(34, -14, 37, -14, 34.00000001126211, -17, True)
@@ -721,19 +733,19 @@ SketchArc_22.result().setName("SketchArc_24")
 SketchArc_22.results()[1].setName("SketchArc_24_2")
 model.do()
 ExtrusionCut_11 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchArc_23_2r-SketchLine_59f-SketchLine_60r"), model.selection("WIRE", "Sketch_8/Wire-SketchArc_24_2r-SketchLine_62f-SketchLine_63r")], model.selection(), 0, "100*coeff", [model.selection("SOLID", "ExtrusionCut_9_1")])
-Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_5_1/Generated_Face_3"))
+Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_5_1/Generated_Face_1"))
 SketchLine_58 = Sketch_9.addLine(-32, -19, -32, -3.575047476349699)
 SketchLine_58.setName("SketchLine_64")
 SketchLine_58.result().setName("SketchLine_64")
 SketchLine_58.setAuxiliary(True)
-SketchLine_59 = Sketch_9.addLine(model.selection("EDGE", "Extrusion_5_1/Generated_Face_3&Extrusion_5_1/Generated_Face_2"))
+SketchLine_59 = Sketch_9.addLine(model.selection("EDGE", "Extrusion_5_1/Generated_Face_1&Extrusion_5_1/Generated_Face_2"))
 SketchLine_59.setName("SketchLine_65")
 SketchLine_59.result().setName("SketchLine_65")
 SketchConstraintCoincidence_81 = Sketch_9.setCoincident(SketchLine_58.startPoint(), SketchLine_59.result())
 SketchConstraintCoincidence_81.setName("SketchConstraintCoincidence_89")
 SketchConstraintCoincidence_82 = Sketch_9.setCoincident(SketchLine_58.endPoint(), SketchLine_59.result())
 SketchConstraintCoincidence_82.setName("SketchConstraintCoincidence_90")
-SketchLine_60 = Sketch_9.addLine(model.selection("EDGE", "Extrusion_5_1/Generated_Face_3&Extrusion_5_1/From_Face_1"))
+SketchLine_60 = Sketch_9.addLine(model.selection("EDGE", "Extrusion_5_1/Generated_Face_1&Extrusion_5_1/From_Face_1"))
 SketchLine_60.setName("SketchLine_66")
 SketchLine_60.result().setName("SketchLine_66")
 SketchArc_23 = Sketch_9.addArc(-29, -19, -32, -19, -29.00002201340376, -22, False)
@@ -764,6 +776,7 @@ SketchConstraintRadius_16 = Sketch_9.setRadius(SketchArc_23.results()[1], "3*coe
 SketchConstraintRadius_16.setName("SketchConstraintRadius_17")
 model.do()
 ExtrusionCut_12 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchArc_25_2r-SketchLine_67f-SketchLine_68f")], model.selection(), 0, "100*coeff", [model.selection("SOLID", "Extrusion_5_1")])
+ExtrusionCut_12.result().setName("ExtrusionCut_12_1")
 model.do()
 
 from GeomAPI import  GeomAPI_Shape