Salome HOME
Merge remote-tracking branch 'remotes/origin/HighLevelDump'
authordbv <dbv@opencascade.com>
Wed, 24 Aug 2016 12:33:18 +0000 (15:33 +0300)
committerdbv <dbv@opencascade.com>
Wed, 24 Aug 2016 12:33:18 +0000 (15:33 +0300)
249 files changed:
src/BuildAPI/BuildAPI_Edge.cpp
src/BuildAPI/BuildAPI_Edge.h
src/BuildAPI/BuildAPI_Face.cpp
src/BuildAPI/BuildAPI_Face.h
src/BuildAPI/BuildAPI_Shell.cpp
src/BuildAPI/BuildAPI_Shell.h
src/BuildAPI/BuildAPI_SubShapes.cpp
src/BuildAPI/BuildAPI_SubShapes.h
src/BuildAPI/BuildAPI_Vertex.cpp
src/BuildAPI/BuildAPI_Vertex.h
src/BuildAPI/BuildAPI_Wire.cpp
src/BuildAPI/BuildAPI_Wire.h
src/BuildPlugin/Test/TestEdge.py
src/BuildPlugin/Test/TestFace.py
src/BuildPlugin/Test/TestShell.py
src/BuildPlugin/Test/TestSubShapes.py
src/BuildPlugin/Test/TestVertex.py
src/BuildPlugin/Test/TestWire.py
src/ConstructionAPI/ConstructionAPI_Axis.cpp
src/ConstructionAPI/ConstructionAPI_Axis.h
src/ConstructionAPI/ConstructionAPI_Plane.cpp
src/ConstructionAPI/ConstructionAPI_Plane.h
src/ConstructionAPI/ConstructionAPI_Point.cpp
src/ConstructionAPI/ConstructionAPI_Point.h
src/ConstructionAPI/Test/TestAxis.py
src/ConstructionAPI/Test/TestPoint.py
src/ConstructionPlugin/CMakeLists.txt
src/ConstructionPlugin/Test/TestAxisCreation.py
src/ConstructionPlugin/Test/TestPlane.py
src/ConstructionPlugin/Test/TestPoint.py
src/ConstructionPlugin/Test/TestPointName.py
src/ConstructionPlugin/Test/UnitTestAxis.py
src/ExchangeAPI/ExchangeAPI_Export.cpp
src/ExchangeAPI/ExchangeAPI_Import.cpp
src/ExchangeAPI/ExchangeAPI_Import.h
src/ExchangeAPI/Test/TestExchange.py
src/ExchangePlugin/CMakeLists.txt
src/ExchangePlugin/ExchangePlugin_Dump.cpp [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_Dump.h [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_Plugin.cpp
src/ExchangePlugin/Test/TestExport.py
src/ExchangePlugin/Test/TestImport.py
src/ExchangePlugin/icons/dump.png [new file with mode: 0644]
src/ExchangePlugin/plugin-Exchange.xml
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Boolean.cpp
src/FeaturesAPI/FeaturesAPI_Boolean.h
src/FeaturesAPI/FeaturesAPI_Extrusion.cpp
src/FeaturesAPI/FeaturesAPI_Extrusion.h
src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.cpp
src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.h
src/FeaturesAPI/FeaturesAPI_Group.cpp
src/FeaturesAPI/FeaturesAPI_Group.h
src/FeaturesAPI/FeaturesAPI_Intersection.cpp
src/FeaturesAPI/FeaturesAPI_Intersection.h
src/FeaturesAPI/FeaturesAPI_Partition.cpp
src/FeaturesAPI/FeaturesAPI_Partition.h
src/FeaturesAPI/FeaturesAPI_Pipe.cpp
src/FeaturesAPI/FeaturesAPI_Pipe.h
src/FeaturesAPI/FeaturesAPI_Placement.cpp
src/FeaturesAPI/FeaturesAPI_Placement.h
src/FeaturesAPI/FeaturesAPI_Recover.cpp
src/FeaturesAPI/FeaturesAPI_Recover.h
src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp
src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h
src/FeaturesAPI/FeaturesAPI_Revolution.cpp
src/FeaturesAPI/FeaturesAPI_Revolution.h
src/FeaturesAPI/FeaturesAPI_RevolutionBoolean.cpp
src/FeaturesAPI/FeaturesAPI_RevolutionBoolean.h
src/FeaturesAPI/FeaturesAPI_Rotation.cpp
src/FeaturesAPI/FeaturesAPI_Rotation.h
src/FeaturesAPI/FeaturesAPI_Translation.cpp
src/FeaturesAPI/FeaturesAPI_Translation.h
src/FeaturesAPI/FeaturesAPI_Union.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_Union.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp
src/FeaturesPlugin/FeaturesPlugin_Translation.cpp
src/FeaturesPlugin/Test/TestBoolean.py
src/FeaturesPlugin/Test/TestBooleanCompSolids.py
src/FeaturesPlugin/Test/TestBooleanFill.py
src/FeaturesPlugin/Test/TestBooleanSmash.py
src/FeaturesPlugin/Test/TestCompositeFeaturesOnCompSolids.py
src/FeaturesPlugin/Test/TestExtrusion.py
src/FeaturesPlugin/Test/TestExtrusionCut.py
src/FeaturesPlugin/Test/TestExtrusionFuse.py
src/FeaturesPlugin/Test/TestGroup.py
src/FeaturesPlugin/Test/TestIntersection.py
src/FeaturesPlugin/Test/TestMultiBoolean.py
src/FeaturesPlugin/Test/TestPartition.py
src/FeaturesPlugin/Test/TestPipe.py
src/FeaturesPlugin/Test/TestPlacement.py
src/FeaturesPlugin/Test/TestRecover.py
src/FeaturesPlugin/Test/TestRemoveSubShapes.py
src/FeaturesPlugin/Test/TestRevolution.py
src/FeaturesPlugin/Test/TestRevolutionCut.py
src/FeaturesPlugin/Test/TestRevolutionFuse.py
src/FeaturesPlugin/Test/TestRotation.py
src/FeaturesPlugin/Test/TestSerialBoolean.py
src/FeaturesPlugin/Test/TestTranslation.py
src/FeaturesPlugin/Test/TestUnion.py
src/GeomAPI/GeomAPI_Circ2d.cpp
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomData/GeomData_Point2D.cpp
src/GeomDataAPI/GeomDataAPI_Dir.h
src/GeomValidators/GeomValidators_Different.cpp
src/GeomValidators/GeomValidators_ZeroOffset.cpp
src/InitializationPlugin/InitializationPlugin_Plugin.cpp
src/Model/Model_AttributeBoolean.cpp
src/Model/Model_AttributeBoolean.h
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_AttributeString.cpp
src/Model/Model_AttributeString.h
src/Model/Model_BodyBuilder.cpp
src/Model/Model_Data.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Expression.cpp
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_SelectionNaming.cpp
src/Model/Model_SelectionNaming.h
src/Model/Model_Update.cpp
src/ModelAPI/Test/Test1064.py
src/ModelAPI/Test/Test1512.py
src/ModelAPI/Test/TestDocument.py
src/ModelAPI/Test/TestIntArray.py
src/ModelAPI/Test/TestResults.py
src/ModelAPI/Test/TestUndoRedo.py
src/ModelGeomAlgo/Test/TestPoint2D.py
src/ModelHighAPI/CMakeLists.txt
src/ModelHighAPI/ModelHighAPI.i
src/ModelHighAPI/ModelHighAPI_Dumper.cpp [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI_Dumper.h [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI_FeatureStore.h [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI_Interface.cpp
src/ModelHighAPI/ModelHighAPI_Interface.h
src/ModelHighAPI/ModelHighAPI_Macro.h
src/ModelHighAPI/ModelHighAPI_RefAttr.cpp
src/ModelHighAPI/ModelHighAPI_RefAttr.h
src/ModelHighAPI/ModelHighAPI_Reference.cpp
src/ModelHighAPI/ModelHighAPI_Reference.h
src/ModelHighAPI/ModelHighAPI_Selection.cpp
src/ModelHighAPI/ModelHighAPI_Selection.h
src/ModelHighAPI/ModelHighAPI_Services.cpp
src/ModelHighAPI/ModelHighAPI_Services.h
src/ModelHighAPI/ModelHighAPI_Tools.cpp
src/ModelHighAPI/ModelHighAPI_Tools.h
src/ModelHighAPI/ModelHighAPI_swig.h
src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp
src/ParametersAPI/ParametersAPI_Parameter.cpp
src/ParametersAPI/ParametersAPI_Parameter.h
src/ParametersPlugin/Test/TestParameterChangeValue.py
src/ParametersPlugin/Test/TestParameterCreation.py
src/ParametersPlugin/Test/TestParameterRename.py
src/PartSet/PartSet_WidgetPoint2d.cpp
src/PartSetAPI/PartSetAPI_Part.cpp
src/PartSetAPI/PartSetAPI_Part.h
src/PythonAPI/Test/TestFeatures.py
src/PythonAPI/Test/TestFeaturesExtrusion.py
src/PythonAPI/Test/TestFeaturesRevolution.py
src/PythonAPI/Test/TestModel.py
src/PythonAPI/Test/TestSketcher.py
src/PythonAPI/Test/TestSketcherSetParallel.py
src/PythonAPI/examples/MakeBrick1.py
src/PythonAPI/examples/MakeBrick2.py
src/PythonAPI/examples/MakeBrick3.py
src/PythonAPI/examples/Platine.py
src/PythonAPI/model/__init__.py
src/PythonAPI/model/build/__init__.py [new file with mode: 0644]
src/PythonAPI/model/dump/DumpAssistant.py [new file with mode: 0644]
src/PythonAPI/model/dump/__init__.py [new file with mode: 0644]
src/PythonAPI/model/features/__init__.py
src/PythonAPI/model/services/__init__.py
src/PythonAddons/macros/box/feature.py
src/SketchAPI/CMakeLists.txt
src/SketchAPI/SketchAPI.i
src/SketchAPI/SketchAPI_Arc.cpp
src/SketchAPI/SketchAPI_Arc.h
src/SketchAPI/SketchAPI_Circle.cpp
src/SketchAPI/SketchAPI_Circle.h
src/SketchAPI/SketchAPI_Constraint.cpp [new file with mode: 0644]
src/SketchAPI/SketchAPI_Constraint.h [new file with mode: 0644]
src/SketchAPI/SketchAPI_IntersectionPoint.cpp
src/SketchAPI/SketchAPI_IntersectionPoint.h
src/SketchAPI/SketchAPI_Line.cpp
src/SketchAPI/SketchAPI_Line.h
src/SketchAPI/SketchAPI_Mirror.cpp
src/SketchAPI/SketchAPI_Mirror.h
src/SketchAPI/SketchAPI_Point.cpp
src/SketchAPI/SketchAPI_Point.h
src/SketchAPI/SketchAPI_Projection.cpp
src/SketchAPI/SketchAPI_Projection.h
src/SketchAPI/SketchAPI_Rotation.cpp
src/SketchAPI/SketchAPI_Rotation.h
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchAPI/SketchAPI_SketchEntity.cpp
src/SketchAPI/SketchAPI_SketchEntity.h
src/SketchAPI/SketchAPI_Translation.cpp
src/SketchAPI/SketchAPI_Translation.h
src/SketchAPI/SketchAPI_swig.h
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp
src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp
src/SketchPlugin/SketchPlugin_Feature.cpp
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_MultiRotation.cpp
src/SketchPlugin/SketchPlugin_MultiTranslation.cpp
src/SketchPlugin/SketchPlugin_Point.cpp
src/SketchPlugin/SketchPlugin_Projection.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/Test/TestConstraintAngle.py
src/SketchPlugin/Test/TestConstraintCoincidence.py
src/SketchPlugin/Test/TestConstraintCollinear.py
src/SketchPlugin/Test/TestConstraintDistance.py
src/SketchPlugin/Test/TestConstraintEqual.py
src/SketchPlugin/Test/TestConstraintHorizontal.py
src/SketchPlugin/Test/TestConstraintLength.py
src/SketchPlugin/Test/TestConstraintMiddlePoint.py
src/SketchPlugin/Test/TestConstraintMirror.py
src/SketchPlugin/Test/TestConstraintParallel.py
src/SketchPlugin/Test/TestConstraintPerpendicular.py
src/SketchPlugin/Test/TestConstraintRadius.py
src/SketchPlugin/Test/TestConstraintRigid.py
src/SketchPlugin/Test/TestConstraintTangent.py
src/SketchPlugin/Test/TestConstraintVertical.py
src/SketchPlugin/Test/TestFillet.py
src/SketchPlugin/Test/TestHighload.py
src/SketchPlugin/Test/TestMultiRotation.py
src/SketchPlugin/Test/TestMultiTranslation.py
src/SketchPlugin/Test/TestProjection.py
src/SketchPlugin/Test/TestRectangle.py
src/SketchPlugin/Test/TestSketchArcCircle.py
src/SketchPlugin/Test/TestSketchPointLine.py
src/SketchPlugin/Test/TestSnowflake.py
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp
src/SketchSolver/SketchSolver_ConstraintMirror.cpp
src/SketchSolver/SketchSolver_Manager.cpp
src/SketcherPrs/SketcherPrs_Tools.cpp

index a1a1a03dfd5b7b6a43ef2d3ea335707454426aea..09374b14d6081dcb97cfab753489b19dd6cc60f7 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "BuildAPI_Edge.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -39,6 +40,16 @@ void BuildAPI_Edge::setBase(const std::list<ModelHighAPI_Selection>& theBaseObje
   execute();
 }
 
+//==================================================================================================
+void BuildAPI_Edge::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addEdge(" << aPartName << ", "
+            << aBase->selectionList(BuildPlugin_Edge::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
 //==================================================================================================
 EdgePtr addEdge(const std::shared_ptr<ModelAPI_Document>& thePart,
                 const std::list<ModelHighAPI_Selection>& theBaseObjects)
index 6df02f745aa820cca1d0e19cb4bb973ed9850f27..2d9fe087ed9c27d7a1574650e8a3b11d8e4347c1 100644 (file)
@@ -41,6 +41,10 @@ public:
   /// Modify base attribute of the feature.
   BUILDAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  BUILDAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Edge object.
index 3f5cf71df35a59bd4b8756491590cabd8741457a..54b731c84806d92585b0445baa51367fcd02ae26 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "BuildAPI_Face.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -39,6 +40,16 @@ void BuildAPI_Face::setBase(const std::list<ModelHighAPI_Selection>& theBaseObje
   execute();
 }
 
+//==================================================================================================
+void BuildAPI_Face::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addFace(" << aPartName << ", "
+            << aBase->selectionList(BuildPlugin_Face::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
 //==================================================================================================
 FacePtr addFace(const std::shared_ptr<ModelAPI_Document>& thePart,
                 const std::list<ModelHighAPI_Selection>& theBaseObjects)
index 8a621790e4c166291f9cbb42b7f6296e2a3a747e..997499bbba16116bc5a373bd74c8d85709910b3a 100644 (file)
@@ -41,6 +41,10 @@ public:
   /// Modify base attribute of the feature.
   BUILDAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  BUILDAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Face object.
index 86151b4cfffabe3f5bb292062cfaf23db19293d4..0e825e40efd28f5326e82af39997c7fda8c05653 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "BuildAPI_Shell.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -39,6 +40,16 @@ void BuildAPI_Shell::setBase(const std::list<ModelHighAPI_Selection>& theBaseObj
   execute();
 }
 
+//==================================================================================================
+void BuildAPI_Shell::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addShell(" << aPartName << ", "
+    << aBase->selectionList(BuildPlugin_Shell::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
 //==================================================================================================
 ShellPtr addShell(const std::shared_ptr<ModelAPI_Document>& thePart,
                   const std::list<ModelHighAPI_Selection>& theBaseObjects)
index 3b7fbef193f275e33dcea9952c41d1242d0f2225..0e6338842a62b0f60c26c185f1b08468e5547467 100644 (file)
@@ -41,6 +41,10 @@ public:
   /// Modify base attribute of the feature.
   BUILDAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  BUILDAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Shell object.
index c4eaafb4fe371bf6d79605ad12ead1eba6db4e52..21f23e83928e4787616ee7f716ee945f26f0392c 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "BuildAPI_SubShapes.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -49,6 +50,17 @@ void BuildAPI_SubShapes::setSubShapes(const std::list<ModelHighAPI_Selection>& t
   execute();
 }
 
+//==================================================================================================
+void BuildAPI_SubShapes::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addSubShapes(" << aPartName << ", "
+            << aBase->selection(BuildPlugin_SubShapes::BASE_SHAPE_ID()) << ", "
+            << aBase->selectionList(BuildPlugin_SubShapes::SUBSHAPES_ID()) << ")" << std::endl;
+}
+
 //==================================================================================================
 SubShapesPtr addSubShapes(const std::shared_ptr<ModelAPI_Document>& thePart,
                           const ModelHighAPI_Selection& theBaseShape,
index b8108f5bf730bd0b4b556d482c974bea9b78b816..492df6fdc4ed4ab4521e590b6b271b7fc27b6ee2 100644 (file)
@@ -47,6 +47,10 @@ public:
   /// Modify sub-shapes attribute of the feature.
   BUILDAPI_EXPORT
   void setSubShapes(const std::list<ModelHighAPI_Selection>& theSubShapes);
+
+  /// Dump wrapped feature
+  BUILDAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on SubShapes object.
index b1723c84e3141bcd69e63b42657525827dacdc27..1ac2f874959a868204c420e810bbf53d56d2f32b 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "BuildAPI_Vertex.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -46,3 +47,13 @@ VertexPtr addVertex(const std::shared_ptr<ModelAPI_Document>& thePart,
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Vertex::ID());
   return VertexPtr(new BuildAPI_Vertex(aFeature, theBaseObjects));
 }
+
+//==================================================================================================
+void BuildAPI_Vertex::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addVertex(" << aPartName << ", "
+            << aBase->selectionList(BuildPlugin_Vertex::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
index a01ea4c14284f95096a703b3655f696f263fb923..d4dc4b8c58fdce40458a5016e5e19dadcd9f6c97 100644 (file)
@@ -41,6 +41,10 @@ public:
   /// Modify base attribute of the feature.
   BUILDAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  BUILDAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Vertex object.
index 58a498954f066148c5bd6e68b224efbf4ebc09af..124ba6838269f6daf146f68a35c6466a1e4ed9e7 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "BuildAPI_Wire.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -39,6 +40,16 @@ void BuildAPI_Wire::setBase(const std::list<ModelHighAPI_Selection>& theBaseObje
   execute();
 }
 
+//==================================================================================================
+void BuildAPI_Wire::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addWire(" << aPartName << ", "
+            << aBase->selectionList(BuildPlugin_Wire::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
 //==================================================================================================
 void BuildAPI_Wire::addContour()
 {
index d1d24fa71b21c66f3710bb754de9d2a9fb2d89aa..68430929e0f3ce028d82f3725dd6c4696a424013 100644 (file)
@@ -45,6 +45,10 @@ public:
   /// Adds closed contour.
   BUILDAPI_EXPORT
   void addContour();
+
+  /// Dump wrapped feature
+  BUILDAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Wire object.
index 5c5ebb590c87ed3ea28a670170099b363f630813..648aa57d8208189781516ad99aaab76aa62eb8f6 100644 (file)
@@ -54,3 +54,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(anEdgeFeature.results()) == aNumOfLines)
+
+import model
+assert(model.checkPythonDump())
index bd85a3a61717f53ba645f13d8ab314f3d3bc658f..9f4b9e8281aec7ccc952247a9152e581dc3cefad 100644 (file)
@@ -62,3 +62,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(aFaceFeature.results()) > 0)
+
+import model
+assert(model.checkPythonDump())
index cd06246f1568b7188797a2787d8dc893f5c09f10..2406a93b51bf87a296cfbe5d31eceda085a29786 100644 (file)
@@ -77,3 +77,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(aShellFeature.results()) > 0)
+
+import model
+assert(model.checkPythonDump())
index 59668662c84ff151a26f3936770d550b03212f02..e943f66b3752733c6d701583fa7aaf583092f8cc 100644 (file)
@@ -126,3 +126,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(aSubShapesFeature.results()) > 0)
+
+import model
+assert(model.checkPythonDump())
index cc2da7929bd025ed769cba6311e9f467f235640c..d292e6aafd568124430f16c3d8eea192f4bf74e0 100644 (file)
@@ -55,3 +55,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(aVertexFeature.results()) == aNumOfPoints)
+
+import model
+assert(model.checkPythonDump())
index 9b50b70ee5ce15866371dc6826bd7aefafcf2bdd..545c5ffa6e5aea22278c95e90c03f95b9cd0a487 100644 (file)
@@ -62,3 +62,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(aWireFeature.results()) > 0)
+
+import model
+assert(model.checkPythonDump())
index 132adba5124a93bf623cbb65a9f05b0913d46054..399017fea881a8992e3a3a6590b92ff302405d7c 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "ConstructionAPI_Axis.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -196,14 +197,70 @@ void ConstructionAPI_Axis::setByTwoPlanes(const ModelHighAPI_Selection& thePlane
   execute();
 }
 
+//==================================================================================================
+void ConstructionAPI_Axis::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addAxis(" << aDocName;
+
+  std::string aCreationMethod = aBase->string(ConstructionPlugin_Axis::METHOD())->value();
+
+  if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_DIMENSIONS()) {
+    AttributeDoublePtr anAttrDX = aBase->real(ConstructionPlugin_Axis::DX());
+    AttributeDoublePtr anAttrDY = aBase->real(ConstructionPlugin_Axis::DY());
+    AttributeDoublePtr anAttrDZ = aBase->real(ConstructionPlugin_Axis::DZ());
+
+    theDumper << ", " << anAttrDX << ", " << anAttrDY << ", " << anAttrDZ;
+  } else if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_TWO_POINTS()) {
+    AttributeSelectionPtr anAttrFirstPnt = aBase->selection(ConstructionPlugin_Axis::POINT_FIRST());
+    AttributeSelectionPtr anAttrSecondPnt = aBase->selection(ConstructionPlugin_Axis::POINT_SECOND());
+
+    theDumper << ", " << anAttrFirstPnt << ", " << anAttrSecondPnt;
+  } else if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_LINE()) {
+    AttributeSelectionPtr anAttrLine = aBase->selection(ConstructionPlugin_Axis::LINE());
+
+    theDumper << ", " << anAttrLine;
+  } else if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_CYLINDRICAL_FACE()) {
+    AttributeSelectionPtr anAttrFace = aBase->selection(ConstructionPlugin_Axis::CYLINDRICAL_FACE());
+
+    theDumper << ", " << anAttrFace;
+  } else if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_PLANE_AND_POINT()) {
+    AttributeSelectionPtr anAttrPlane = aBase->selection(ConstructionPlugin_Axis::PLANE());
+    AttributeSelectionPtr anAttrPoint = aBase->selection(ConstructionPlugin_Axis::POINT());
+
+    theDumper << ", " << anAttrPlane << ", " << anAttrPoint;
+  } else if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_TWO_PLANES()) {
+    AttributeSelectionPtr anAttrPlane1 = aBase->selection(ConstructionPlugin_Axis::PLANE1());
+    AttributeDoublePtr anAttrOffset1 = aBase->real(ConstructionPlugin_Axis::OFFSET1());
+    AttributeBooleanPtr anAttrReverseOffset1 = aBase->boolean(ConstructionPlugin_Axis::REVERSE_OFFSET1());
+    AttributeSelectionPtr anAttrPlane2 = aBase->selection(ConstructionPlugin_Axis::PLANE2());
+    AttributeDoublePtr anAttrOffset2 = aBase->real(ConstructionPlugin_Axis::OFFSET2());
+    AttributeBooleanPtr anAttrReverseOffset2 = aBase->boolean(ConstructionPlugin_Axis::REVERSE_OFFSET2());
+
+    theDumper << ", " << anAttrPlane1 << ", " << anAttrOffset1 << ", " << anAttrReverseOffset1
+              << ", " << anAttrPlane2 << ", " << anAttrOffset2 << ", " << anAttrReverseOffset2;
+  } else if(aCreationMethod == ConstructionPlugin_Axis::CREATION_METHOD_BY_POINT_AND_DIRECTION()) {
+    AttributeSelectionPtr anAttrFirstPnt = aBase->selection(ConstructionPlugin_Axis::POINT_FIRST());
+    AttributeDoublePtr anAttrX = aBase->real(ConstructionPlugin_Axis::X_DIRECTION());
+    AttributeDoublePtr anAttrY = aBase->real(ConstructionPlugin_Axis::Y_DIRECTION());
+    AttributeDoublePtr anAttrZ = aBase->real(ConstructionPlugin_Axis::Z_DIRECTION());
+
+    theDumper << ", " << anAttrFirstPnt << ", " << anAttrX << ", " << anAttrY << ", " << anAttrZ;
+  }
+
+  theDumper << ")" << std::endl;
+}
+
 //==================================================================================================
 AxisPtr addAxis(const std::shared_ptr<ModelAPI_Document>& thePart,
-                const ModelHighAPI_Selection& thePoint1,
-                const ModelHighAPI_Selection& thePoint2)
+                const ModelHighAPI_Selection& theObject1,
+                const ModelHighAPI_Selection& theObject2)
 {
   // TODO(spo): check that thePart is not empty
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Axis::ID());
-  return AxisPtr(new ConstructionAPI_Axis(aFeature, thePoint1, thePoint2));
+  return AxisPtr(new ConstructionAPI_Axis(aFeature, theObject1, theObject2));
 }
 
 //==================================================================================================
index 0b62587a637ac2a0d3e85d80cd188877d2ab6ee9..fc6bbbc1936fbf96ee7a32b685bfc290039c05b4 100644 (file)
@@ -137,6 +137,10 @@ public:
                       const ModelHighAPI_Selection& thePlane2,
                       const ModelHighAPI_Double& theOffset2,
                       const bool theReverseOffset2);
+
+  /// Dump wrapped feature
+  CONSTRUCTIONAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Axis object
index fdde03ebb39359a00f0d148482e3a5e057e90fc8..b7de5703c0b882fc8e56067c416ce264c13914ab 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "ConstructionAPI_Plane.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -190,6 +191,65 @@ void ConstructionAPI_Plane::setByRotation(const ModelHighAPI_Selection& thePlane
   execute();
 }
 
+//==================================================================================================
+void ConstructionAPI_Plane::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addPlane(" << aDocName;
+
+  std::string aCreationMethod = aBase->string(ConstructionPlugin_Plane::CREATION_METHOD())->value();
+
+  if(aCreationMethod == ConstructionPlugin_Plane::CREATION_METHOD_BY_GENERAL_EQUATION()) {
+    AttributeDoublePtr anAttrA = aBase->real(ConstructionPlugin_Plane::A());
+    AttributeDoublePtr anAttrB = aBase->real(ConstructionPlugin_Plane::B());
+    AttributeDoublePtr anAttrC = aBase->real(ConstructionPlugin_Plane::C());
+    AttributeDoublePtr anAttrD = aBase->real(ConstructionPlugin_Plane::D());
+
+    theDumper << ", " << anAttrA << ", " << anAttrB << ", " << anAttrC << ", " << anAttrD;
+  } else if(aCreationMethod == ConstructionPlugin_Plane::CREATION_METHOD_BY_THREE_POINTS()) {
+    AttributeSelectionPtr anAttrPnt1 = aBase->selection(ConstructionPlugin_Plane::POINT1());
+    AttributeSelectionPtr anAttrPnt2 = aBase->selection(ConstructionPlugin_Plane::POINT2());
+    AttributeSelectionPtr anAttrPnt3 = aBase->selection(ConstructionPlugin_Plane::POINT3());
+
+    theDumper << ", " << anAttrPnt1 << ", " << anAttrPnt2 << ", " << anAttrPnt3;
+  } else if(aCreationMethod == ConstructionPlugin_Plane::CREATION_METHOD_BY_LINE_AND_POINT()) {
+    AttributeSelectionPtr anAttrLine = aBase->selection(ConstructionPlugin_Plane::LINE());
+    AttributeSelectionPtr anAttrPoint = aBase->selection(ConstructionPlugin_Plane::POINT());
+    AttributeBooleanPtr anAttrPerpendicular = aBase->boolean(ConstructionPlugin_Plane::PERPENDICULAR());
+
+    theDumper << ", " << anAttrLine << ", " << anAttrPoint << ", " << anAttrPerpendicular;
+  } else if(aCreationMethod == ConstructionPlugin_Plane::CREATION_METHOD_BY_OTHER_PLANE()) {
+    AttributeSelectionPtr anAttrPlane = aBase->selection(ConstructionPlugin_Plane::PLANE());
+
+    std::string aCreationMethodOption =
+        aBase->string(ConstructionPlugin_Plane::CREATION_METHOD_BY_OTHER_PLANE_OPTION())->value();
+    if(aCreationMethodOption == ConstructionPlugin_Plane::CREATION_METHOD_BY_DISTANCE_FROM_OTHER()) {
+      AttributeDoublePtr anAttrDistance = aBase->real(ConstructionPlugin_Plane::DISTANCE());
+      AttributeBooleanPtr anAttrReverse = aBase->boolean(ConstructionPlugin_Plane::REVERSE());
+
+      theDumper << ", " << anAttrPlane << ", " << anAttrDistance << ", " << anAttrReverse;
+    } else if(aCreationMethodOption == ConstructionPlugin_Plane::CREATION_METHOD_BY_COINCIDENT_TO_POINT()) {
+      AttributeSelectionPtr anAttrPoint = aBase->selection(ConstructionPlugin_Plane::COINCIDENT_POINT());
+
+      theDumper << ", " << anAttrPlane << ", " << anAttrPoint;
+    } else if(aCreationMethodOption == ConstructionPlugin_Plane::CREATION_METHOD_BY_ROTATION()) {
+      AttributeSelectionPtr anAttrAxis = aBase->selection(ConstructionPlugin_Plane::AXIS());
+      AttributeDoublePtr anAttrAngle = aBase->real(ConstructionPlugin_Plane::ANGLE());
+
+      theDumper << ", " << anAttrPlane << ", " << anAttrAxis << ", " << anAttrAngle;
+    }
+  } else if(aCreationMethod == ConstructionPlugin_Plane::CREATION_METHOD_BY_TWO_PARALLEL_PLANES()) {
+    AttributeSelectionPtr anAttrPlane1 = aBase->selection(ConstructionPlugin_Plane::PLANE1());
+    AttributeSelectionPtr anAttrPlane2 = aBase->selection(ConstructionPlugin_Plane::PLANE2());
+
+    theDumper << ", " << anAttrPlane1 << ", " << anAttrPlane2;
+  }
+
+  theDumper << ")" << std::endl;
+}
+
 //==================================================================================================
 PlanePtr addPlane(const std::shared_ptr<ModelAPI_Document>& thePart,
                   const ModelHighAPI_Selection& theFace,
index 2aaac52290ab71e0b6697cb4e421219d50537bcc..48eef87db38f27daea155b6e2c26ee2f5e10a268 100644 (file)
@@ -136,6 +136,9 @@ public:
                      const ModelHighAPI_Selection& theAxis,
                      const ModelHighAPI_Double& theAngle);
 
+  /// Dump wrapped feature
+  CONSTRUCTIONAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Plane object
index c503c16fa9c0885473a0ee4c8a672a558cb832d5..5e9aea6e18b291132bd0aa7dcf2045e498c15d13 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <GeomAPI_Shape.h>
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 
@@ -82,7 +83,7 @@ void ConstructionAPI_Point::setByXYZ(const ModelHighAPI_Double& theX,
   fillAttribute(theY, myy);
   fillAttribute(theZ, myz);
 
-  execute();
+  execute(false);
 }
 
 /*//==================================================================================================
@@ -133,6 +134,21 @@ void ConstructionAPI_Point::setByLineAndPlaneIntersection(const ModelHighAPI_Sel
   execute();
 }*/
 
+//==================================================================================================
+void ConstructionAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  // TODO: all types of points
+
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeDoublePtr anAttrX = aBase->real(ConstructionPlugin_Point::X());
+  AttributeDoublePtr anAttrY = aBase->real(ConstructionPlugin_Point::Y());
+  AttributeDoublePtr anAttrZ = aBase->real(ConstructionPlugin_Point::Z());
+  theDumper << aBase << " = model.addPoint(" << aDocName << ", "
+            << anAttrX << ", " << anAttrY << ", " << anAttrZ << ")" << std::endl;
+}
+
 //==================================================================================================
 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document>& thePart,
                   const ModelHighAPI_Double& theX,
index c27ea76d57357a658a4d41070016fa19022c5ba5..6c2b295bb69c0490bd1f178a6f85261773c5d7f0 100644 (file)
@@ -102,6 +102,10 @@ public:
   CONSTRUCTIONAPI_EXPORT
   void setByLineAndPlaneIntersection(const ModelHighAPI_Selection& theEdge,
                                      const ModelHighAPI_Selection& theFace);*/
+
+  /// Dump wrapped feature
+  CONSTRUCTIONAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Point object.
index 626ff62b76924566020f5df9da1cbc0db232629a..ddce019986744cce1816df5fe1cf39d3bb893bcf 100644 (file)
@@ -2,6 +2,7 @@ import unittest
 
 import ModelAPI
 import ConstructionAPI
+import model
 
 class AxisTestCase(unittest.TestCase):
 
@@ -14,6 +15,7 @@ class AxisTestCase(unittest.TestCase):
         self.session.finishOperation()
 
     def tearDown(self):
+        assert(model.checkPythonDump())
         self.session.closeAll()
 
     def test_ConstructorWithDimensions(self):
index a1bc2eca78e2292a5bcccf7af74e8ec857950ffc..929610f575eeee4793c7f05f6cd2973a314726f0 100644 (file)
@@ -2,6 +2,7 @@ import unittest
 
 import ModelAPI
 import ConstructionAPI
+import model
 
 class PointTestCase(unittest.TestCase):
 
@@ -10,10 +11,10 @@ class PointTestCase(unittest.TestCase):
         self.doc = self.session.moduleDocument()
         self.session.startOperation()
         self.feature = self.doc.addFeature("Point")
-        self.feature.execute()
-        self.session.finishOperation()
 
     def tearDown(self):
+        self.session.finishOperation()
+        assert(model.checkPythonDump())
         self.session.closeAll()
 
     def test_ConstructorWithValues(self):
@@ -24,9 +25,9 @@ class PointTestCase(unittest.TestCase):
 
     def test_setValue(self):
         point = ConstructionAPI.ConstructionAPI_Point(self.feature)
-        self.assertEqual(0, point.x().value())
-        self.assertEqual(0, point.y().value())
-        self.assertEqual(0, point.z().value())
+        assert(point.x().isInitialized() == False)
+        assert(point.y().isInitialized() == False)
+        assert(point.z().isInitialized() == False)
 
         point.setByXYZ(10, "20", "x + 30")
         self.assertEqual(10, point.x().value())
index 00263fbf70190cffeba5d3997700e723ed504173..43ac4fdadeb1581698497044086c1471849f68e7 100644 (file)
@@ -59,6 +59,6 @@ INCLUDE_DIRECTORIES(
 
 ADD_UNIT_TESTS(TestAxisCreation.py
                UnitTestAxis.py
-               TestPointName.py
                TestPoint.py
+               TestPointName.py
                TestPlane.py)
index 86ce8bc3771f001a72de3916b8147e34a8820052..77be60ef1dfd48437eaa6c99291f36eb806c3af3 100644 (file)
@@ -188,3 +188,6 @@ aSession.startOperation()
 anAxis = model.addAxis(aPart, aPlane1.result()[0], 50, False, aPlane2.result()[0], 100, True)
 aSession.finishOperation()
 assert (len(anAxis.result()) > 0)
+
+#import model
+#assert(model.checkPythonDump())
index 0661b4dd3e7589f6613d0bbbebfe58a8f7da726b..3a3b7c862d2fc2149fb0bdfb70c9a062bf835427 100644 (file)
@@ -82,3 +82,6 @@ aSession.startOperation()
 aPlane = model.addPlane(aDocument, aCoincidentPlane.result()[0], aPlane.result()[0])
 aSession.finishOperation()
 assert (len(aPlane.result()) > 0)
+
+import model
+assert(model.checkPythonDump())
index 5ea7e780b5287d5c07b447730db0ecb09ce1bf7c..d91d746345f18923b8fb934fcffdfa7ec5b822d1 100644 (file)
@@ -60,3 +60,5 @@ assert (len(aPoint.result()) > 0)
 # aPoint = model.addPoint(aDocument, aSketchLine1.result()[0], aPlane.result()[0])
 # aSession.finishOperation()
 # assert (len(aPoint.result()) > 0)
+
+assert(model.checkPythonDump())
index fcf606b054c6a19baaf45a188115f1c1f11a77eb..9d17c2294d5427a10122ef646de6a2144a3f1243 100644 (file)
@@ -20,3 +20,6 @@ aFeature1 = aDoc.object("Construction", 7)
 aFeature1Name = aFeature1.data().name()
 
 assert (aFeatureName == aFeature1Name)
+
+import model
+assert(model.checkPythonDump())
index 845dcef37b7f27fa03aa0acd520c8f7881c1e130..9dbb8c8fc491261fbe7f364965eb84298138d4a2 100644 (file)
@@ -74,3 +74,6 @@ aSession.finishOperation()
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 176df43ccbb063fcd0c5b67ac1706e82b6a38a47..68a0b464536359d64579f4dde80738aa56a17107 100644 (file)
@@ -16,6 +16,7 @@ void exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
 {
   // TODO(spo): check that thePart is not empty
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangePlugin_ExportFeature::ID());
+  fillAttribute("Regular", aFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
   fillAttribute(theFilePath, aFeature->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()));
   fillAttribute(theSelectionList, aFeature->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()));
   fillAttribute(theFileFormat, aFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
@@ -29,9 +30,11 @@ void exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
 {
   // TODO(spo): check that thePart is not empty
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangePlugin_ExportFeature::ID());
-  fillAttribute(theFilePath, aFeature->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()));
+  fillAttribute("XAO", aFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
+  fillAttribute(theFilePath, aFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
   fillAttribute(theAuthor, aFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
   fillAttribute(theGeometryName, aFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
+  fillAttribute("XAO", aFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
   aFeature->execute();
 }
 
index 0c2e7ff7d33fe4ebebaa1a58fe99693550f26a1f..cf8b40089326b9e928d4b4d54051d8b104224de6 100644 (file)
@@ -7,8 +7,11 @@
 //--------------------------------------------------------------------------------------
 #include "ExchangeAPI_Import.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
+#include <algorithm>
+
 ExchangeAPI_Import::ExchangeAPI_Import(
     const std::shared_ptr<ModelAPI_Feature> & theFeature)
 : ModelHighAPI_Interface(theFeature)
@@ -38,6 +41,37 @@ void ExchangeAPI_Import::setFilePath(const std::string & theFilePath)
   execute();
 }
 
+//--------------------------------------------------------------------------------------
+void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  std::string aPartName = theDumper.name(aBase->document());
+
+  std::string aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value();
+  std::string aFrom = "\\";
+  std::string aTo = "\\\\";
+  for(std::size_t aPos = aFilePath.find(aFrom);
+      aPos != std::string::npos;
+      aPos = aFilePath.find(aFrom, aPos)) {
+    aFilePath.replace(aPos, aFrom.size(), aTo);
+    aPos += aTo.size();
+  }
+
+  theDumper << aBase << " = model.addImport(" << aPartName << ", \""
+            << aFilePath << "\")" << std::endl;
+  // to make import have results
+  theDumper << "model.do()" << std::endl;
+
+  CompositeFeaturePtr aCompositeFeature = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
+  if(aCompositeFeature.get()) {
+    int aNbOfSubs = aCompositeFeature->numberOfSubs();
+    for(int anIndex = 0; anIndex < aNbOfSubs; ++anIndex) {
+      std::string aSubFeatureGet = theDumper.name(aBase) + ".subFeature(" + std::to_string((long long)anIndex) + ")";
+      theDumper.dumpSubFeatureNameAndColor(aSubFeatureGet, aCompositeFeature->subFeature(anIndex));
+    }
+  }
+}
+
 //--------------------------------------------------------------------------------------
 ImportPtr addImport(
     const std::shared_ptr<ModelAPI_Document> & thePart,
index 015b374f39803d697851d154d83c6096528755d6..7f55c7342470159db302555996d9c71e1f768134 100644 (file)
@@ -42,6 +42,10 @@ public:
   /// Set point values
   EXCHANGEAPI_EXPORT
   void setFilePath(const std::string & theFilePath);
+
+  /// Dump wrapped feature
+  EXCHANGEAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Import object
index 681688fa1f06482bf958bca552991e6a13435bbd..d628d4f015d628203888fd68336cfece40ca2ecd 100644 (file)
@@ -2,6 +2,7 @@ import unittest
 
 import ModelAPI
 import ExchangeAPI
+import model
 
 class ExchangeTestCase(unittest.TestCase):
 
@@ -10,6 +11,9 @@ class ExchangeTestCase(unittest.TestCase):
         self.doc = self.session.moduleDocument()
 
     def tearDown(self):
+        # assert(model.checkPythonDump())
+        # This test just checks interface of Exchange High API
+        # Export feature stays in the tree because it's invalid, but after dump it is not in the tree.
         self.session.closeAll()
 
     def test_addImport(self):
index 0745869cee2134e6065c4f6cfe9f15a32a21f6ff..2e11f037530f328897f399b0215658bcccf55b1c 100644 (file)
@@ -6,6 +6,7 @@ INCLUDE(UnitTest)
 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/Config
                     ${PROJECT_SOURCE_DIR}/src/ModelAPI
+                    ${PROJECT_SOURCE_DIR}/src/ModelHighAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
                     ${PROJECT_SOURCE_DIR}/src/XAO
@@ -18,6 +19,7 @@ SET(PROJECT_HEADERS
     ExchangePlugin_ExportFeature.h
     ExchangePlugin_Validators.h
     ExchangePlugin_Tools.h
+    ExchangePlugin_Dump.h
 )
 
 SET(PROJECT_SOURCES
@@ -26,6 +28,7 @@ SET(PROJECT_SOURCES
     ExchangePlugin_ExportFeature.cpp
     ExchangePlugin_Validators.cpp
     ExchangePlugin_Tools.cpp
+    ExchangePlugin_Dump.cpp
 )
 
 SET(XML_RESOURCES
@@ -41,6 +44,7 @@ SET(PROJECT_LIBRARIES
     Events
     Config
     ModelAPI
+    ModelHighAPI
     GeomAPI
     GeomAlgoAPI
     XAO
diff --git a/src/ExchangePlugin/ExchangePlugin_Dump.cpp b/src/ExchangePlugin/ExchangePlugin_Dump.cpp
new file mode 100644 (file)
index 0000000..168e9dc
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:    ExchangePlugin_ExportFeature.cpp
+// Created: May 14, 2015
+// Author:  Sergey POKHODENKO
+
+#include <ExchangePlugin_Dump.h>
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Session.h>
+
+#include <ModelHighAPI_Dumper.h>
+
+#include <Config_ModuleReader.h>
+
+
+ExchangePlugin_Dump::ExchangePlugin_Dump()
+{
+}
+
+ExchangePlugin_Dump::~ExchangePlugin_Dump()
+{
+}
+
+void ExchangePlugin_Dump::initAttributes()
+{
+  data()->addAttribute(ExchangePlugin_Dump::FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(ExchangePlugin_Dump::FILE_FORMAT_ID(), ModelAPI_AttributeString::typeId());
+}
+
+void ExchangePlugin_Dump::execute()
+{
+  AttributeStringPtr aFilePathAttr =
+      this->string(ExchangePlugin_Dump::FILE_PATH_ID());
+  std::string aFilePath = aFilePathAttr->value();
+  if (aFilePath.empty())
+    return;
+
+  dump(aFilePath);
+}
+
+void ExchangePlugin_Dump::dump(const std::string& theFileName)
+{
+  // load DumpAssistant from Python side
+  Config_ModuleReader::loadScript("model.dump");
+
+  ModelHighAPI_Dumper* aDumper = ModelHighAPI_Dumper::getInstance();
+  aDumper->clear();
+  DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument();
+  if (!aDumper || !aDumper->process(aDoc, theFileName))
+    setError("An error occured while dumping to " + theFileName);
+}
diff --git a/src/ExchangePlugin/ExchangePlugin_Dump.h b/src/ExchangePlugin/ExchangePlugin_Dump.h
new file mode 100644 (file)
index 0000000..dc40965
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
+
+// File:    ExchangePlugin_Dump.h
+// Created: August 1, 2016
+// Author:  Artem ZHIDKOV
+
+#ifndef EXCHANGEPLUGIN_DUMP_H_
+#define EXCHANGEPLUGIN_DUMP_H_
+
+#include <ExchangePlugin.h>
+
+#include <ModelAPI_Feature.h>
+
+/**
+ * \class ExchangePlugin_Dump
+ * \ingroup Plugins
+ * \brief Store full model as a Python script
+ */
+class ExchangePlugin_Dump : public ModelAPI_Feature
+{
+public:
+  /// Feature kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_DUMP_ID("Dump");
+    return MY_DUMP_ID;
+  }
+  /// attribute name of file path
+  inline static const std::string& FILE_PATH_ID()
+  {
+    static const std::string MY_FILE_PATH_ID("file_path");
+    return MY_FILE_PATH_ID;
+  }
+  /// attribute name of file format
+  inline static const std::string& FILE_FORMAT_ID()
+  {
+    static const std::string MY_FILE_FORMAT_ID("file_format");
+    return MY_FILE_FORMAT_ID;
+  }
+
+  /// Default constructor
+  EXCHANGEPLUGIN_EXPORT ExchangePlugin_Dump();
+  /// Default destructor
+  EXCHANGEPLUGIN_EXPORT virtual ~ExchangePlugin_Dump();
+
+  /// Returns the unique kind of a feature
+  EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    return ExchangePlugin_Dump::ID();
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  EXCHANGEPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Computes or recomputes the results
+  EXCHANGEPLUGIN_EXPORT virtual void execute();
+
+  /// Reimplemented from ModelAPI_Feature::isMacro(). Returns true.
+  EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+  /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
+  EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+
+protected:
+  /// Performs dump to the file
+  EXCHANGEPLUGIN_EXPORT void dump(const std::string& theFileName);
+};
+
+#endif
index e731309c3896018630dde2abe962449582cdc9e5..af30181453b3be8b09cf07992c475931c73ed6f2 100644 (file)
@@ -5,6 +5,7 @@
 // Author:  Sergey BELASH
 
 #include <ExchangePlugin_Plugin.h>
+#include <ExchangePlugin_Dump.h>
 #include <ExchangePlugin_ImportFeature.h>
 #include <ExchangePlugin_ExportFeature.h>
 #include <ExchangePlugin_Validators.h>
@@ -40,6 +41,9 @@ FeaturePtr ExchangePlugin_Plugin::createFeature(string theFeatureID)
   } else
   if (theFeatureID == ExchangePlugin_ExportFeature::ID()) {
     return FeaturePtr(new ExchangePlugin_ExportFeature);
+  } else
+  if (theFeatureID == ExchangePlugin_Dump::ID()) {
+    return FeaturePtr(new ExchangePlugin_Dump);
   }
   // feature of such kind is not found
   return FeaturePtr();
index a8113e799147bec5d025f4f5874457717bab0476..eda5c0aff3e2a9c0f647177d637695757e61dfec 100644 (file)
@@ -90,16 +90,16 @@ def testExportXAO():
 
     aSession.startOperation()
     aGroup = model.addGroup(aPart, [])
-    aGroup.defaultResult().data().setName("")
     aGroup.groupList().setSelectionType("face")
     aGroup.groupList().append("Box_1_1/Shape1_1")
     aGroup.groupList().append("Box_1_1/Shape2_1")
+    aGroup.defaultResult().data().setName("")
 #     aGroupFeature = aSession.activeDocument().addFeature("Group")
 #     aGroupFeature.data().setName("")
 #     aSelectionListAttr = aGroupFeature.selectionList("group_list")
 #     aSelectionListAttr.setSelectionType("face")
-#     aSelectionListAttr.append("Box_1_1/Shape1_1")
-#     aSelectionListAttr.append("Box_1_1/Shape2_1")
+#     aSelectionListAttr.append("Box_1_1/Shape1")
+#     aSelectionListAttr.append("Box_1_1/Shape2")
 #     aGroupFeature.execute()
     aSession.finishOperation()
 
@@ -145,3 +145,5 @@ if __name__ == '__main__':
 #=========================================================================
 # End of test
 #=========================================================================
+
+assert(model.checkPythonDump())
index 5a07ad66a303545ba3641ed6b5d06225c23338e1..55e805cd538f34f563dff5f1ba22a50376502db0 100644 (file)
@@ -73,7 +73,7 @@ def testImportXAO():
     aSelectionList = aFeature1.selectionList("group_list")
     assert aSelectionList.selectionType() == "solid"
     assert aSelectionList.size() == 1
-    assert aSelectionList.value(0).namingName("") == "mygeom_1_1"
+    assert aSelectionList.value(0).namingName("") == "mygeom_1"
 
     aFeature2 = aCompositeFeature.subFeature(1, False)
     assert aFeature2.getKind() == "Group"
@@ -82,8 +82,9 @@ def testImportXAO():
     aSelectionList = aFeature2.selectionList("group_list") 
     assert aSelectionList.selectionType() == "face"
     assert aSelectionList.size() == 2
-    assert aSelectionList.value(0).namingName("") == "mygeom_1/Shape1_1"
-    assert aSelectionList.value(1).namingName("") == "mygeom_1/Shape2_1"
+    assert aSelectionList.value(0).namingName("") == "mygeom_1/Shape1"
+    print aSelectionList.value(1).namingName("")
+    assert aSelectionList.value(1).namingName("") == "mygeom_1/Shape2"
 
 if __name__ == '__main__':
 #=========================================================================
@@ -108,3 +109,6 @@ if __name__ == '__main__':
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
diff --git a/src/ExchangePlugin/icons/dump.png b/src/ExchangePlugin/icons/dump.png
new file mode 100644 (file)
index 0000000..196cf55
Binary files /dev/null and b/src/ExchangePlugin/icons/dump.png differ
index f428938d91b73d60616ae4d115fc679032db1753..abd5f75baba9afbce476ca4f133dc72c95805faa 100755 (executable)
       <feature id="Export" title="Export" tooltip="Export to file" icon="icons/Exchange/export.png">
         <source path="export_widget.xml" />
       </feature>
+      <feature id="Dump" title="Dump" tooltip="Dump python script" icon="icons/Exchange/dump.png">
+        <export_file_selector id="file_path"
+                              type="save"
+                              title="Dump to file"
+                              path="">
+          <validator id="ExchangePlugin_ExportFormat"
+                     parameters="py:Python" />
+        </export_file_selector>
+      </feature>
     </group>
   </workbench>
 </plugin>
\ No newline at end of file
index 1db8f2dd69765e6b3b03ad9ee6bb28c9ef633c1b..70ea1166d1cc9a8d8dd4b2569cd17d97da963e8a 100644 (file)
@@ -18,6 +18,7 @@ SET(PROJECT_HEADERS
   FeaturesAPI_RevolutionBoolean.h
   FeaturesAPI_Rotation.h
   FeaturesAPI_Translation.h
+  FeaturesAPI_Union.h
 )
 
 SET(PROJECT_SOURCES
@@ -35,6 +36,7 @@ SET(PROJECT_SOURCES
   FeaturesAPI_RevolutionBoolean.cpp
   FeaturesAPI_Rotation.cpp
   FeaturesAPI_Translation.cpp
+  FeaturesAPI_Union.cpp
 )
 
 SET(PROJECT_LIBRARIES
index d2c9f968a0ecba19b569ca9a027bf4070447b359..cc7cbdd54b18dc6d4553d9855ce800624bbb91e9 100644 (file)
@@ -37,6 +37,7 @@
 %shared_ptr(FeaturesAPI_RevolutionFuse)
 %shared_ptr(FeaturesAPI_Rotation)
 %shared_ptr(FeaturesAPI_Translation)
+%shared_ptr(FeaturesAPI_Union)
 
 // all supported interfaces
 %include "FeaturesAPI_Boolean.h"
@@ -53,3 +54,4 @@
 %include "FeaturesAPI_RevolutionBoolean.h"
 %include "FeaturesAPI_Rotation.h"
 %include "FeaturesAPI_Translation.h"
+%include "FeaturesAPI_Union.h"
index 4ee728c6c45132dee6e2606b599a74b76652dbd8..f47eab172fd41fbc0562b6ccca1785bb09c892da 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Boolean.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Integer.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
@@ -29,7 +30,7 @@ FeaturesAPI_Boolean::FeaturesAPI_Boolean(const std::shared_ptr<ModelAPI_Feature>
     fillAttribute(theMainObjects, mymainObjects);
     fillAttribute(theToolObjects, mytoolObjects);
 
-    execute();
+    execute(false);
   }
 }
 
@@ -63,6 +64,31 @@ void FeaturesAPI_Boolean::setToolObjects(const std::list<ModelHighAPI_Selection>
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Boolean::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+
+  FeaturesPlugin_Boolean::OperationType aType =
+      (FeaturesPlugin_Boolean::OperationType)aBase->integer(FeaturesPlugin_Boolean::TYPE_ID())->value();
+
+  theDumper << aBase << " = model.add";
+
+  switch(aType) {
+    case FeaturesPlugin_Boolean::BOOL_CUT:    theDumper << "Cut";    break;
+    case FeaturesPlugin_Boolean::BOOL_FUSE:   theDumper << "Fuse";   break;
+    case FeaturesPlugin_Boolean::BOOL_COMMON: theDumper << "Common"; break;
+    case FeaturesPlugin_Boolean::BOOL_FILL:   theDumper << "Fill";   break;
+    case FeaturesPlugin_Boolean::BOOL_SMASH:  theDumper << "Smash";  break;
+  }
+
+  const std::string& aDocName = theDumper.name(aBase->document());
+  AttributeSelectionListPtr anObjects = aBase->selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
+  AttributeSelectionListPtr aTools = aBase->selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
+
+  theDumper << "(" << aDocName << ", " << anObjects << ", " << aTools << ")" << std::endl;
+}
+
 //==================================================================================================
 BooleanPtr addCut(const std::shared_ptr<ModelAPI_Document>& thePart,
                   const std::list<ModelHighAPI_Selection>& theMainObjects,
index 9ad38f4bcf4b462cb0cb8a3c1db36a8b4f441f1e..f314158cd851905708017ebc6aa5d03d64f1032a 100644 (file)
@@ -54,6 +54,10 @@ public:
   /// Set tool objects.
   FEATURESAPI_EXPORT
   void setToolObjects(const std::list<ModelHighAPI_Selection>& theToolObjects);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Boolean object.
index d79749b5f28389b1114568008bcb158d71327588..e2f3171822432b2969be7e1eceba098ad0876877 100644 (file)
@@ -7,6 +7,8 @@
 #include "FeaturesAPI_Extrusion.h"
 
 #include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Reference.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -105,15 +107,26 @@ FeaturesAPI_Extrusion::FeaturesAPI_Extrusion(const std::shared_ptr<ModelAPI_Feat
 //==================================================================================================
 FeaturesAPI_Extrusion::~FeaturesAPI_Extrusion()
 {
+}
+
+//==================================================================================================
+void FeaturesAPI_Extrusion::setNestedSketch(const ModelHighAPI_Reference& theSketch)
+{
+  mysketch->setValue(theSketch.feature());
+  mybaseObjects->clear();
+  mybaseObjects->append(theSketch.feature()->firstResult(), GeomShapePtr());
 
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
 void FeaturesAPI_Extrusion::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
 {
+  mysketch->setValue(ObjectPtr());
+  mybaseObjects->clear();
   fillAttribute(theBaseObjects, mybaseObjects);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -121,7 +134,7 @@ void FeaturesAPI_Extrusion::setDirection(const ModelHighAPI_Selection& theDirect
 {
   fillAttribute(theDirection, mydirection);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -132,7 +145,7 @@ void FeaturesAPI_Extrusion::setSizes(const ModelHighAPI_Double& theToSize,
   fillAttribute(theToSize, mytoSize);
   fillAttribute(theFromSize, myfromSize);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -142,7 +155,7 @@ void FeaturesAPI_Extrusion::setSize(const ModelHighAPI_Double& theSize)
   fillAttribute(theSize, mytoSize);
   fillAttribute(ModelHighAPI_Double(), myfromSize);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -157,7 +170,52 @@ void FeaturesAPI_Extrusion::setPlanesAndOffsets(const ModelHighAPI_Selection& th
   fillAttribute(theFromObject, myfromObject);
   fillAttribute(theFromOffset, myfromOffset);
 
-  execute();
+  execIfBaseNotEmpty();
+}
+
+//==================================================================================================
+void FeaturesAPI_Extrusion::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeReferencePtr anAttrSketch = aBase->reference(FeaturesPlugin_Extrusion::SKETCH_ID());
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID());
+  AttributeSelectionPtr anAttrDirection = aBase->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID());
+
+  theDumper << aBase << " = model.addExtrusion(" << aDocName << ", ";
+  anAttrSketch->isInitialized() ? theDumper << "[]" : theDumper << anAttrObjects;
+  theDumper << ", " << anAttrDirection;
+
+  std::string aCreationMethod = aBase->string(FeaturesPlugin_Extrusion::CREATION_METHOD())->value();
+
+  if(aCreationMethod == FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES()) {
+    AttributeDoublePtr anAttrToSize = aBase->real(FeaturesPlugin_Extrusion::TO_SIZE_ID());
+    AttributeDoublePtr anAttrFromSize = aBase->real(FeaturesPlugin_Extrusion::FROM_SIZE_ID());
+
+    theDumper << ", " << anAttrToSize << ", " << anAttrFromSize;
+  } else if(aCreationMethod == FeaturesPlugin_Extrusion::CREATION_METHOD_BY_PLANES()) {
+    AttributeSelectionPtr anAttrToObject = aBase->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID());
+    AttributeDoublePtr anAttrToOffset = aBase->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID());
+    AttributeSelectionPtr anAttrFromObject = aBase->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID());
+    AttributeDoublePtr anAttrFromOffset = aBase->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID());
+
+    theDumper << ", " << anAttrToObject << ", " << anAttrToOffset << ", " << anAttrFromObject << ", " << anAttrFromOffset;
+  }
+
+  theDumper << ")" << std::endl;
+
+  if(anAttrSketch->isInitialized()) {
+    theDumper << aBase << ".setNestedSketch(" << anAttrSketch << ")" << std::endl;
+  }
+}
+
+//==================================================================================================
+void FeaturesAPI_Extrusion::execIfBaseNotEmpty()
+{
+  if(mybaseObjects->size() > 0) {
+    execute();
+  }
 }
 
 //==================================================================================================
index 2c569802f942c7a48db6e82bd913c0b68c0d8a65..9350d981737791046d7e3943c3b9108a8afe538d 100644 (file)
@@ -15,6 +15,7 @@
 #include <ModelHighAPI_Macro.h>
 
 class ModelHighAPI_Double;
+class ModelHighAPI_Reference;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Extrusion
@@ -78,16 +79,20 @@ public:
   virtual ~FeaturesAPI_Extrusion();
 
   INTERFACE_10(FeaturesPlugin_Extrusion::ID(),
+               sketch, FeaturesPlugin_Extrusion::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */,
                baseObjects, FeaturesPlugin_Extrusion::BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Base objects */,
+               direction, FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID(), ModelAPI_AttributeSelection, /** Direction */,
                creationMethod, FeaturesPlugin_Extrusion::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */,
                toSize, FeaturesPlugin_Extrusion::TO_SIZE_ID(), ModelAPI_AttributeDouble, /** To size */,
                fromSize, FeaturesPlugin_Extrusion::FROM_SIZE_ID(), ModelAPI_AttributeDouble, /** From size */,
                toObject, FeaturesPlugin_Extrusion::TO_OBJECT_ID(), ModelAPI_AttributeSelection, /** To object */,
                toOffset, FeaturesPlugin_Extrusion::TO_OFFSET_ID(), ModelAPI_AttributeDouble, /** To offset */,
                fromObject, FeaturesPlugin_Extrusion::FROM_OBJECT_ID(), ModelAPI_AttributeSelection, /** From object */,
-               fromOffset, FeaturesPlugin_Extrusion::FROM_OFFSET_ID(), ModelAPI_AttributeDouble, /** From offset */,
-               direction, FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID(), ModelAPI_AttributeSelection, /** Direction */,
-               sketchLauncher, FeaturesPlugin_Extrusion::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */)
+               fromOffset, FeaturesPlugin_Extrusion::FROM_OFFSET_ID(), ModelAPI_AttributeDouble, /** From offset */)
+
+  /// Modify base attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setNestedSketch(const ModelHighAPI_Reference& theSketch);
 
   /// Modify base attribute of the feature.
   FEATURESAPI_EXPORT
@@ -111,6 +116,13 @@ public:
                            const ModelHighAPI_Double& theToOffset,
                            const ModelHighAPI_Selection& theFromObject,
                            const ModelHighAPI_Double& theFromOffset);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+  void execIfBaseNotEmpty();
 };
 
 /// Pointer on Extrusion object.
index 357421b6ee9bf181b292e4f9fb448e875efbd89c..d384af987bf6d0650a671eb191f7155a4515f10d 100644 (file)
@@ -7,6 +7,8 @@
 #include "FeaturesAPI_ExtrusionBoolean.h"
 
 #include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Reference.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -20,12 +22,24 @@ FeaturesAPI_ExtrusionBoolean::~FeaturesAPI_ExtrusionBoolean()
 {
 }
 
+//==================================================================================================
+void FeaturesAPI_ExtrusionBoolean::setNestedSketch(const ModelHighAPI_Reference& theSketch)
+{
+  mysketch->setValue(theSketch.feature());
+  mybaseObjects->clear();
+  mybaseObjects->append(theSketch.feature()->firstResult(), GeomShapePtr());
+
+  execIfBaseNotEmpty();
+}
+
 //==================================================================================================
 void FeaturesAPI_ExtrusionBoolean::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
 {
+  mysketch->setValue(ObjectPtr());
+  mybaseObjects->clear();
   fillAttribute(theBaseObjects, mybaseObjects);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -33,7 +47,7 @@ void FeaturesAPI_ExtrusionBoolean::setDirection(const ModelHighAPI_Selection& th
 {
   fillAttribute(theDirection, mydirection);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -44,7 +58,7 @@ void FeaturesAPI_ExtrusionBoolean::setSizes(const ModelHighAPI_Double& theToSize
   fillAttribute(theToSize, mytoSize);
   fillAttribute(theFromSize, myfromSize);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -54,7 +68,7 @@ void FeaturesAPI_ExtrusionBoolean::setSize(const ModelHighAPI_Double& theSize)
   fillAttribute(theSize, mytoSize);
   fillAttribute(ModelHighAPI_Double(), myfromSize);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -69,7 +83,7 @@ void FeaturesAPI_ExtrusionBoolean::setPlanesAndOffsets(const ModelHighAPI_Select
   fillAttribute(theFromObject, myfromObject);
   fillAttribute(theFromOffset, myfromOffset);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -77,9 +91,62 @@ void FeaturesAPI_ExtrusionBoolean::setBooleanObjects(const std::list<ModelHighAP
 {
   fillAttribute(theBooleanObjects, mybooleanObjects);
 
-  execute();
+  execIfBaseNotEmpty();
+}
+
+//==================================================================================================
+void FeaturesAPI_ExtrusionBoolean::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeReferencePtr anAttrSketch = aBase->reference(FeaturesPlugin_Extrusion::SKETCH_ID());
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID());
+  AttributeSelectionPtr anAttrDirection = aBase->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID());
+
+  theDumper << aBase << " = model.addExtrusion";
+  if(aBase->getKind() == FeaturesPlugin_ExtrusionCut::ID()) {
+    theDumper << "Cut";
+  } else if(aBase->getKind() == FeaturesPlugin_ExtrusionFuse::ID()) {
+    theDumper << "Fuse";
+  }
+  theDumper << "(" << aDocName << ", ";
+  anAttrSketch->isInitialized() ? theDumper << "[]" : theDumper << anAttrObjects;
+  theDumper << ", " << anAttrDirection;
+
+  std::string aCreationMethod = aBase->string(FeaturesPlugin_Extrusion::CREATION_METHOD())->value();
+
+  if(aCreationMethod == FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES()) {
+    AttributeDoublePtr anAttrToSize = aBase->real(FeaturesPlugin_Extrusion::TO_SIZE_ID());
+    AttributeDoublePtr anAttrFromSize = aBase->real(FeaturesPlugin_Extrusion::FROM_SIZE_ID());
+
+    theDumper << ", " << anAttrToSize << ", " << anAttrFromSize;
+  } else if(aCreationMethod == FeaturesPlugin_Extrusion::CREATION_METHOD_BY_PLANES()) {
+    AttributeSelectionPtr anAttrToObject = aBase->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID());
+    AttributeDoublePtr anAttrToOffset = aBase->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID());
+    AttributeSelectionPtr anAttrFromObject = aBase->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID());
+    AttributeDoublePtr anAttrFromOffset = aBase->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID());
+
+    theDumper << ", " << anAttrToObject << ", " << anAttrToOffset << ", " << anAttrFromObject << ", " << anAttrFromOffset;
+  }
+
+  AttributeSelectionListPtr anAttrBoolObjects = aBase->selectionList(FeaturesPlugin_CompositeBoolean::OBJECTS_ID());
+  theDumper << ", " << anAttrBoolObjects << ")" << std::endl;
+
+  if(anAttrSketch->isInitialized()) {
+    theDumper << aBase << ".setNestedSketch(" << anAttrSketch << ")" << std::endl;
+  }
 }
 
+//==================================================================================================
+void FeaturesAPI_ExtrusionBoolean::execIfBaseNotEmpty()
+{
+  if(mybaseObjects->size() > 0) {
+    execute();
+  }
+}
+
+
 //==================================================================================================
 FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAPI_Feature>& theFeature)
 : FeaturesAPI_ExtrusionBoolean(theFeature)
@@ -96,6 +163,7 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAP
 {
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theSize, mytoSize);
     fillAttribute(ModelHighAPI_Double(), myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -113,6 +181,7 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAP
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theSize, mytoSize);
     fillAttribute(ModelHighAPI_Double(), myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -129,6 +198,7 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAP
 {
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theToSize, mytoSize);
     fillAttribute(theFromSize, myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -147,6 +217,7 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAP
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theToSize, mytoSize);
     fillAttribute(theFromSize, myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -165,6 +236,7 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAP
 {
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_PLANES(), mycreationMethod);
     fillAttribute(theToObject, mytoObject);
     fillAttribute(theToOffset, mytoOffset);
     fillAttribute(theFromObject, myfromObject);
@@ -187,6 +259,7 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAP
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_PLANES(), mycreationMethod);
     fillAttribute(theToObject, mytoObject);
     fillAttribute(theToOffset, mytoOffset);
     fillAttribute(theFromObject, myfromObject);
@@ -301,6 +374,7 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(const std::shared_ptr<Model
 {
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theSize, mytoSize);
     fillAttribute(ModelHighAPI_Double(), myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -318,6 +392,7 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(const std::shared_ptr<Model
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theSize, mytoSize);
     fillAttribute(ModelHighAPI_Double(), myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -334,6 +409,7 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(const std::shared_ptr<Model
 {
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theToSize, mytoSize);
     fillAttribute(theFromSize, myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -352,6 +428,7 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(const std::shared_ptr<Model
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_SIZES(), mycreationMethod);
     fillAttribute(theToSize, mytoSize);
     fillAttribute(theFromSize, myfromSize);
     setBooleanObjects(theBooleanObjects);
@@ -370,6 +447,7 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(const std::shared_ptr<Model
 {
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_PLANES(), mycreationMethod);
     fillAttribute(theToObject, mytoObject);
     fillAttribute(theToOffset, mytoOffset);
     fillAttribute(theFromObject, myfromObject);
@@ -392,6 +470,7 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(const std::shared_ptr<Model
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_BY_PLANES(), mycreationMethod);
     fillAttribute(theToObject, mytoObject);
     fillAttribute(theToOffset, mytoOffset);
     fillAttribute(theFromObject, myfromObject);
index 390a955cbf4ddc7859f53fca37b5152c9f909e26..d5572cb4c6ee74739a82ee1871371b2325510973 100644 (file)
@@ -9,7 +9,6 @@
 
 #include "FeaturesAPI.h"
 
-#include <FeaturesPlugin_CompositeBoolean.h>
 #include <FeaturesPlugin_ExtrusionCut.h>
 #include <FeaturesPlugin_ExtrusionFuse.h>
 
@@ -17,6 +16,7 @@
 #include <ModelHighAPI_Macro.h>
 
 class ModelHighAPI_Double;
+class ModelHighAPI_Reference;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_ExtrusionBoolean
@@ -30,7 +30,7 @@ public:
   virtual ~FeaturesAPI_ExtrusionBoolean();
 
   INTERFACE_11("",
-               sketchLauncher, FeaturesPlugin_Extrusion::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */,
+               sketch, FeaturesPlugin_Extrusion::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */,
                baseObjects, FeaturesPlugin_Extrusion::BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Base objects */,
                direction, FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID(), ModelAPI_AttributeSelection, /** Direction */,
                creationMethod, FeaturesPlugin_Extrusion::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */,
@@ -42,6 +42,10 @@ public:
                fromOffset, FeaturesPlugin_Extrusion::FROM_OFFSET_ID(), ModelAPI_AttributeDouble, /** From offset */,
                booleanObjects, FeaturesPlugin_CompositeBoolean::OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Boolean objects */)
 
+  /// Modify base attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setNestedSketch(const ModelHighAPI_Reference& theSketch);
+
   /// Modify base attribute of the feature.
   FEATURESAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
@@ -69,19 +73,30 @@ public:
   FEATURESAPI_EXPORT
   void setBooleanObjects(const std::list<ModelHighAPI_Selection>& theBooleanObjects);
 
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
 protected:
   /// Constructor without values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionBoolean(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+private:
+  void execIfBaseNotEmpty();
 };
 
 class FeaturesAPI_ExtrusionCut: public FeaturesAPI_ExtrusionBoolean
 {
 public:
-  FEATURESAPI_EXPORT
-  virtual std::string getID() {
-    return FeaturesPlugin_ExtrusionCut::ID();
-  }
+
+  static std::string ID() { return FeaturesPlugin_ExtrusionCut::ID(); }
+  virtual std::string getID() { return ID(); }
+
+  //FEATURESAPI_EXPORT
+  //virtual std::string getID() {
+  //  return FeaturesPlugin_ExtrusionCut::ID();
+  //}
 
   /// Constructor without values.
   FEATURESAPI_EXPORT
@@ -206,10 +221,8 @@ ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePar
 class FeaturesAPI_ExtrusionFuse: public FeaturesAPI_ExtrusionBoolean
 {
 public:
-  FEATURESAPI_EXPORT
-  virtual std::string getID() {
-    return FeaturesPlugin_ExtrusionFuse::ID();
-  }
+  static std::string ID() { return FeaturesPlugin_ExtrusionFuse::ID(); }
+  virtual std::string getID() { return ID(); }
 
   /// Constructor without values.
   FEATURESAPI_EXPORT
index 274fe8e40e9e1d3cdcae2f3fb9f1000edd848d89..d12e73f45f47d5f6d98069585b168aa35e65faf4 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Group.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Integer.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
@@ -41,6 +42,17 @@ void FeaturesAPI_Group::setGroupList(const std::list<ModelHighAPI_Selection>& th
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Group::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrList = aBase->selectionList(FeaturesPlugin_Group::LIST_ID());
+
+  theDumper << aBase << " = model.addGroup(" << aDocName << ", " << anAttrList << ")" << std::endl;
+}
+
 //==================================================================================================
 GroupPtr addGroup(const std::shared_ptr<ModelAPI_Document>& thePart,
                   const std::list<ModelHighAPI_Selection>& theGroupList)
index 68239201bb5ee7089f01dc92cc1cf181cb6cb0a9..fece502f25f7320428279fd654780e709dcb9cc0 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Group
@@ -41,6 +42,10 @@ public:
   /// Set main objects.
   FEATURESAPI_EXPORT
   void setGroupList(const std::list<ModelHighAPI_Selection>& theGroupList);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Group object.
index ce33f83da978172674e9eff8172225db1796112b..8cd80eb47e5985b86fdb0f3c1461099d9a8d9d33 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Intersection.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -51,6 +52,19 @@ void FeaturesAPI_Intersection::setTools(const std::list<ModelHighAPI_Selection>&
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Intersection::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Intersection::OBJECT_LIST_ID());
+  AttributeSelectionListPtr anAttrTools = aBase->selectionList(FeaturesPlugin_Intersection::TOOL_LIST_ID());
+
+  theDumper << aBase << " = model.addIntersection(" << aDocName << ", "
+            << anAttrObjects << ", " << anAttrTools << ")" << std::endl;
+}
+
 //==================================================================================================
 IntersectionPtr addIntersection(const std::shared_ptr<ModelAPI_Document>& thePart,
                                 const std::list<ModelHighAPI_Selection>& theObjects,
index 440e43013115365897168255f97c9745e88561ea..78a6d51562b2264f8add3e632ba46ee46c8f2227 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Intersection
@@ -47,6 +48,10 @@ public:
   /// Modify tools attribute of the feature.
   FEATURESAPI_EXPORT
   void setTools(const std::list<ModelHighAPI_Selection>& theTools);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Intersection object.
index 2b4515fc2360dd1f8b0592941853c134e36fc2e0..3580a0997f0aa06f83a1d53ddf13b52be7a7c1ce 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Partition.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -39,6 +40,17 @@ void FeaturesAPI_Partition::setBase(const std::list<ModelHighAPI_Selection>& the
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Partition::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Partition::BASE_OBJECTS_ID());
+
+  theDumper << aBase << " = model.addPartition(" << aDocName << ", " << anAttrObjects << ")" << std::endl;
+}
+
 //==================================================================================================
 PartitionPtr addPartition(const std::shared_ptr<ModelAPI_Document>& thePart,
                           const std::list<ModelHighAPI_Selection>& theBaseObjects)
index c88047899585290f4507bd38b24df50dc0eb1506..cc7831d8f1b5923c4886c692d25aaec3626ba436 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Partition
@@ -41,6 +42,10 @@ public:
   /// Modify base attribute of the feature.
   FEATURESAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Partition object.
index 3ca9a4e54e78263ea85fd030522843c8feeee35e..f99cccef2a3d2630b9e76c3b89649855420a33c8 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Pipe.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -110,6 +111,35 @@ void FeaturesAPI_Pipe::setByBasePathLocations(const std::list<ModelHighAPI_Selec
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Pipe::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Pipe::BASE_OBJECTS_ID());
+  AttributeSelectionPtr anAttrPath = aBase->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID());
+
+  theDumper << aBase << " = model.addPipe(" << aDocName << ", "
+            << anAttrObjects << ", " << anAttrPath;
+
+  std::string aCreationMethod = aBase->string(FeaturesPlugin_Pipe::CREATION_METHOD())->value();
+
+  if(aCreationMethod == FeaturesPlugin_Pipe::CREATION_METHOD_SIMPLE()) {
+    // Do nothing;
+  } else if(aCreationMethod == FeaturesPlugin_Pipe::CREATION_METHOD_BINORMAL()) {
+    AttributeSelectionPtr anAttrBiNormal = aBase->selection(FeaturesPlugin_Pipe::BINORMAL_ID());
+
+    theDumper << ", " << anAttrBiNormal;
+  } else if(aCreationMethod == FeaturesPlugin_Pipe::CREATION_METHOD_LOCATIONS()) {
+    AttributeSelectionListPtr anAttrLocations = aBase->selectionList(FeaturesPlugin_Pipe::LOCATIONS_ID());
+
+    theDumper << ", " << anAttrLocations;
+  }
+
+  theDumper << ")" << std::endl;
+}
+
 //==================================================================================================
 PipePtr addPipe(const std::shared_ptr<ModelAPI_Document>& thePart,
                 const std::list<ModelHighAPI_Selection>& theBaseObjects,
index 1a3ee09a03810a5debbaee02b7634e1f7b978876..e45fd369f585c0acee352217d36884feffc1e5ad 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Pipe
@@ -81,6 +82,10 @@ public:
   void setByBasePathLocations(const std::list<ModelHighAPI_Selection>& theBaseObjects,
                               const ModelHighAPI_Selection& thePath,
                               const std::list<ModelHighAPI_Selection>& theLocations);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Pipe object.
index f45264e14dc22ecf832f6dad7a6bc8bec9297926..5d3aff8b494772236e606a977c33f50076148300 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Placement.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -79,6 +80,23 @@ void FeaturesAPI_Placement::setCentering(const bool theCentering)
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Placement::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Placement::OBJECTS_LIST_ID());
+  AttributeSelectionPtr anAttrStartShape = aBase->selection(FeaturesPlugin_Placement::START_SHAPE_ID());
+  AttributeSelectionPtr anAttrEndShape = aBase->selection(FeaturesPlugin_Placement::END_SHAPE_ID());
+  AttributeBooleanPtr anAttrReverse = aBase->boolean(FeaturesPlugin_Placement::REVERSE_ID());
+  AttributeBooleanPtr anAttrCentering = aBase->boolean(FeaturesPlugin_Placement::CENTERING_ID());
+
+  theDumper << aBase << " = model.addPlacement(" << aDocName << ", "
+            << anAttrObjects << ", " << anAttrStartShape << ", " << anAttrEndShape << ", "
+            << anAttrReverse << ", " << anAttrCentering << ")" << std::endl;
+}
+
 //==================================================================================================
 PlacementPtr addPlacement(const std::shared_ptr<ModelAPI_Document>& thePart,
                           const std::list<ModelHighAPI_Selection>& theObjects,
index 14378f06870e61577352f23e5e4bdc07f9d4fa34..2b157611f2893da24dc7b8dbd6b3e187dab23695 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Placement
@@ -65,6 +66,10 @@ public:
   /// Set centering flag.
   FEATURESAPI_EXPORT
   void setCentering(const bool theCentering);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Placement object.
index 4fdf104f7561adc1664f8b51eedf5025c65d4922..efc80327bd5a25daba989a2bed38fbb88546f77d 100644 (file)
@@ -6,15 +6,18 @@
 
 #include "FeaturesAPI_Recover.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Reference.h>
 #include <ModelHighAPI_Tools.h>
 
+//=================================================================================================
 FeaturesAPI_Recover::FeaturesAPI_Recover(const std::shared_ptr<ModelAPI_Feature>& theFeature)
 : ModelHighAPI_Interface(theFeature)
 {
   initialize();
 }
 
+//=================================================================================================
 FeaturesAPI_Recover::FeaturesAPI_Recover(const std::shared_ptr<ModelAPI_Feature>& theFeature,
   const ModelHighAPI_Reference& theBaseFeature,
   const std::list<ModelHighAPI_Selection>& theRecoveredList, const bool thePersistent)
@@ -27,27 +30,49 @@ FeaturesAPI_Recover::FeaturesAPI_Recover(const std::shared_ptr<ModelAPI_Feature>
   }
 }
 
+//=================================================================================================
 FeaturesAPI_Recover::~FeaturesAPI_Recover()
 {}
 
+//=================================================================================================
 void FeaturesAPI_Recover::setBaseFeature(const ModelHighAPI_Reference& theBaseFeature)
 {
   fillAttribute(theBaseFeature, mybaseFeature);
   // do not need to execute because on attribute changed it does everything anyway
 }
 
+//=================================================================================================
 void FeaturesAPI_Recover::setRecoveredList(const std::list<ModelHighAPI_Selection>& theRecoverList)
 {
   fillAttribute(theRecoverList, myrecoveredList);
   // do not need to execute because on attribute changed it does everything anyway
 }
 
+//=================================================================================================
 void FeaturesAPI_Recover::setIsPersistent(bool thePersistent)
 {
   fillAttribute(thePersistent, myisPersistent);
   // do not need to execute because on attribute changed it does everything anyway
 }
 
+//==================================================================================================
+void FeaturesAPI_Recover::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeReferencePtr anAttrBaseFeature = aBase->reference(FeaturesPlugin_Recover::BASE_FEATURE());
+  AttributeRefListPtr anAttrRecoveredEntities = aBase->reflist(FeaturesPlugin_Recover::RECOVERED_ENTITIES());
+  AttributeBooleanPtr anAttrPersistent = aBase->boolean(FeaturesPlugin_Recover::PERSISTENT());
+
+  FeaturePtr aFeature = ModelAPI_Feature::feature(anAttrBaseFeature->value());
+
+  theDumper << aBase << " = model.addRecover(" << aDocName << ", "
+            << aFeature << ", " << anAttrRecoveredEntities << ", "
+            << anAttrPersistent << ")" << std::endl;
+}
+
+//=================================================================================================
 RecoverPtr addRecover(const std::shared_ptr<ModelAPI_Document>& thePart,
   const ModelHighAPI_Reference& theBaseFeature,
   const std::list<ModelHighAPI_Selection>& theRecoveredList, const bool thePersistent)
index 28c8e180488c4135d90b185bc6afb7691a03a022..e7f57d4262cae2747e5555218ecae4a95185a382 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Reference;
 
 /// \class FeaturesAPI_Recover
@@ -54,6 +55,9 @@ public:
   FEATURESAPI_EXPORT
   void setIsPersistent(bool thePersistent);
 
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Recover object.
index 4d0726effad4865eb9d5b1e15d591cfc3e7241e3..b5dd098c9be008baecb2bddc73c25b53e700a9ed 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_RemoveSubShapes.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -49,6 +50,19 @@ void FeaturesAPI_RemoveSubShapes::setSubShapesToKeep(const std::list<ModelHighAP
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_RemoveSubShapes::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  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;
+}
+
 //==================================================================================================
 RemoveSubShapesPtr addRemoveSubShapes(const std::shared_ptr<ModelAPI_Document>& thePart,
                                       const ModelHighAPI_Selection& theBase)
index d4de1dcc27d60e0585f834dcb58555d66874d4c0..b6e4d587e51b388db813042e72a807ddc09282c7 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_RemoveSubShapes
@@ -46,6 +47,10 @@ public:
   /// Modify tools attribute of the feature.
   FEATURESAPI_EXPORT
   void setSubShapesToKeep(const std::list<ModelHighAPI_Selection>& theSubShapes);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on RemoveSubShapes object.
index fc982e9c1e00431c407fab17dc869489ae7f62b8..6c09db9f22251506fb1162c51f481479d92639f1 100644 (file)
@@ -7,6 +7,8 @@
 #include "FeaturesAPI_Revolution.h"
 
 #include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Reference.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -68,12 +70,24 @@ FeaturesAPI_Revolution::~FeaturesAPI_Revolution()
 
 }
 
+//==================================================================================================
+void FeaturesAPI_Revolution::setNestedSketch(const ModelHighAPI_Reference& theSketch)
+{
+  mysketch->setValue(theSketch.feature());
+  mybaseObjects->clear();
+  mybaseObjects->append(theSketch.feature()->firstResult(), GeomShapePtr());
+
+  execIfBaseNotEmpty();
+}
+
 //==================================================================================================
 void FeaturesAPI_Revolution::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
 {
+  mysketch->setValue(ObjectPtr());
+  mybaseObjects->clear();
   fillAttribute(theBaseObjects, mybaseObjects);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -81,7 +95,7 @@ void FeaturesAPI_Revolution::setAxis(const ModelHighAPI_Selection& theAxis)
 {
   fillAttribute(theAxis, myaxis);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -92,7 +106,7 @@ void FeaturesAPI_Revolution::setAngles(const ModelHighAPI_Double& theToAngle,
   fillAttribute(theToAngle, mytoAngle);
   fillAttribute(theFromAngle, myfromAngle);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -102,7 +116,7 @@ void FeaturesAPI_Revolution::setAngle(const ModelHighAPI_Double& theAngle)
   fillAttribute(theAngle, mytoAngle);
   fillAttribute(ModelHighAPI_Double(), myfromAngle);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -117,7 +131,52 @@ void FeaturesAPI_Revolution::setPlanesAndOffsets(const ModelHighAPI_Selection& t
   fillAttribute(theFromObject, myfromObject);
   fillAttribute(theFromOffset, myfromOffset);
 
-  execute();
+  execIfBaseNotEmpty();
+}
+
+//==================================================================================================
+void FeaturesAPI_Revolution::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeReferencePtr anAttrSketch = aBase->reference(FeaturesPlugin_Revolution::SKETCH_ID());
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Revolution::BASE_OBJECTS_ID());
+  AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Revolution::AXIS_OBJECT_ID());
+
+  theDumper << aBase << " = model.addRevolution(" << aDocName << ", ";
+  anAttrSketch->isInitialized() ? theDumper << "[]" : theDumper << anAttrObjects;
+  theDumper << ", " << anAttrAxis;
+
+  std::string aCreationMethod = aBase->string(FeaturesPlugin_Revolution::CREATION_METHOD())->value();
+
+  if(aCreationMethod == FeaturesPlugin_Revolution::CREATION_METHOD_BY_ANGLES()) {
+    AttributeDoublePtr anAttrToAngle = aBase->real(FeaturesPlugin_Revolution::TO_ANGLE_ID());
+    AttributeDoublePtr anAttrFromAngle = aBase->real(FeaturesPlugin_Revolution::FROM_ANGLE_ID());
+
+    theDumper << ", " << anAttrToAngle << ", " << anAttrFromAngle;
+  } else if(aCreationMethod == FeaturesPlugin_Revolution::CREATION_METHOD_BY_PLANES()) {
+    AttributeSelectionPtr anAttrToObject = aBase->selection(FeaturesPlugin_Revolution::TO_OBJECT_ID());
+    AttributeDoublePtr anAttrToOffset = aBase->real(FeaturesPlugin_Revolution::TO_OFFSET_ID());
+    AttributeSelectionPtr anAttrFromObject = aBase->selection(FeaturesPlugin_Revolution::FROM_OBJECT_ID());
+    AttributeDoublePtr anAttrFromOffset = aBase->real(FeaturesPlugin_Revolution::FROM_OFFSET_ID());
+
+    theDumper << ", " << anAttrToObject << ", " << anAttrToOffset << ", " << anAttrFromObject << ", " << anAttrFromOffset;
+  }
+
+  theDumper << ")" << std::endl;
+
+  if(anAttrSketch->isInitialized()) {
+    theDumper << aBase << ".setNestedSketch(" << anAttrSketch << ")" << std::endl;
+  }
+}
+
+//==================================================================================================
+void FeaturesAPI_Revolution::execIfBaseNotEmpty()
+{
+  if(mybaseObjects->size() > 0) {
+    execute();
+  }
 }
 
 //==================================================================================================
index a8e4bc6dd80eb36cef3c55cba3335dd40b6611ac..e011ee403684e601be1f00cc152eccbd668edac9 100644 (file)
@@ -15,6 +15,7 @@
 #include <ModelHighAPI_Macro.h>
 
 class ModelHighAPI_Double;
+class ModelHighAPI_Reference;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Revolution
@@ -57,6 +58,7 @@ public:
   virtual ~FeaturesAPI_Revolution();
 
   INTERFACE_10(FeaturesPlugin_Revolution::ID(),
+               sketch, FeaturesPlugin_Revolution::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */,
                baseObjects, FeaturesPlugin_Revolution::BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Base objects */,
                axis, FeaturesPlugin_Revolution::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection, /** Axis */,
                creationMethod, FeaturesPlugin_Revolution::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */,
@@ -65,8 +67,11 @@ public:
                toObject, FeaturesPlugin_Revolution::TO_OBJECT_ID(), ModelAPI_AttributeSelection, /** To object */,
                toOffset, FeaturesPlugin_Revolution::TO_OFFSET_ID(), ModelAPI_AttributeDouble, /** To offset */,
                fromObject, FeaturesPlugin_Revolution::FROM_OBJECT_ID(), ModelAPI_AttributeSelection, /** From object */,
-               fromOffset, FeaturesPlugin_Revolution::FROM_OFFSET_ID(), ModelAPI_AttributeDouble, /** From offset */,
-               sketchLauncher, FeaturesPlugin_Revolution::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */)
+               fromOffset, FeaturesPlugin_Revolution::FROM_OFFSET_ID(), ModelAPI_AttributeDouble, /** From offset */)
+
+  /// Modify base attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setNestedSketch(const ModelHighAPI_Reference& theSketch);
 
   /// Modify base attribute of the feature.
   FEATURESAPI_EXPORT
@@ -90,6 +95,13 @@ public:
                            const ModelHighAPI_Double& theToOffset,
                            const ModelHighAPI_Selection& theFromObject,
                            const ModelHighAPI_Double& theFromOffset);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+  void execIfBaseNotEmpty();
 };
 
 /// Pointer on Revolution object.
index 3ca6f2b7d55612da19c0cbd3bfe6816cd2c3e730..097fbfbdb5accf241bebb7141061c74fe77c42dd 100644 (file)
@@ -7,6 +7,8 @@
 #include "FeaturesAPI_RevolutionBoolean.h"
 
 #include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Reference.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -20,12 +22,24 @@ FeaturesAPI_RevolutionBoolean::~FeaturesAPI_RevolutionBoolean()
 {
 }
 
+//==================================================================================================
+void FeaturesAPI_RevolutionBoolean::setNestedSketch(const ModelHighAPI_Reference& theSketch)
+{
+  mysketch->setValue(theSketch.feature());
+  mybaseObjects->clear();
+  mybaseObjects->append(theSketch.feature()->firstResult(), GeomShapePtr());
+
+  execIfBaseNotEmpty();
+}
+
 //==================================================================================================
 void FeaturesAPI_RevolutionBoolean::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
 {
+  mysketch->setValue(ObjectPtr());
+  mybaseObjects->clear();
   fillAttribute(theBaseObjects, mybaseObjects);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -33,7 +47,7 @@ void FeaturesAPI_RevolutionBoolean::setAxis(const ModelHighAPI_Selection& theAxi
 {
   fillAttribute(theAxis, myaxis);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -44,7 +58,7 @@ void FeaturesAPI_RevolutionBoolean::setAngles(const ModelHighAPI_Double& theToAn
   fillAttribute(theToAngle, mytoAngle);
   fillAttribute(theFromAngle, myfromAngle);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -54,7 +68,7 @@ void FeaturesAPI_RevolutionBoolean::setAngle(const ModelHighAPI_Double& theAngle
   fillAttribute(theAngle, mytoAngle);
   fillAttribute(ModelHighAPI_Double(), myfromAngle);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -69,7 +83,7 @@ void FeaturesAPI_RevolutionBoolean::setPlanesAndOffsets(const ModelHighAPI_Selec
   fillAttribute(theFromObject, myfromObject);
   fillAttribute(theFromOffset, myfromOffset);
 
-  execute();
+  execIfBaseNotEmpty();
 }
 
 //==================================================================================================
@@ -77,7 +91,59 @@ void FeaturesAPI_RevolutionBoolean::setBooleanObjects(const std::list<ModelHighA
 {
   fillAttribute(theBooleanObjects, mybooleanObjects);
 
-  execute();
+  execIfBaseNotEmpty();
+}
+
+//==================================================================================================
+void FeaturesAPI_RevolutionBoolean::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeReferencePtr anAttrSketch = aBase->reference(FeaturesPlugin_Revolution::SKETCH_ID());
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Revolution::BASE_OBJECTS_ID());
+  AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Revolution::AXIS_OBJECT_ID());
+
+  theDumper << aBase << " = model.addRevolution";
+  if(aBase->getKind() == FeaturesPlugin_RevolutionCut::ID()) {
+    theDumper << "Cut";
+  } else if(aBase->getKind() == FeaturesPlugin_RevolutionFuse::ID()) {
+    theDumper << "Fuse";
+  }
+  theDumper << "(" << aDocName << ", ";
+  anAttrSketch->isInitialized() ? theDumper << "[]" : theDumper << anAttrObjects;
+  theDumper << ", " << anAttrAxis;
+
+  std::string aCreationMethod = aBase->string(FeaturesPlugin_Revolution::CREATION_METHOD())->value();
+
+  if(aCreationMethod == FeaturesPlugin_Revolution::CREATION_METHOD_BY_ANGLES()) {
+    AttributeDoublePtr anAttrToAngle = aBase->real(FeaturesPlugin_Revolution::TO_ANGLE_ID());
+    AttributeDoublePtr anAttrFromAngle = aBase->real(FeaturesPlugin_Revolution::FROM_ANGLE_ID());
+
+    theDumper << ", " << anAttrToAngle << ", " << anAttrFromAngle;
+  } else if(aCreationMethod == FeaturesPlugin_Revolution::CREATION_METHOD_BY_PLANES()) {
+    AttributeSelectionPtr anAttrToObject = aBase->selection(FeaturesPlugin_Revolution::TO_OBJECT_ID());
+    AttributeDoublePtr anAttrToOffset = aBase->real(FeaturesPlugin_Revolution::TO_OFFSET_ID());
+    AttributeSelectionPtr anAttrFromObject = aBase->selection(FeaturesPlugin_Revolution::FROM_OBJECT_ID());
+    AttributeDoublePtr anAttrFromOffset = aBase->real(FeaturesPlugin_Revolution::FROM_OFFSET_ID());
+
+    theDumper << ", " << anAttrToObject << ", " << anAttrToOffset << ", " << anAttrFromObject << ", " << anAttrFromOffset;
+  }
+
+  AttributeSelectionListPtr anAttrBoolObjects = aBase->selectionList(FeaturesPlugin_CompositeBoolean::OBJECTS_ID());
+  theDumper << ", " << anAttrBoolObjects << ")" << std::endl;
+
+  if(anAttrSketch->isInitialized()) {
+    theDumper << aBase << ".setNestedSketch(" << anAttrSketch << ")" << std::endl;
+  }
+}
+
+//==================================================================================================
+void FeaturesAPI_RevolutionBoolean::execIfBaseNotEmpty()
+{
+  if(mybaseObjects->size() > 0) {
+    execute();
+  }
 }
 
 //==================================================================================================
@@ -98,6 +164,7 @@ FeaturesAPI_RevolutionCut::FeaturesAPI_RevolutionCut(const std::shared_ptr<Model
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theAxis, myaxis);
+    fillAttribute(FeaturesPlugin_Revolution::CREATION_METHOD_BY_ANGLES(), mycreationMethod);
     fillAttribute(theSize, mytoAngle);
     fillAttribute(ModelHighAPI_Double(), myfromAngle);
     setBooleanObjects(theBooleanObjects);
@@ -116,6 +183,7 @@ FeaturesAPI_RevolutionCut::FeaturesAPI_RevolutionCut(const std::shared_ptr<Model
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theAxis, myaxis);
+    fillAttribute(FeaturesPlugin_Revolution::CREATION_METHOD_BY_ANGLES(), mycreationMethod);
     fillAttribute(theToAngle, mytoAngle);
     fillAttribute(theFromAngle, myfromAngle);
     setBooleanObjects(theBooleanObjects);
@@ -136,6 +204,7 @@ FeaturesAPI_RevolutionCut::FeaturesAPI_RevolutionCut(const std::shared_ptr<Model
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theAxis, myaxis);
+    fillAttribute(FeaturesPlugin_Revolution::CREATION_METHOD_BY_PLANES(), mycreationMethod);
     fillAttribute(theToObject, mytoObject);
     fillAttribute(theToOffset, mytoOffset);
     fillAttribute(theFromObject, myfromObject);
@@ -212,6 +281,7 @@ FeaturesAPI_RevolutionFuse::FeaturesAPI_RevolutionFuse(const std::shared_ptr<Mod
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theAxis, myaxis);
+    fillAttribute(FeaturesPlugin_Revolution::CREATION_METHOD_BY_ANGLES(), mycreationMethod);
     fillAttribute(theSize, mytoAngle);
     fillAttribute(ModelHighAPI_Double(), myfromAngle);
     setBooleanObjects(theBooleanObjects);
@@ -230,6 +300,7 @@ FeaturesAPI_RevolutionFuse::FeaturesAPI_RevolutionFuse(const std::shared_ptr<Mod
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theAxis, myaxis);
+    fillAttribute(FeaturesPlugin_Revolution::CREATION_METHOD_BY_ANGLES(), mycreationMethod);
     fillAttribute(theToAngle, mytoAngle);
     fillAttribute(theFromAngle, myfromAngle);
     setBooleanObjects(theBooleanObjects);
@@ -250,6 +321,7 @@ FeaturesAPI_RevolutionFuse::FeaturesAPI_RevolutionFuse(const std::shared_ptr<Mod
   if(initialize()) {
     fillAttribute(theBaseObjects, mybaseObjects);
     fillAttribute(theAxis, myaxis);
+    fillAttribute(FeaturesPlugin_Revolution::CREATION_METHOD_BY_PLANES(), mycreationMethod);
     fillAttribute(theToObject, mytoObject);
     fillAttribute(theToOffset, mytoOffset);
     fillAttribute(theFromObject, myfromObject);
index 679eb58317eddf25f7ce06a3ccf6d9784ff0ec33..bc5942242d9bb78ee22e54bf69cf63e1291edcf1 100644 (file)
@@ -17,6 +17,8 @@
 #include <ModelHighAPI_Macro.h>
 
 class ModelHighAPI_Double;
+class ModelHighAPI_Dumper;
+class ModelHighAPI_Reference;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_RevolutionBoolean
@@ -30,7 +32,7 @@ public:
   virtual ~FeaturesAPI_RevolutionBoolean();
 
   INTERFACE_11("",
-               sketchLauncher, FeaturesPlugin_Revolution::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */,
+               sketch, FeaturesPlugin_Revolution::SKETCH_ID(), ModelAPI_AttributeReference, /** Sketch launcher */,
                baseObjects, FeaturesPlugin_Revolution::BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Base objects */,
                axis, FeaturesPlugin_Revolution::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection, /** Axis */,
                creationMethod, FeaturesPlugin_Revolution::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */,
@@ -42,6 +44,10 @@ public:
                fromOffset, FeaturesPlugin_Revolution::FROM_OFFSET_ID(), ModelAPI_AttributeDouble, /** From offset */,
                booleanObjects, FeaturesPlugin_CompositeBoolean::OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Boolean objects */)
 
+  /// Modify base attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setNestedSketch(const ModelHighAPI_Reference& theSketch);
+
   /// Modify base attribute of the feature.
   FEATURESAPI_EXPORT
   void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
@@ -69,19 +75,25 @@ public:
   FEATURESAPI_EXPORT
   void setBooleanObjects(const std::list<ModelHighAPI_Selection>& theBooleanObjects);
 
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
 protected:
   /// Constructor without values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_RevolutionBoolean(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+private:
+  void execIfBaseNotEmpty();
 };
 
 class FeaturesAPI_RevolutionCut: public FeaturesAPI_RevolutionBoolean
 {
 public:
-  FEATURESAPI_EXPORT
-  virtual std::string getID() {
-    return FeaturesPlugin_RevolutionCut::ID();
-  }
+
+  static std::string ID() { return FeaturesPlugin_RevolutionCut::ID(); }
+  virtual std::string getID() { return ID(); }
 
   /// Constructor without values.
   FEATURESAPI_EXPORT
@@ -153,10 +165,9 @@ RevolutionCutPtr addRevolutionCut(const std::shared_ptr<ModelAPI_Document>& theP
 class FeaturesAPI_RevolutionFuse: public FeaturesAPI_RevolutionBoolean
 {
 public:
-  FEATURESAPI_EXPORT
-  virtual std::string getID() {
-    return FeaturesPlugin_RevolutionFuse::ID();
-  }
+
+  static std::string ID() { return FeaturesPlugin_RevolutionFuse::ID(); }
+  virtual std::string getID() { return ID(); }
 
   /// Constructor without values.
   FEATURESAPI_EXPORT
index 861f3da0006cb8be4b1f650ff9ffc374cd94de03..d24aa08900bdbda186b0807af194860cc38ac604 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Rotation.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -59,12 +60,26 @@ void FeaturesAPI_Rotation::setAngle(const ModelHighAPI_Double& theAngle)
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Rotation::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID());
+  AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Rotation::AXIS_OBJECT_ID());
+  AttributeDoublePtr anAttrAngle = aBase->real(FeaturesPlugin_Rotation::ANGLE_ID());
+
+  theDumper << aBase << " = model.addRotation(" << aDocName << ", "
+            << anAttrObjects << ", " << anAttrAxis << ", " << anAttrAngle << ")" << std::endl;
+}
+
 //==================================================================================================
 RotationPtr addRotation(const std::shared_ptr<ModelAPI_Document>& thePart,
                         const std::list<ModelHighAPI_Selection>& theMainObjects,
                         const ModelHighAPI_Selection& theAxisObject,
-                        const ModelHighAPI_Double& theDistance)
+                        const ModelHighAPI_Double& theAngle)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Rotation::ID());
-  return RotationPtr(new FeaturesAPI_Rotation(aFeature, theMainObjects, theAxisObject, theDistance));
+  return RotationPtr(new FeaturesAPI_Rotation(aFeature, theMainObjects, theAxisObject, theAngle));
 }
index c8e74ace884c6ae0a75825d6816bdf1e34133a1b..03fd636ad780685298603699e60404eeae564405 100644 (file)
@@ -15,6 +15,7 @@
 #include <ModelHighAPI_Macro.h>
 
 class ModelHighAPI_Double;
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Rotation
@@ -54,6 +55,10 @@ public:
   /// Set angle.
   FEATURESAPI_EXPORT
   void setAngle(const ModelHighAPI_Double& theAngle);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Rotation object.
@@ -65,6 +70,6 @@ FEATURESAPI_EXPORT
 RotationPtr addRotation(const std::shared_ptr<ModelAPI_Document>& thePart,
                         const std::list<ModelHighAPI_Selection>& theMainObjects,
                         const ModelHighAPI_Selection& theAxisObject,
-                        const ModelHighAPI_Double& theDistance);
+                        const ModelHighAPI_Double& theAngle);
 
 #endif // FeaturesAPI_Rotation_H_
index 46a977c964551e26e030b8fd0ba64b2e0b4e54ab..e70df5b8c24c0846ea519b6702a85201ba415e2e 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "FeaturesAPI_Translation.h"
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 
 //==================================================================================================
@@ -59,6 +60,20 @@ void FeaturesAPI_Translation::setDistance(const ModelHighAPI_Double& theDistance
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Translation::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
+  AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Translation::AXIS_OBJECT_ID());
+  AttributeDoublePtr anAttrDistance = aBase->real(FeaturesPlugin_Translation::DISTANCE_ID());
+
+  theDumper << aBase << " = model.addTranslation(" << aDocName << ", "
+            << anAttrObjects << ", " << anAttrAxis << ", " << anAttrDistance << ")" << std::endl;
+}
+
 //==================================================================================================
 TranslationPtr addTranslation(const std::shared_ptr<ModelAPI_Document>& thePart,
                               const std::list<ModelHighAPI_Selection>& theMainObjects,
index 0304f28199361697f03490fd754de376777f723f..995b880a83af0b79aeb8d1bf3b921817c0c8cc29 100644 (file)
@@ -15,6 +15,7 @@
 #include <ModelHighAPI_Macro.h>
 
 class ModelHighAPI_Double;
+class ModelHighAPI_Dumper;
 class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Translation
@@ -54,6 +55,10 @@ public:
   /// Set distance.
   FEATURESAPI_EXPORT
   void setDistance(const ModelHighAPI_Double& theDistance);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Translation object.
diff --git a/src/FeaturesAPI/FeaturesAPI_Union.cpp b/src/FeaturesAPI/FeaturesAPI_Union.cpp
new file mode 100644 (file)
index 0000000..a3580a3
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesAPI_Union.cpp
+// Created:     09 June 2016
+// Author:      Dmitry Bobylev
+
+#include "FeaturesAPI_Union.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+FeaturesAPI_Union::FeaturesAPI_Union(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+//==================================================================================================
+FeaturesAPI_Union::FeaturesAPI_Union(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const std::list<ModelHighAPI_Selection>& theBaseObjects)
+: ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    setBase(theBaseObjects);
+  }
+}
+
+//==================================================================================================
+FeaturesAPI_Union::~FeaturesAPI_Union()
+{
+
+}
+
+//==================================================================================================
+void FeaturesAPI_Union::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+  fillAttribute(theBaseObjects, mybaseObjects);
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Union::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
+
+  theDumper << aBase << " = model.addUnion(" << aDocName << ", " << anAttrObjects << ")" << std::endl;
+}
+
+//==================================================================================================
+UnionPtr addUnion(const std::shared_ptr<ModelAPI_Document>& thePart,
+                  const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Union::ID());
+  return UnionPtr(new FeaturesAPI_Union(aFeature, theBaseObjects));
+}
diff --git a/src/FeaturesAPI/FeaturesAPI_Union.h b/src/FeaturesAPI/FeaturesAPI_Union.h
new file mode 100644 (file)
index 0000000..e07a9b1
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesAPI_Union.h
+// Created:     09 June 2016
+// Author:      Dmitry Bobylev
+
+#ifndef FeaturesAPI_Union_H_
+#define FeaturesAPI_Union_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_Union.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Dumper;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_Union
+/// \ingroup CPPHighAPI
+/// \brief Interface for Union feature.
+class FeaturesAPI_Union: public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Union(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Union(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Destructor.
+  FEATURESAPI_EXPORT
+  virtual ~FeaturesAPI_Union();
+
+  INTERFACE_1(FeaturesPlugin_Union::ID(),
+              baseObjects, FeaturesPlugin_Union::BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList, /** Base objects */)
+
+  /// Modify base attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Union object.
+typedef std::shared_ptr<FeaturesAPI_Union> UnionPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Union feature.
+FEATURESAPI_EXPORT
+UnionPtr addUnion(const std::shared_ptr<ModelAPI_Document>& thePart,
+                  const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+#endif // FeaturesAPI_Union_H_
index f8da2bcfafc44d752b452ac95d54bc04efccc205..8fff1a42b580a2d93da1a5053a3182f02861aa75 100644 (file)
@@ -24,5 +24,6 @@
   #include "FeaturesAPI_RevolutionBoolean.h"
   #include "FeaturesAPI_Rotation.h"
   #include "FeaturesAPI_Translation.h"
+  #include "FeaturesAPI_Union.h"
 
 #endif // FeaturesAPI_swig_H_
index 69915b1b38674876b643180cd03e19801d224e8b..075bd5f7b0498a51cb4d09cdc3ee42cf6252cb86 100644 (file)
@@ -39,13 +39,9 @@ void FeaturesPlugin_Boolean::initAttributes()
   AttributeSelectionListPtr aSelection = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // extrusion works with faces always
-  aSelection->setSelectionType("SOLID");
 
   aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // extrusion works with faces always
-  aSelection->setSelectionType("SOLID");
 
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
index 43b25be205b2270e3e0eec2bb0c5ce5d840f75c8..496abeb0a42122e4f4b061d26e31fcc28d6907a5 100644 (file)
@@ -34,8 +34,6 @@ void FeaturesPlugin_Placement::initAttributes()
   AttributeSelectionListPtr aSelection = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // extrusion works with faces always
-  aSelection->setSelectionType("SOLID");
 
   data()->addAttribute(START_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(END_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
index 3d3076ab5d085516c6cce484a267717f3b2c636f..91ab7c7b09b2335bdd68758f099b1549bcda1f3e 100755 (executable)
@@ -25,8 +25,6 @@ void FeaturesPlugin_Rotation::initAttributes()
   AttributeSelectionListPtr aSelection = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Rotation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // revolution works with faces always
-  aSelection->setSelectionType("SOLID");
 
   data()->addAttribute(FeaturesPlugin_Rotation::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(FeaturesPlugin_Rotation::ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
index c3931387cf2de04422574dc778d6052237958fc7..e335277846986784435cb6a3cde322cc9736273e 100644 (file)
@@ -27,8 +27,6 @@ void FeaturesPlugin_Translation::initAttributes()
   AttributeSelectionListPtr aSelection = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Translation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // revolution works with faces always
-  aSelection->setSelectionType("SOLID");
 
   data()->addAttribute(FeaturesPlugin_Translation::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(FeaturesPlugin_Translation::DISTANCE_ID(), ModelAPI_AttributeDouble::typeId());
index c83eb2f2b54816da15651c3ada20dfab72c5d604..c1b686df978e6efda244a5fd791cf81081ff47a6 100644 (file)
@@ -118,3 +118,6 @@ assert (aBooleanResult is not None)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index ed2a6051456413a4072cf233258a0d01a1b2671b..8d997e60ecb747a8516bf6445d8e63da72d433b4 100644 (file)
@@ -128,3 +128,6 @@ assert (aBooleanResult is not None)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 26caead92fe1b5237149b15733c51da1a6470ffc..524286a3511b6501124cf5dc40cccb6c73dc3f8e 100644 (file)
@@ -43,3 +43,5 @@ aSession.startOperation()
 aBoolean = model.addFill(aDocument, [anExtrusion.result()[0]], [anExtrusion.result()[1]])
 assert (len(aBoolean.result()) > 0)
 aSession.finishOperation()
+
+assert(model.checkPythonDump())
index 8591f52d0ce1ea731a7f87233e9f2230f29cf6fd..2190346cffbae2dedde442cbb757f9a8638a902f 100644 (file)
@@ -102,3 +102,6 @@ assert (aBooleanResult is not None)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 1f9f97c49b62d8f7c2292fc359be9ee1c8435c75..0e556e5fa0428faef7b0613fa4bd1b616003fd86 100644 (file)
@@ -224,3 +224,6 @@ assert (aFactory.validate(anRevolutionFuseFt))
 assert (len(anRevolutionFuseFt.results()) > 0)
 aCurrentResult = modelAPI_ResultBody(anRevolutionFuseFt.firstResult())
 assert (aCurrentResult is not None)
+
+import model
+assert(model.checkPythonDump())
index 9a5c6d784e084f088b198fd9716c410631fba886..ea08653101f30fea67d00aea923fa2fa2bd51b52 100644 (file)
@@ -245,3 +245,6 @@ assert (anExtrusionResult is not None)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index e880babc7ae0175483d4715cdde64d6658fc44ef..72a536f984dd4b3c654302f698ce960a437d0325 100644 (file)
@@ -117,3 +117,6 @@ assert (aFactory.validate(anExtrusionCutFt))
 assert (len(anExtrusionCutFt.results()) > 0)
 aCurrentResult = modelAPI_ResultBody(anExtrusionCutFt.firstResult())
 assert (aCurrentResult is not None)
+
+import model
+assert(model.checkPythonDump())
index 5832c3baa7881838e224a7da6512d333703ac009..e57883994301b8bd3aea5339aa5de54784346dbc 100644 (file)
@@ -117,3 +117,6 @@ assert (aFactory.validate(anExtrusionFuseFt))
 assert (len(anExtrusionFuseFt.results()) > 0)
 aCurrentResult = modelAPI_ResultBody(anExtrusionFuseFt.firstResult())
 assert (aCurrentResult is not None)
+
+import model
+assert(model.checkPythonDump())
index a2ca95ef1fe76a702c61531c304c3f75a00a2368..139d41208c84a86e524ce2b3f75bcb0108356343 100644 (file)
@@ -242,3 +242,6 @@ assert(aGroupResult.shape())
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 04490b0f7252b19d5e0a9f1a3c0a58881deac7f8..2915cff8671449c280dc9e2de5216386a0b561e6 100644 (file)
@@ -146,3 +146,6 @@ assert (aFactory.validate(anIntersectionFt))
 assert (len(anIntersectionFt.results()) > 0)
 anItersectionResult = modelAPI_ResultBody(anIntersectionFt.firstResult())
 assert (anItersectionResult is not None)
+
+import model
+assert(model.checkPythonDump())
index 65ca076f16edf1b96f33262a8bd0fadb24cc9578..b6a6e742cba94fc89c79b54b69d1c992c258d0d4 100644 (file)
@@ -192,3 +192,6 @@ aSession.finishOperation()
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index db00eaeeffde8132f605ba0e91ae87a8d75ebdd7..dbc14ed948dbd49706de3997e97ee3d9f6f9cf84 100644 (file)
@@ -129,3 +129,6 @@ assert (aFactory.validate(aPartitionFt))
 assert (len(aPartitionFt.results()) > 0)
 aPartitionResult = modelAPI_ResultBody(aPartitionFt.firstResult())
 assert (aPartitionResult is not None)
+
+import model
+assert(model.checkPythonDump())
index 5623aa59419148e8d8d6e89da7c21894f7adae2a..5cd9a2b9a3cf475128341c521ce94f69cb527a1b 100644 (file)
@@ -163,3 +163,6 @@ aSession.finishOperation()
 
 # Test results
 assert (len(aPipeFeature.results()) > 0)
+
+import model
+assert(model.checkPythonDump())
index 58e328fa95c3fadd3a42f9a6036bac49ebce5865..24619f2173e747a6fa6d278d8d3e81e1a3ec771a 100644 (file)
@@ -217,3 +217,6 @@ aSession.finishOperation()
 assert (len(aPlacementFt.results()) > 0)
 aPlacementResult = modelAPI_ResultBody(aPlacementFt.firstResult())
 assert (aPlacementResult is not None)
+
+import model
+assert(model.checkPythonDump())
index 28a47fc83f2af54ccce154d03fb427c6234aa9f8..f3afa4106e83ef0b8fed2eb3062303f4dd459808 100644 (file)
@@ -15,10 +15,12 @@ mypart = model.addPart(mypartset).document()
 
 sk1 = model.addSketch(mypart, model.defaultPlane("XOY"))
 c1 = sk1.addCircle(0, 0, 100)
+model.do()
 bigcyl = model.addExtrusion(mypart, sk1.selectFace(), 100)
 
 sk2 = model.addSketch(mypart, model.defaultPlane("XOY"))
 c2 = sk2.addCircle(20, 30, 30)
+model.do()
 smallcyl = model.addExtrusion(mypart, sk2.selectFace(), 150)
 
 cut = model.addCut(mypart, bigcyl.result(), smallcyl.result())
@@ -48,6 +50,7 @@ recover = model.addRecover(mypart, cut, smallcyl.result(), True)
 assert(mypart.size("Bodies") == 2)
 sk3 = model.addSketch(mypart, model.defaultPlane("XOY"))
 c3 = sk3.addCircle(0, 0, 90)
+model.do()
 big2 = model.addExtrusion(mypart, sk3.selectFace(), 110)
 
 cut2 = model.addCut(mypart, big2.result(), smallcyl.result())
@@ -64,3 +67,5 @@ recover.setIsPersistent(False)
 model.end()
 # only two booleans
 assert(mypart.size("Bodies") == 2)
+
+assert(model.checkPythonDump())
index 6685760da35ddf022beb74a2db7344e42eaf17a3..713e7e94e3bbc3bff8b12520ac553756ebffa4e6 100644 (file)
@@ -72,3 +72,6 @@ aSession.finishOperation()
 assert (len(aRemoveSubShapesFeature.results()) > 0)
 anUnionResult = modelAPI_ResultCompSolid(modelAPI_ResultBody(aRemoveSubShapesFeature.firstResult()))
 assert (anUnionResult.numberOfSubs() == 2)
+
+import model
+assert(model.checkPythonDump())
index 3f46da758957cd3386b72b2a47f1d5c330f40d3f..cfac07013495388e06287617ebf342503e1c79a3 100644 (file)
@@ -206,3 +206,6 @@ aSession.finishOperation()
 assert (len(aRevolFt.results()) > 0)
 aRevolResult = modelAPI_ResultBody(aRevolFt.firstResult())
 assert (aRevolResult is not None)
+
+import model
+assert(model.checkPythonDump())
index ca8f2b57b57010d2d1eb2f2b65bb350ecdf4080b..6ec4eb3b584c37d659c5273b2745d5f96842e4df 100644 (file)
@@ -144,3 +144,6 @@ assert (aFactory.validate(anRevolutionCutFt))
 assert (len(anRevolutionCutFt.results()) > 0)
 aCurrentResult = modelAPI_ResultBody(anRevolutionCutFt.firstResult())
 assert (aCurrentResult is not None)
+
+import model
+assert(model.checkPythonDump())
index 369c413a0b8accb156e5a4e24730f1c8a20f944c..807a4d4430d57cf14fcd23e360ce14cabbade237 100644 (file)
@@ -172,3 +172,6 @@ assert (aFactory.validate(anRevolutionFuseFt))
 assert (len(anRevolutionFuseFt.results()) > 0)
 aCurrentResult = modelAPI_ResultBody(anRevolutionFuseFt.firstResult())
 assert (aCurrentResult is not None)
+
+import model
+assert(model.checkPythonDump())
index e86b7b8e92502946d177b72f64172cea5262242e..9cd1479c529c41cdf69117c0404122d11963e085 100644 (file)
@@ -132,3 +132,5 @@ assert (len(aRotateFt.results()) > 0)
 aMoveResult = modelAPI_ResultBody(aRotateFt.firstResult())
 assert (aMoveResult is not None)
 
+import model
+assert(model.checkPythonDump())
index ce9fa673474e020385339392a5cce9c49b08e99a..9b248edcc789397da16b601d3b62dae1b05321fa 100644 (file)
@@ -192,3 +192,6 @@ aSession.finishOperation()
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index dd90e09ea0724a63f961530230a663f1264a5ada..820b72c62c8753afb7a36868ac5d6c538c743565 100644 (file)
@@ -132,3 +132,5 @@ assert (len(aMoveFt.results()) > 0)
 aMoveResult = modelAPI_ResultBody(aMoveFt.firstResult())
 assert (aMoveResult is not None)
 
+import model
+assert(model.checkPythonDump())
index 562645c4241bbd77f1d18b46560f07a7a8d50cbf..eb4be902a064e7c82d03704e089b6d9414323f24 100644 (file)
@@ -73,3 +73,6 @@ aSession.finishOperation()
 assert (len(aUnionFeature.results()) > 0)
 anUnionResult = modelAPI_ResultCompSolid(modelAPI_ResultBody(aUnionFeature.firstResult()))
 assert (anUnionResult.numberOfSubs() == 0)
+
+import model
+assert(model.checkPythonDump())
index 4ac7458640a9e61f1ef6681aa0c3eb6689615353..cbb16dd4be9757a23c4c84b90dc6cef6553a33ca 100644 (file)
@@ -39,7 +39,7 @@ static gp_Circ2d* newCirc2d(const double theCenterX, const double theCenterY,
   if (aCenter.IsEqual(aPoint, Precision::Confusion()))
     return NULL;
 
-  gp_Dir2d aDir(theCenterX - thePointX, theCenterY - thePointY);
+  gp_Dir2d aDir(thePointX - theCenterX, thePointY - theCenterY);
 
   return newCirc2d(theCenterX, theCenterY, aDir, aRadius);
 }
index 43627a1dd56a1281fadcec7db90295ec647be12c..5a520fb7cc6b1c43681cd04eac5b33979a2a5c49 100644 (file)
@@ -287,39 +287,39 @@ std::string GeomAPI_Shape::shapeTypeStr() const
 
   switch(aShapeType) {
     case COMPOUND: {
-      aShapeTypeStr = "Compound";
+      aShapeTypeStr = "COMPOUND";
       break;
     }
     case COMPSOLID: {
-      aShapeTypeStr = "CompSolid";
+      aShapeTypeStr = "COMPSOLID";
       break;
     }
     case SOLID: {
-      aShapeTypeStr = "Solid";
+      aShapeTypeStr = "SOLID";
       break;
     }
     case SHELL: {
-      aShapeTypeStr = "Shell";
+      aShapeTypeStr = "SHELL";
       break;
     }
     case FACE: {
-      aShapeTypeStr = "Face";
+      aShapeTypeStr = "FACE";
       break;
     }
     case WIRE: {
-      aShapeTypeStr = "Wire";
+      aShapeTypeStr = "WIRE";
       break;
     }
     case EDGE: {
-      aShapeTypeStr = "Edge";
+      aShapeTypeStr = "EDGE";
       break;
     }
     case VERTEX: {
-      aShapeTypeStr = "Vertex";
+      aShapeTypeStr = "VERTEX";
       break;
     }
     case SHAPE: {
-      aShapeTypeStr = "Shape";
+      aShapeTypeStr = "SHAPE";
       break;
     }
   }
index fb7bdc99f2fc0b9ed89483344d7f2b1065705d1f..8b6116b63e51cf7fd7e019d5088cd291119c562b 100644 (file)
@@ -59,6 +59,8 @@ std::shared_ptr<GeomAPI_Pnt2d> GeomData_Point2D::pnt()
 void GeomData_Point2D::setText(const std::string& theX,
                                const std::string& theY)
 {
+  if (!myIsInitialized && theX.empty() && theY.empty())
+    return; // empty strings are not good initializers
   if (!myIsInitialized || textX() != theX || textY() != theY) {
     myExpression[0]->setText(theX);
     myExpression[1]->setText(theY);
index 4e61cd8f072ace18a6caa6561712e71bcf9f5339..bd91b7d423b521f79431519b0a47e97fd05180ac 100644 (file)
@@ -52,4 +52,7 @@ class GeomDataAPI_Dir : public ModelAPI_Attribute
   GEOMDATAAPI_EXPORT virtual ~GeomDataAPI_Dir();
 };
 
+//! Pointer on attribute object
+typedef std::shared_ptr<GeomDataAPI_Dir> AttributeDirPtr;
+
 #endif
index 617161f9c1624faad28e75b0ceaab38191e0c956..8c324f40b70ec2ce2c9d2a8560cc340f7a8e0535 100644 (file)
@@ -27,7 +27,8 @@ To extend GeomValidators_Different validator with new attribute types:
 
 bool isEqual(const AttributePoint2DPtr& theLeft, const AttributePoint2DPtr& theRight)
 {
-  return theLeft->pnt()->distance(theRight->pnt()) < tolerance;
+  return theLeft->isInitialized() && theRight->isInitialized() &&
+    theLeft->pnt()->distance(theRight->pnt()) < tolerance;
 }
 
 bool isEqualAttributes(const AttributePtr& theLeft, const AttributePtr& theRight)
index 20d324edd59db1d70acaf4c152607a02cf6b75fd..e66cc4333b21256e55797b78894ddb9da9adad57 100644 (file)
@@ -87,11 +87,11 @@ bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr<ModelAPI_Feature>&
   double aToSize = 0.0;
   double aFromSize = 0.0;
 
-  if(theFeature->real(*anIt)) {
+  if(theFeature->real(*anIt) && theFeature->real(*anIt)->isInitialized()) {
     aToSize = theFeature->real(*anIt)->value();
   }
   anIt++;
-  if(theFeature->real(*anIt)) {
+  if(theFeature->real(*anIt) && theFeature->real(*anIt)->isInitialized()) {
     aFromSize = theFeature->real(*anIt)->value();
   }
   anIt++;
@@ -109,7 +109,7 @@ bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr<ModelAPI_Feature>&
   std::shared_ptr<GeomAPI_Shape> aFromShape;
 
   std::shared_ptr<ModelAPI_AttributeSelection> anAttrSel = theFeature->selection(*anIt);
-  if(anAttrSel) {
+  if(anAttrSel && anAttrSel->isInitialized()) {
     aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anAttrSel->value());
     if(aToShape.get() == NULL && anAttrSel->context().get() != NULL) {
       aToShape =  anAttrSel->context()->shape();
@@ -118,13 +118,13 @@ bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr<ModelAPI_Feature>&
   anIt++;
 
   std::shared_ptr<ModelAPI_AttributeDouble> anAttrDouble = theFeature->real(*anIt);
-  if(anAttrDouble) {
+  if(anAttrDouble && anAttrDouble->isInitialized()) {
     aToSize = anAttrDouble->value();
   }
   anIt++;
 
   anAttrSel = theFeature->selection(*anIt);
-  if(anAttrSel) {
+  if(anAttrSel && anAttrSel->isInitialized()) {
     aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anAttrSel->value());
     if(aFromShape.get() == NULL && anAttrSel->context().get() != NULL) {
       aFromShape = anAttrSel->context()->shape();
@@ -133,7 +133,7 @@ bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr<ModelAPI_Feature>&
   anIt++;
 
   anAttrDouble = theFeature->real(*anIt);
-  if(anAttrDouble) {
+  if(anAttrDouble && anAttrDouble->isInitialized()) {
     aFromSize = anAttrDouble->value();
   }
 
index c6ad9ab0c43e40e27914f95a88daaa58ee391285..93b60ffd2fc316daefd759d540d6f0a46b80aae6 100644 (file)
@@ -71,18 +71,12 @@ void InitializationPlugin_Plugin::processEvent(const std::shared_ptr<Events_Mess
       }
     }
     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-
     // the viewer update should be unblocked in order to avoid the features blinking before they are
     // hidden
     aMsg = std::shared_ptr<Events_Message>(
                   new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
 
     Events_Loop::loop()->send(aMsg);
-
-  } else if (theMessage.get()) {
-    Events_InfoMessage("InitializationPlugin_Plugin",
-        "InitializationPlugin_Plugin::processEvent: unhandled message caught: %1")
-            .arg(theMessage->eventID().eventText()).send();
   }
 }
 
index 3ebcaf953db0f6a17d9460084274f5cf116628dd..f603def2d681f8ffbea1fa3b2cf146d286fce82c 100644 (file)
@@ -14,6 +14,8 @@ void Model_AttributeBoolean::setValue(bool theValue)
 {
   Standard_Boolean aValue = theValue ? Standard_True : Standard_False;
   if (!myIsInitialized || myBool->Get() != aValue) {
+    if (myBool.IsNull())
+      myBool = TDataStd_Integer::Set(myLab, 0);
     myBool->Set(aValue);
     owner()->data()->sendAttributeUpdated(this);
   }
@@ -21,15 +23,12 @@ void Model_AttributeBoolean::setValue(bool theValue)
 
 bool Model_AttributeBoolean::value()
 {
-  return myBool->Get() == Standard_True ;
+  return myIsInitialized && myBool->Get() == Standard_True ;
 }
 
 Model_AttributeBoolean::Model_AttributeBoolean(TDF_Label& theLabel)
 {
+  myLab = theLabel;
   // check the attribute could be already presented in this doc (after load document)
   myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), myBool) == Standard_True;
-  if (!myIsInitialized) {
-    // create attribute: not initialized by value yet, just zero
-    myBool = TDataStd_Integer::Set(theLabel, 0);
-  }
 }
index c3217b6ca7f6112b099aa2334a92beb1bd9b90a4..1ad1f487e170854ef9f1bdf06a076294ceb8aeb4 100644 (file)
@@ -20,6 +20,7 @@
 class Model_AttributeBoolean : public ModelAPI_AttributeBoolean
 {
   Handle_TDataStd_Integer myBool;  ///< double is Real attribute
+  TDF_Label myLab; ///< if attribute is not initialized, store label here
  public:
   /// Defines the double value
   MODEL_EXPORT virtual void setValue(bool theValue);
index 92b91327c230a0cf7f2133ec39424b2241d4575b..ac66944c56b40d3a4f15ece7dcf2ef0bfc89587f 100644 (file)
@@ -56,6 +56,8 @@
 #include <TopoDS_Iterator.hxx>
 #include <TNaming_Iterator.hxx>
 #include <BRep_Builder.hxx>
+#include <ModelAPI_Session.h>
+
 using namespace std;
 //#define DEB_NAMING 1
 #ifdef DEB_NAMING
@@ -146,7 +148,8 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
         aBuilder.Generated(theContext->shape()->impl<TopoDS_Shape>());
         std::shared_ptr<Model_Document> aMyDoc = 
           std::dynamic_pointer_cast<Model_Document>(owner()->document());
-        std::string aName = theContext->data()->name();
+        std::string aName = contextName(theContext);
+        // for selection in different document, add the document name
         aMyDoc->addNamingName(aSelLab, aName);
         TDataStd_Name::Set(aSelLab, aName.c_str());
       } else {  // for sketch the naming is needed in DS
@@ -173,10 +176,6 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
   //myIsInitialized = true;
 
   owner()->data()->sendAttributeUpdated(this);
-
-  std::string aSelName = namingName();
-  if(!aSelName.empty())
-    TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name
 }
 
 std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
@@ -373,19 +372,6 @@ TDF_LabelMap& Model_AttributeSelection::scope()
   return myScope;
 }
 
-/// produces theEdge orientation relatively to theContext face
-int edgeOrientation(const TopoDS_Shape& theContext, TopoDS_Edge& theEdge)
-{
-  if (theContext.ShapeType() != TopAbs_FACE)
-    return 0;
-  TopoDS_Face aContext = TopoDS::Face(theContext);
-  if (theEdge.Orientation() == TopAbs_FORWARD) 
-    return 1;
-  if (theEdge.Orientation() == TopAbs_REVERSED) 
-    return -1;
-  return 0; // unknown
-}
-
 /// Sets the invalid flag if flag is false, or removes it if "true"
 /// Returns theFlag
 static bool setInvalidIfFalse(TDF_Label& theLab, const bool theFlag) {
@@ -428,7 +414,7 @@ bool Model_AttributeSelection::update()
       aBuilder.Generated(aContext->shape()->impl<TopoDS_Shape>());
       std::shared_ptr<Model_Document> aMyDoc = 
         std::dynamic_pointer_cast<Model_Document>(owner()->document());
-      std::string aName = aContext->data()->name();
+      std::string aName = contextName(aContext);
       aMyDoc->addNamingName(aSelLab, aName);
       TDataStd_Name::Set(aSelLab, aName.c_str());
     }
@@ -520,43 +506,7 @@ bool Model_AttributeSelection::update()
               }
             }
           }
-          int aBestFound = 0; // best number of found edges (not percentage: issue 1019)
-          int aBestOrient = 0; // for the equal "BestFound" additional parameter is orientation
-          for(int aFaceIndex = 0; aFaceIndex < aConstructionContext->facesNum(); aFaceIndex++) {
-            int aFound = 0, aNotFound = 0, aSameOrientation = 0;
-            TopoDS_Face aFace = 
-              TopoDS::Face(aConstructionContext->face(aFaceIndex)->impl<TopoDS_Shape>());
-            TopExp_Explorer anEdgesExp(aFace, TopAbs_EDGE);
-            TColStd_MapOfTransient alreadyProcessed; // to avoid counting edges with same curved (841)
-            for(; anEdgesExp.More(); anEdgesExp.Next()) {
-              TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current());
-              if (!anEdge.IsNull()) {
-                Standard_Real aFirst, aLast;
-                Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
-                if (alreadyProcessed.Contains(aCurve))
-                  continue;
-                alreadyProcessed.Add(aCurve);
-                if (allCurves.IsBound(aCurve)) {
-                  aFound++;
-                  int anOrient = allCurves.Find(aCurve);
-                  if (anOrient != 0) {  // extra comparision score is orientation
-                    if (edgeOrientation(aFace, anEdge) == anOrient)
-                      aSameOrientation++;
-                  }
-                } else {
-                  aNotFound++;
-                }
-              }
-            }
-            if (aFound + aNotFound != 0) {
-              if (aFound > aBestFound || 
-                  (aFound == aBestFound && aSameOrientation > aBestOrient)) {
-                aBestFound = aFound;
-                aBestOrient = aSameOrientation;
-                aNewSelected = aConstructionContext->face(aFaceIndex);
-              }
-            }
-          }
+          aNewSelected = Model_SelectionNaming::findAppropriateFace(aContext, allCurves);
         }
         if (aNewSelected) { // store this new selection
           if (aShapeType == TopAbs_WIRE) { // just get a wire from face to have wire
@@ -691,6 +641,7 @@ void Model_AttributeSelection::selectBody(
 static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape,
   const int theID, const FeaturePtr& theContextFeature, std::shared_ptr<Model_Document> theDoc,
   std::string theAdditionalName, std::map<int, int>& theOrientations,
+  std::map<int, std::string>& theSubNames, // name of sub-elements by ID to be exported instead of indexes
   Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)(),
   const int theOrientation = 0)
 {
@@ -701,29 +652,44 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape,
   TNaming_Builder aBuilder(aLab);
   aBuilder.Generated(theShape);
   std::stringstream aName;
-  aName<<theContextFeature->name()<<"/";
-  if (!theAdditionalName.empty())
-    aName<<theAdditionalName<<"/";
-  if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face";
-  else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire";
-  else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge";
-  else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex";
-
-  if (theRefs.IsNull()) {
-    aName<<theID;
-    if (theOrientation == 1)
-      aName<<"f";
-    else if (theOrientation == -1)
-      aName<<"r";
-  } else { // make a composite name from all sub-elements indexes: "1_2_3_4"
-    TColStd_MapIteratorOfPackedMapOfInteger aRef(theRefs->GetMap());
-    for(; aRef.More(); aRef.Next()) {
-      aName<<"-"<<aRef.Key();
-      if (theOrientations.find(aRef.Key()) != theOrientations.end()) {
-        if (theOrientations[aRef.Key()] == 1)
-          aName<<"f";
-        else if (theOrientations[aRef.Key()] == -1)
-          aName<<"r";
+  // add the part name if the selected object is located in other part
+  if (theDoc != theContextFeature->document()) {
+    if (theContextFeature->document() == ModelAPI_Session::get()->moduleDocument()) {
+      aName<<theContextFeature->document()->kind()<<"/";
+    } else {
+      ResultPtr aDocRes = ModelAPI_Tools::findPartResult(
+        ModelAPI_Session::get()->moduleDocument(), theContextFeature->document());
+      if (aDocRes.get()) {
+        aName<<aDocRes->data()->name()<<"/";
+      }
+    }
+  }
+  aName<<theContextFeature->name();
+  if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction
+    aName<<"/";
+    if (!theAdditionalName.empty())
+      aName<<theAdditionalName<<"/";
+    if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face";
+    else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire";
+    else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge";
+    else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex";
+
+    if (theRefs.IsNull()) {
+      aName<<theID;
+      if (theOrientation == 1)
+        aName<<"f";
+      else if (theOrientation == -1)
+        aName<<"r";
+    } else { // make a composite name from all sub-elements indexes: "1_2_3_4"
+      TColStd_MapIteratorOfPackedMapOfInteger aRef(theRefs->GetMap());
+      for(; aRef.More(); aRef.Next()) {
+        aName<<"-"<<theSubNames[aRef.Key()];
+        if (theOrientations.find(aRef.Key()) != theOrientations.end()) {
+          if (theOrientations[aRef.Key()] == 1)
+            aName<<"f";
+          else if (theOrientations[aRef.Key()] == -1)
+            aName<<"r";
+        }
       }
     }
   }
@@ -745,8 +711,9 @@ void Model_AttributeSelection::selectConstruction(
     // saving of context is enough: result construction contains exactly the needed shape
     TNaming_Builder aBuilder(selectionLabel());
     aBuilder.Generated(aSubShape);
-    aMyDoc->addNamingName(selectionLabel(), theContext->data()->name());
-    TDataStd_Name::Set(selectionLabel(), theContext->data()->name().c_str());
+    std::string aName = contextName(theContext);
+    aMyDoc->addNamingName(selectionLabel(), aName);
+    TDataStd_Name::Set(selectionLabel(), aName.c_str());
     return;
   }
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(owner()->data());
@@ -770,6 +737,7 @@ void Model_AttributeSelection::selectConstruction(
   // iterate and store the result ids of sub-elements and sub-elements to sub-labels
   Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
   std::map<int, int> anOrientations; //map from edges IDs to orientations of these edges in face
+  std::map<int, std::string> aSubNames; //map from edges IDs to names of edges
   aRefs->Clear();
   const int aSubNum = aComposite->numberOfSubs();
   for(int a = 0; a < aSubNum; a++) {
@@ -789,14 +757,17 @@ void Model_AttributeSelection::selectConstruction(
           gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex));
           if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) {
             aRefs->Add(aComposite->subFeatureId(a));
+            aSubNames[aComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr);
           }
-        } else { // get first or last vertex of the edge: last is stored with negative sign
+        } else { // get first or last vertex of the edge: last is stored with additional delta
           const TopoDS_Shape& anEdge = aConstr->shape()->impl<TopoDS_Shape>();
           int aDelta = kSTART_VERTEX_DELTA;
           for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) {
             gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current()));
             if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) {
               aRefs->Add(aDelta + aComposite->subFeatureId(a));
+              aSubNames[aDelta + aComposite->subFeatureId(a)] =
+                Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA);
               break;
             }
             aDelta += kSTART_VERTEX_DELTA;
@@ -812,6 +783,7 @@ void Model_AttributeSelection::selectConstruction(
             if (allCurves.Contains(aCurve)) {
               int anID = aComposite->subFeatureId(a);
               aRefs->Add(anID);
+              aSubNames[anID] = Model_SelectionNaming::shortName(aConstr);
               if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels
                 // add edges to sub-label to support naming for edges selection
                 TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE);
@@ -820,11 +792,11 @@ void Model_AttributeSelection::selectConstruction(
                   Standard_Real aFirst, aLast;
                   Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
                   if (aFaceCurve == aCurve) {
-                    int anOrient = edgeOrientation(aSubShape, anEdge);
+                    int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
                     anOrientations[anID] = anOrient;
                     registerSubShape(
                       selectionLabel(), anEdge, anID, aContextFeature, aMyDoc, "", anOrientations,
-                      Handle(TDataStd_IntPackedMap)(), anOrient);
+                      aSubNames, Handle(TDataStd_IntPackedMap)(), anOrient);
                   }
                 }
               } else { // put vertices of the selected edge to sub-labels
@@ -836,7 +808,8 @@ void Model_AttributeSelection::selectConstruction(
 
                   std::stringstream anAdditionalName; 
                   registerSubShape(
-                    selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, "", anOrientations);
+                    selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, "", anOrientations,
+                    aSubNames);
                 }
               }
             }
@@ -849,7 +822,7 @@ void Model_AttributeSelection::selectConstruction(
   TNaming_Builder aBuilder(selectionLabel());
   aBuilder.Generated(aSubShape);
     registerSubShape(
-      selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", anOrientations, aRefs); 
+      selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", anOrientations, aSubNames, aRefs); 
 }
 
 bool Model_AttributeSelection::selectPart(
@@ -899,11 +872,6 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa
   std::string aName("");
   if(!this->isInitialized())
     return !theDefaultName.empty() ? theDefaultName : aName;
-  Handle(TDataStd_Name) anAtt;
-  if(selectionLabel().FindAttribute(TDataStd_Name::GetID(), anAtt)) {
-    aName = TCollection_AsciiString(anAtt->Get()).ToCString();
-    return aName;
-  }
 
   std::shared_ptr<GeomAPI_Shape> aSubSh = value();
   ResultPtr aCont = context();
@@ -1015,3 +983,20 @@ void Model_AttributeSelection::setId(int theID)
   setValue(aContext, aSelection);
 }
 
+std::string Model_AttributeSelection::contextName(const ResultPtr& theContext) const
+{
+  std::string aResult;
+  if (owner()->document() != theContext->document()) {
+    if (theContext->document() == ModelAPI_Session::get()->moduleDocument()) {
+      aResult = theContext->document()->kind() + "/";
+    } else {
+      ResultPtr aDocRes = ModelAPI_Tools::findPartResult(
+        ModelAPI_Session::get()->moduleDocument(), theContext->document());
+      if (aDocRes.get()) {
+        aResult = aDocRes->data()->name() + "/";
+      }
+    }
+  }
+  aResult += theContext->data()->name();
+  return aResult;
+}
index 1f3c4594570754cab0c5af149c814f32f499c9d6..2f9250642d023a018a0c265aebf27f4521580010 100644 (file)
@@ -104,6 +104,9 @@ protected:
   /// Sets the ID of the attribute in Data (called from Data): here it is used for myRef ID setting
   MODEL_EXPORT virtual void setID(const std::string theID);
 
+  /// Returns the name by context. Adds the part name if the context is located in other document
+  std::string contextName(const ResultPtr& theContext) const;
+
   friend class Model_Data;
   friend class Model_AttributeSelectionList;
 };
index d2bd6191aa87a8aa9dea0864c05792a5c776c577..773a8bef919fbeaf61988b4080f8da2512d0e13b 100644 (file)
@@ -20,6 +20,8 @@ void Model_AttributeString::setValue(const std::string& theValue)
 {
   TCollection_ExtendedString aValue(theValue.c_str());
   if (!myIsInitialized || myString->Get() != aValue) {
+    if (myString.IsNull())
+      myString = TDataStd_Name::Set(myLab, TCollection_ExtendedString());
     myString->Set(aValue);
     owner()->data()->sendAttributeUpdated(this);
   }
@@ -27,15 +29,14 @@ void Model_AttributeString::setValue(const std::string& theValue)
 
 std::string Model_AttributeString::value()
 {
+  if (myString.IsNull())
+    return "";  // not initialized
   return TCollection_AsciiString(myString->Get()).ToCString();
 }
 
 Model_AttributeString::Model_AttributeString(TDF_Label& theLabel)
 {
+  myLab = theLabel;
   // check the attribute could be already presented in this doc (after load document)
   myIsInitialized = theLabel.FindAttribute(TDataStd_Name::GetID(), myString) == Standard_True;
-  if (!myIsInitialized) {
-    // create attribute: not initialized by value yet, just empty string
-    myString = TDataStd_Name::Set(theLabel, TCollection_ExtendedString());
-  }
 }
index 2d1ba634dea54673f8a62b93e388d4b1413c463d..ac020f051cb82c2a88c0e66cb18fd34731e78b90 100644 (file)
@@ -22,7 +22,8 @@
 
 class Model_AttributeString : public ModelAPI_AttributeString
 {
-  Handle_TDataStd_Name myString;
+  Handle_TDataStd_Name myString; ///< container of the string value
+  TDF_Label myLab; ///< if attribute is not initialized, store label here
  public:
   /// Defines the std::string value
   MODEL_EXPORT virtual void setValue(const std::string& theValue);
index bfa8d62fe1a32d7a78b6a20dd77aa45c8e1e4172..56d22c8c16ad58faaa8d17cd1f29108238e67b48 100755 (executable)
@@ -235,6 +235,15 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theO
           TDataStd_Name::Set(aSubBuilder.NamedShape()->Label(), aSolidName.c_str());
         }
       }
+    } else if(!aBuilder.NamedShape()->IsEmpty()) {
+      Handle(TDataStd_Name) anAttr;
+      if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+        std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
+        if(!aName.empty()) {
+          std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+        }
+      }
     }
   }
 }
@@ -284,10 +293,9 @@ TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
 
 void Model_BodyBuilder::buildName(const int theTag, const std::string& theName)
 {
-  std::string aName = data()->name() + "/" + theName; 
   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
-  aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), aName);
-  TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(),aName.c_str());
+  //aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), theName);
+  TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(), theName.c_str());
 }
 void Model_BodyBuilder::generated(
   const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
@@ -316,8 +324,8 @@ void Model_BodyBuilder::generated(const std::shared_ptr<GeomAPI_Shape>& theOldSh
       TDF_Label aChildLabel = aLabel.FindChild(aTag);
       TNaming_Builder aBuilder(aChildLabel);
       aBuilder.Generated(anOldShape, anExp.Current());
-      TCollection_AsciiString aChildName = TCollection_AsciiString((data()->name() + "/" + theName + "_").c_str()) + aTag;
-      aDoc->addNamingName(aChildLabel, aChildName.ToCString());
+      TCollection_AsciiString aChildName = TCollection_AsciiString((theName + "_").c_str()) + aTag;
+      //aDoc->addNamingName(aChildLabel, aChildName.ToCString());
       TDataStd_Name::Set(aChildLabel, aChildName.ToCString());
       aTag++;
     }
@@ -455,8 +463,8 @@ void Model_BodyBuilder::loadAndOrientGeneratedShapes (
           TDF_Label aChildLabel = aLabel.FindChild(aTag);
           TNaming_Builder aBuilder(aChildLabel);
           aBuilder.Generated(aRoot, anExp.Current());
-          TCollection_AsciiString aChildName = TCollection_AsciiString((data()->name() + "/" + theName + "_").c_str()) + aTag;
-          aDoc->addNamingName(aChildLabel, aChildName.ToCString());
+          TCollection_AsciiString aChildName = TCollection_AsciiString((theName + "_").c_str()) + aTag;
+          //aDoc->addNamingName(aChildLabel, aChildName.ToCString());
           TDataStd_Name::Set(aChildLabel, aChildName.ToCString());
           aTag++;
         }
@@ -711,23 +719,6 @@ void Model_BodyBuilder::loadDisconnectedEdges(
     }
   }
 
-  /*  TopTools_IndexedDataMapOfShapeListOfShape aDM;
-  TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, aDM);
-  for(int i=1; i <= aDM.Extent(); i++) {
-  if(aDM.FindFromIndex(i).Extent() > 1) continue;
-  if (BRep_Tool::Degenerated(TopoDS::Edge(aDM.FindKey(i))))
-  continue;
-  builder(theTag)->Generated(aDM.FindKey(i));
-  TCollection_AsciiString aStr(theTag);
-  std::string aName = theName + aStr.ToCString();
-  buildName(theTag, aName);
-  #ifdef DEB_IMPORT
-  aName +=  + ".brep";
-  BRepTools::Write(aDM.FindKey(i), aName.c_str());
-  #endif
-  theTag++;
-  }
-  */
   TopTools_MapOfShape anEdgesToDelete;
   TopExp_Explorer anEx(aShape,TopAbs_EDGE); 
   std::string aName;
index 60714f8becb2a6d490c21542327ee6954207acbf..7f86b2116b0bc3c38fa6f24a681d3684c8f78b7e 100644 (file)
@@ -112,6 +112,10 @@ void Model_Data::setName(const std::string& theName)
   }
   if (mySendAttributeUpdated && isModified)
     ModelAPI_ObjectRenamedMessage::send(myObject, anOldName, theName, this);
+  if (isModified && myObject && myObject->document()) {
+    std::dynamic_pointer_cast<Model_Document>(myObject->document())->
+      changeNamingName(anOldName, theName);
+  }
 }
 
 AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
@@ -638,15 +642,10 @@ void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
 {
   TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
   copyAttrs(myLab, aTargetRoot);
-  // make initialized the initialized attributes
-  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator aMyIter = myAttrs.begin();
-  for(; aMyIter != myAttrs.end(); aMyIter++) {
-    if (aMyIter->second->isInitialized()) {
-      AttributePtr aTargetAttr = theTarget->attribute(aMyIter->first);
-      if (aTargetAttr)
-        aTargetAttr->setInitialized();
-    }
-  }
+  // reinitialize Model_Attributes by TDF_Attributes set
+  std::shared_ptr<Model_Data> aTData = std::dynamic_pointer_cast<Model_Data>(theTarget);
+  aTData->myAttrs.clear();
+  theTarget->owner()->initAttributes(); // reinit feature attributes
 }
 
 bool Model_Data::isInHistory()
index ebc4de9d8871ea39ed8d1e4d6e4a0bf84057ee93..fdfaa6f6970b47511770cd250fac59957c812b3d 100755 (executable)
@@ -16,7 +16,6 @@
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultBody.h>
-
 #include <Events_Loop.h>
 #include <Events_InfoMessage.h>
 
 #include <TDF_ChildIDIterator.hxx>
 #include <TDF_LabelMapHasher.hxx>
 #include <TDF_Delta.hxx>
-#include <OSD_File.hxx>
-#include <OSD_Path.hxx>
 #include <TDF_AttributeDelta.hxx>
 #include <TDF_AttributeDeltaList.hxx>
 #include <TDF_ListIteratorOfAttributeDeltaList.hxx>
 #include <TDF_ListIteratorOfLabelList.hxx>
-#include <TopoDS_Shape.hxx>
+#include <TDF_LabelMap.hxx>
 #include <TNaming_SameShapeIterator.hxx>
 #include <TNaming_Iterator.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Tool.hxx>
+
 #include <TopExp_Explorer.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
 
 #include <climits>
 #ifndef WIN32
@@ -366,7 +368,7 @@ void Model_Document::compactNested()
   }
 }
 
-/// Compares the content ofthe given attributes, returns true if equal.
+/// Compares the content of the given attributes, returns true if equal.
 /// This method is used to avoid empty transactions when only "current" is changed
 /// to some value and then comes back in this transaction, so, it compares only
 /// references and Boolean and Integer Arrays for the current moment.
@@ -488,6 +490,11 @@ bool Model_Document::finishOperation()
   bool isNestedClosed = !myDoc->HasOpenCommand() && !myNestedNum.empty();
   static std::shared_ptr<Model_Session> aSession = 
     std::static_pointer_cast<Model_Session>(Model_Session::get());
+
+  // open transaction if nested is closed to fit inside all synchronizeBackRefs and flushed consequences
+  if (isNestedClosed) {
+    myDoc->OpenCommand();
+  }
   // do it before flashes to enable and recompute nesting features correctly
   if (myNestedNum.empty() || (isNestedClosed && myNestedNum.size() == 1)) {
     // if all nested operations are closed, make current the higher level objects (to perform 
@@ -507,6 +514,12 @@ bool Model_Document::finishOperation()
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+
+  if (isNestedClosed) {
+    if (myDoc->CommitCommand())
+      myTransactions.rbegin()->myOCAFNum++;
+  }
+  
   // this must be here just after everything is finished but before real transaction stop
   // to avoid messages about modifications outside of the transaction
   // and to rebuild everything after all updates and creates
@@ -575,8 +588,28 @@ static void modifiedLabels(const Handle(TDocStd_Document)& theDoc, TDF_LabelList
   }
   // add also label of the modified attributes
   const TDF_AttributeDeltaList& anAttrs = aDelta->AttributeDeltas();
+  TDF_LabelMap anExcludedInt; /// named shape evolution also modifies integer on this label: exclude it
   for (TDF_ListIteratorOfAttributeDeltaList anAttr(anAttrs); anAttr.More(); anAttr.Next()) {
-    theDelta.Append(anAttr.Value()->Label());
+    if (anAttr.Value()->Attribute()->ID() == TDataStd_BooleanArray::GetID()) {
+      continue; // Boolean array is used for feature auxiliary attributes only, feature args are not modified
+    }
+    if (anAttr.Value()->Attribute()->ID() == TNaming_NamedShape::GetID()) {
+      anExcludedInt.Add(anAttr.Value()->Label());
+      continue; // named shape evolution is changed in history update => skip them, they are not the features arguents
+    }
+    if (anAttr.Value()->Attribute()->ID() == TDataStd_Integer::GetID()) {
+      if (anExcludedInt.Contains(anAttr.Value()->Label()))
+        continue;
+    }
+      theDelta.Append(anAttr.Value()->Label());
+  }
+  TDF_ListIteratorOfLabelList aDeltaIter(theDelta);
+  for(; aDeltaIter.More(); aDeltaIter.Next()) {
+    if (anExcludedInt.Contains(aDeltaIter.Value())) {
+      theDelta.Remove(aDeltaIter);
+      if (!aDeltaIter.More())
+        break;
+    }
   }
 }
 
@@ -1025,9 +1058,11 @@ void Model_Document::setCurrentFeature(
     }
 
     if (anIter->setDisabled(aDisabledFlag)) {
-      // state of feature is changed => so feature become updated
       static Events_ID anUpdateEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED);
-      ModelAPI_EventCreator::get()->sendUpdated(anIter, anUpdateEvent);
+      // state of feature is changed => so inform that it must be updated if it has such state
+      if (!aDisabledFlag && 
+          (anIter->data()->execState() == ModelAPI_StateMustBeUpdated || anIter->data()->execState() == ModelAPI_StateInvalidArgument))
+        ModelAPI_EventCreator::get()->sendUpdated(anIter, anUpdateEvent);
       // flush is in the end of this method
       ModelAPI_EventCreator::get()->sendUpdated(anIter, aRedispEvent /*, false*/);
       aWasChanged = true;
@@ -1134,12 +1169,38 @@ void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName
   myNamingNames[theName] = theLabel;
 }
 
+void Model_Document::changeNamingName(const std::string theOldName, const std::string theNewName)
+{
+  std::map<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theOldName);
+  if (aFind != myNamingNames.end()) {
+    myNamingNames[theNewName] = aFind->second;
+    myNamingNames.erase(theOldName);
+  }
+}
+
 TDF_Label Model_Document::findNamingName(std::string theName)
 {
   std::map<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theName);
-  if (aFind == myNamingNames.end())
-    return TDF_Label(); // not found
-  return aFind->second;
+  if (aFind != myNamingNames.end()) {
+    return aFind->second;
+  }
+  // not found exact name, try to find by sub-components
+  std::string::size_type aSlash = theName.rfind('/');
+  if (aSlash != std::string::npos) {
+    std::string anObjName = theName.substr(0, aSlash);
+    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();
+      }
+    }
+  }
+  return TDF_Label(); // not found
 }
 
 ResultPtr Model_Document::findByName(const std::string theName)
index f00d87a013f238ac23ac0d02bba7650157ffcd31..46ffb4c86feef45319ee2eab33c03db3605b56d0 100644 (file)
@@ -187,6 +187,8 @@ class Model_Document : public ModelAPI_Document
 
   //! 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);
   //! Returns the label, keeper of the name  for the topological naming needs
   TDF_Label findNamingName(std::string theName);
   //! Returns the result by name of the result (names of results must be unique, used for naming
@@ -283,6 +285,7 @@ class Model_Document : public ModelAPI_Document
   friend class Model_AttributeSelection;
   friend class Model_ResultPart;
   friend class Model_ResultCompSolid;
+  friend class Model_SelectionNaming;
   friend class DFBrowser;
 
  private:
index c7ad95c8188ee116a3fc086cbe8ac490a2d61dbc..7082bd60c0293ba31434b1c9cea62cfa43619228 100644 (file)
@@ -14,6 +14,7 @@
 #include <TDataStd_RealArray.hxx>
 #include <TDataStd_ExtStringArray.hxx>
 
+#include <limits>
 
 static Standard_GUID kInvalidGUID("caee5ce4-34b1-4b29-abcb-685287d18096");
 
@@ -33,8 +34,10 @@ Model_Expression::Model_Expression(TDF_Label& theLabel)
 
 void Model_Expression::setText(const std::string& theValue)
 {
-  if (text() != theValue)
+  if (text() != theValue) {
     myText->Set(TCollection_ExtendedString(theValue.c_str()));
+    myIsInitialized = true; // the value will be set very soon
+  }
 
   setError(text().empty() ? "" : "Not a double value.");
 }
@@ -76,11 +79,11 @@ Model_ExpressionDouble::Model_ExpressionDouble(TDF_Label& theLabel)
     : Model_Expression(theLabel)
 {
   if (!theLabel.FindAttribute(TDataStd_Real::GetID(), myReal)) {
-    myReal = TDataStd_Real::Set(theLabel, 0.);
     myIsInitialized = false;
     // MPV: temporarily to support the previously saved files (to check and resolve bugs), to be removed
     Handle(TDataStd_RealArray) anOldArray;
     if (theLabel.Father().FindAttribute(TDataStd_RealArray::GetID(), anOldArray) == Standard_True) {
+      myReal = TDataStd_Real::Set(theLabel, 0.);
       myReal->Set(anOldArray->Value(theLabel.Tag() - 1));
       myIsInitialized = true;
       Handle(TDataStd_ExtStringArray) anOldExp;
@@ -91,6 +94,7 @@ Model_ExpressionDouble::Model_ExpressionDouble(TDF_Label& theLabel)
       Handle(TDataStd_Real) anOldReal;
       if (theLabel.Father().FindAttribute(TDataStd_Real::GetID(), anOldReal)) {
         myIsInitialized = true;
+        myReal = TDataStd_Real::Set(theLabel, 0.);
         myReal->Set(anOldReal->Get());
         Handle(TDataStd_Name) aText;
         if (theLabel.Father().FindAttribute(TDataStd_Name::GetID(), aText)) {
@@ -104,27 +108,33 @@ Model_ExpressionDouble::Model_ExpressionDouble(TDF_Label& theLabel)
 
 void Model_ExpressionDouble::setValue(const double theValue)
 {
-  if (value() != theValue)
+  if (!myIsInitialized || myReal.IsNull()) {
+    myReal = TDataStd_Real::Set(myText->Label(), theValue);
+    myIsInitialized = true;
+  } else if (value() != theValue) {
     myReal->Set(theValue);
+  }
 }
 
 double Model_ExpressionDouble::value()
 {
-  return myReal->Get();
+  if (myIsInitialized)
+    return myReal->Get();
+  return std::numeric_limits<double>::max(); // error
 }
 
 void Model_ExpressionDouble::setInvalid(const bool theFlag)
 {
   if (theFlag) {
-    TDataStd_UAttribute::Set(myReal->Label(), kInvalidGUID);
+    TDataStd_UAttribute::Set(myText->Label(), kInvalidGUID);
   } else {
-    myReal->Label().ForgetAttribute(kInvalidGUID);
+    myText->Label().ForgetAttribute(kInvalidGUID);
   }
 }
 
 bool Model_ExpressionDouble::isInvalid()
 {
-  return myReal->Label().IsAttribute(kInvalidGUID) == Standard_True;
+  return myText->Label().IsAttribute(kInvalidGUID) == Standard_True;
 }
 
 
@@ -132,7 +142,6 @@ Model_ExpressionInteger::Model_ExpressionInteger(TDF_Label& theLabel)
     : Model_Expression(theLabel)
 {
   if (!theLabel.FindAttribute(TDataStd_Integer::GetID(), myInteger)) {
-    myInteger = TDataStd_Integer::Set(theLabel, 0);
     myIsInitialized = false;
   } else
     myIsInitialized = true;
@@ -140,25 +149,31 @@ Model_ExpressionInteger::Model_ExpressionInteger(TDF_Label& theLabel)
 
 void Model_ExpressionInteger::setValue(const int theValue)
 {
-  if (value() != theValue)
+  if (!myIsInitialized || myInteger.IsNull()) {
+    myInteger = TDataStd_Integer::Set(myText->Label(), theValue);
+    myIsInitialized = true;
+  } else if (value() != theValue) {
     myInteger->Set(theValue);
+  }
 }
 
 int Model_ExpressionInteger::value()
 {
-  return myInteger->Get();
+  if (myIsInitialized)
+    return myInteger->Get();
+  return std::numeric_limits<int>::max(); // error
 }
 
 void Model_ExpressionInteger::setInvalid(const bool theFlag)
 {
   if (theFlag) {
-    TDataStd_UAttribute::Set(myInteger->Label(), kInvalidGUID);
+    TDataStd_UAttribute::Set(myText->Label(), kInvalidGUID);
   } else {
-    myInteger->Label().ForgetAttribute(kInvalidGUID);
+    myText->Label().ForgetAttribute(kInvalidGUID);
   }
 }
 
 bool Model_ExpressionInteger::isInvalid()
 {
-  return myInteger->Label().IsAttribute(kInvalidGUID) == Standard_True;
+  return myText->Label().IsAttribute(kInvalidGUID) == Standard_True;
 }
index 0519e3b1231b61074a6b4cb257b9f6021ac8714d..f1edf57aac1a427ab90f77430dd4a4197015690b 100644 (file)
@@ -663,6 +663,11 @@ void Model_Objects::synchronizeFeatures(
       aFeature = myFeatures.Find(aFeatureLabel);
       aKeptFeatures.insert(aFeature);
       if (anUpdatedMap.Contains(aFeatureLabel)) {
+        if (!theOpen) { // on abort/undo/redo reinitialize attributes is something is changed
+          std::shared_ptr<Model_Data> aD = std::dynamic_pointer_cast<Model_Data>(aFeature->data());
+          aD->myAttrs.clear();
+          aFeature->initAttributes();
+        }
         ModelAPI_EventCreator::get()->sendUpdated(aFeature, anUpdateEvent);
         if (aFeature->getKind() == "Parameter") { // if parameters are changed, update the results (issue 937)
           const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
@@ -1103,9 +1108,10 @@ ResultPtr Model_Objects::findByName(const std::string theName)
     FeaturePtr& aFeature = anObjIter.ChangeValue();
     if (!aFeature.get() || aFeature->isDisabled()) // may be on close
       continue;
-    const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
-    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
-    for (; aRIter != aResults.cend(); aRIter++) {
+    std::list<ResultPtr> allResults;
+    ModelAPI_Tools::allResults(aFeature, allResults);
+    std::list<ResultPtr>::iterator aRIter = allResults.begin();
+    for (; aRIter != allResults.cend(); aRIter++) {
       ResultPtr aRes = *aRIter;
       if (aRes.get() && aRes->data() && aRes->data()->isValid() && !aRes->isDisabled() &&
           aRes->data()->name() == theName) {
index 517311b1edd765c0ae73ccfda572204cab7bbf41..72c85936b48c00153b3cf9eda46f7905e8ad9cc7 100644 (file)
@@ -222,6 +222,8 @@ class Model_Objects
   friend class Model_AttributeReference;
   friend class Model_AttributeRefAttr;
   friend class Model_AttributeRefList;
+  friend class Model_AttributeRefList;
+  friend class Model_SelectionNaming;
 };
 
 #endif
index c577080b136565379a1a3e006e05db9dfb84acbe..5bf2d58c9f71c9e010ad0bb56de1f4f5e05bd124 100644 (file)
@@ -6,8 +6,14 @@
 
 #include "Model_SelectionNaming.h"
 #include "Model_Document.h"
+#include "Model_Objects.h"
 #include <ModelAPI_Feature.h>
 #include <Events_InfoMessage.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_ResultBody.h>
 
 #include <TopoDS_Iterator.hxx>
 #include <TopoDS.hxx>
@@ -26,6 +32,9 @@
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Localizer.hxx>
 #include <TDataStd_Name.hxx>
+#include <TColStd_MapOfTransient.hxx>
+#include <algorithm>
+#include <stdexcept>
 
 #ifdef DEB_NAMING
 #include <BRepTools.hxx>
@@ -36,9 +45,9 @@ Model_SelectionNaming::Model_SelectionNaming(TDF_Label theSelectionLab)
   myLab = theSelectionLab;
 }
 
-
 std::string Model_SelectionNaming::getShapeName(
-  std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape)
+  std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
+  const bool theAddContextName)
 {
   std::string aName;
   // check if the subShape is already in DF
@@ -47,15 +56,9 @@ std::string Model_SelectionNaming::getShapeName(
   if(!aNS.IsNull() && !aNS->IsEmpty()) { // in the document    
     if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) {
       aName = TCollection_AsciiString(anAttr->Get()).ToCString();
-      if(!aName.empty()) {         
-        const TDF_Label& aLabel = theDoc->findNamingName(aName);
-        /* MPV: the same shape with the same name may be duplicated on different labels (selection of the same construction object)
-        if(!aLabel.IsEqual(aNS->Label())) {
-        //aName.erase(); //something is wrong, to be checked!!!
-        aName += "_SomethingWrong";
-        return aName;
-        }*/
-
+      // indexes are added to sub-shapes not primitives (primitives must not be located at the same label)
+      if(!aName.empty() && aNS->Evolution() != TNaming_PRIMITIVE && theAddContextName) {
+        const TDF_Label& aLabel = aNS->Label();//theDoc->findNamingName(aName);
         static const std::string aPostFix("_");
         TNaming_Iterator anItL(aNS);
         for(int i = 1; anItL.More(); anItL.Next(), i++) {
@@ -65,14 +68,23 @@ std::string Model_SelectionNaming::getShapeName(
             break;
           }
         }
-      }        
+      }
+      if (theAddContextName && aName.find("/") == std::string::npos) { // searching for the context object
+        for(TDF_Label anObjL = aNS->Label(); anObjL.Depth() > 4; anObjL = anObjL.Father()) {
+          int aDepth = anObjL.Depth();
+          if (aDepth == 5 || aDepth == 7) {
+            ObjectPtr anObj = theDoc->objects()->object(anObjL);
+            if (anObj) {
+              aName = anObj->data()->name() + "/" + aName;
+            }
+          }
+        }
+      }
     }
   }
   return aName;
 }
 
-
-
 bool isTrivial (const TopTools_ListOfShape& theAncestors, TopTools_IndexedMapOfShape& theSMap)
 {
   // a trivial case: F1 & F2,  aNumber = 1, i.e. intersection gives 1 edge.
@@ -115,9 +127,17 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
 #endif
   std::shared_ptr<Model_Document> aDoc = 
     std::dynamic_pointer_cast<Model_Document>(theContext->document());
+  if (theContext->groupName() == ModelAPI_ResultPart::group()) {
+    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theContext);
+    int anIndex;
+    return aPart->data()->name() + "/" + aPart->nameInPart(theSubSh, anIndex);
+  }
+
+  // add the result name to the name of the shape (it was in BodyBuilder, but did not work on Result rename)
+  bool isNeedContextName = theContext->shape().get() && !theContext->shape()->isEqual(theSubSh);
 
   // check if the subShape is already in DF
-  aName = getShapeName(aDoc, aSubShape);
+  aName = getShapeName(aDoc, aSubShape, isNeedContextName);
   if(aName.empty() ) { // not in the document!
     TopAbs_ShapeEnum aType = aSubShape.ShapeType();
     switch (aType) {
@@ -126,7 +146,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
       break;
     case TopAbs_EDGE:
       {
-        // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case
+        // name structure: F1 & F2 [& F3 & F4], where F1 & F2 the faces which gives the Edge in trivial case
         // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces     
         if (BRep_Tool::Degenerated(TopoDS::Edge(aSubShape))) {
           aName = "Degenerated_Edge";
@@ -164,7 +184,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
         // build name of the sub-shape Edge
         for(int i=1; i <= aSMap.Extent(); i++) {
           const TopoDS_Shape& aFace = aSMap.FindKey(i);
-          std::string aFaceName = getShapeName(aDoc, aFace);
+          std::string aFaceName = getShapeName(aDoc, aFace, isNeedContextName);
           if(i == 1)
             aName = aFaceName;
           else 
@@ -172,7 +192,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
         }
         TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
         for (;itl.More();itl.Next()) {
-          std::string aFaceName = getShapeName(aDoc, itl.Value());
+          std::string aFaceName = getShapeName(aDoc, itl.Value(), isNeedContextName);
           aName += "&" + aFaceName;
         }                
       }
@@ -221,7 +241,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
             TopTools_ListIteratorOfListOfShape itl(aListE);
             for (int i = 1;itl.More();itl.Next(),i++) {
               const TopoDS_Shape& anEdge = itl.Value();
-              std::string anEdgeName = getShapeName(aDoc, anEdge);
+              std::string anEdgeName = getShapeName(aDoc, anEdge, isNeedContextName);
               if (anEdgeName.empty()) { // edge is not in DS, trying by faces anyway
                 isByFaces = true;
                 aName.clear();
@@ -241,7 +261,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
           TopTools_ListIteratorOfListOfShape itl(aList);
           for (int i = 1;itl.More();itl.Next(),i++) {
             const TopoDS_Shape& aFace = itl.Value();
-            std::string aFaceName = getShapeName(aDoc, aFace);
+            std::string aFaceName = getShapeName(aDoc, aFace, isNeedContextName);
             if(i == 1)
               aName = aFaceName;
             else 
@@ -251,10 +271,8 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
       }
       break;
     }
-    // register name                   
-    // aDoc->addNamingName(selectionLabel(), aName);
-    // the selected sub-shape will not be shared and as result it will not require registration
   }
+
   return aName;
 }
 
@@ -311,9 +329,13 @@ const TopoDS_Shape getShapeFromNS(
   if (n == std::string::npos) n = 0;
   std::string aSubString = theSubShapeName.substr(n + 1);
   n = aSubString.rfind('_');
-  if (n == std::string::npos) return aSelection;
-  aSubString = aSubString.substr(n+1);
-  int indx = atoi(aSubString.c_str());
+  int indx;
+  if (n == std::string::npos) {// for primitives this is a first 
+    indx = 1;
+  } else {
+    aSubString = aSubString.substr(n+1);
+    indx = atoi(aSubString.c_str());
+  }
 
   TNaming_Iterator anItL(theNS);
   for(int i = 1; anItL.More(); anItL.Next(), i++) {
@@ -328,18 +350,19 @@ const TopoDS_Shape findFaceByName(
   const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc)
 {
   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);
-  n = aSubString.rfind('_');
-  if (n != std::string::npos) {
-    std::string aSubStr2 = aSubString.substr(0, n);
-    aSubString  = theSubShapeName.substr(0, nb + 1);
-    aSubString = aSubString + aSubStr2;        
-  } else
-    aSubString = theSubShapeName;
-
-  const TDF_Label& aLabel = theDoc->findNamingName(aSubString);
+  //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);
+  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);
+    }
+  }
   if(aLabel.IsNull()) return aFace;
   Handle(TNaming_NamedShape) aNS;
   if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -450,11 +473,155 @@ std::string getContextName(const std::string& theSubShapeName)
 {
   std::string aName;
   std::string::size_type n = theSubShapeName.find('/');                        
-  if (n == std::string::npos) return aName;
+  if (n == std::string::npos) return theSubShapeName;
   aName = theSubShapeName.substr(0, n);
   return aName;
 }
 
+/// Parses naming name of sketch sub-elements: takes indices and orientation 
+/// (if theOriented = true) from this name. Map theIDs constains indices -> 
+/// orientations and start/end vertices: negative is reversed, 2 - start, 3 - end
+bool parseSubIndices(CompositeFeaturePtr theComp, //< to iterate names
+  const std::string& theName, const char* theShapeType, 
+  std::map<int, int>& theIDs, const bool theOriented = false)
+{
+  // collect all IDs in the name
+  std::map<std::string, int> aNames; // short name of sub -> ID of sub of theComp
+  const int aSubNum = theComp->numberOfSubs();
+  for(int a = 0; a < aSubNum; a++) {
+    FeaturePtr aSub = theComp->subFeature(a);
+    const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+    // there may be many shapes (circle and center)
+    for(; aRes != aResults.cend(); aRes++) {
+      ResultConstructionPtr aConstr = 
+        std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+      if (aConstr.get()) {
+        aNames[Model_SelectionNaming::shortName(aConstr)] = theComp->subFeatureId(a);
+      }
+    }
+  }
+
+  size_t aPrevPos = theName.find("/") + 1, aLastNamePos;
+  bool isShape = false; // anyway the first world must be 'Vertex'
+  do {
+    aLastNamePos = theName.find('-', aPrevPos);
+    std::string anID = theName.substr(aPrevPos, aLastNamePos - aPrevPos);
+    if (!isShape) {
+      if (anID != theShapeType)
+        return false;
+      isShape = true;
+    } else {
+      int anOrientation = 1; // default
+      if (theOriented) { // here must be a symbol in the end of digit 'f' or 'r'
+        std::string::iterator aSymbol = anID.end() - 1;
+        if (*aSymbol == 'r') anOrientation = -1;
+        anID.erase(aSymbol); // remove last symbol
+      }
+      // check start/end symbols
+      std::string::iterator aBack = anID.end() - 1;
+      if (*aBack == 's') {
+        anOrientation *= 2;
+        anID.erase(aBack); // remove last symbol
+      } else if (*aBack == 'e') {
+        anOrientation *= 3;
+        anID.erase(aBack); // remove last symbol
+      }
+
+      if (aNames.find(anID) != aNames.end()) {
+        theIDs[aNames[anID]] = anOrientation;
+      }
+    }
+    aPrevPos = aLastNamePos + 1;
+  } while (aLastNamePos != std::string::npos);
+  return true;
+}
+
+/// produces theEdge orientation relatively to theContext face
+int Model_SelectionNaming::edgeOrientation(const TopoDS_Shape& theContext, TopoDS_Edge& theEdge)
+{
+  if (theContext.ShapeType() != TopAbs_FACE && theContext.ShapeType() != TopAbs_WIRE)
+    return 0;
+  if (theEdge.Orientation() == TopAbs_FORWARD) 
+    return 1;
+  if (theEdge.Orientation() == TopAbs_REVERSED) 
+    return -1;
+  return 0; // unknown
+}
+
+std::shared_ptr<GeomAPI_Shape> Model_SelectionNaming::findAppropriateFace(
+  std::shared_ptr<ModelAPI_Result>& theConstr, 
+  NCollection_DataMap<Handle(Geom_Curve), int>& theCurves)
+{
+  int aBestFound = 0; // best number of found edges (not percentage: issue 1019)
+  int aBestOrient = 0; // for the equal "BestFound" additional parameter is orientation
+  std::shared_ptr<GeomAPI_Shape> aResult;
+  ResultConstructionPtr aConstructionContext = 
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theConstr);
+  if (!aConstructionContext.get())
+    return aResult;
+  for(int aFaceIndex = 0; aFaceIndex < aConstructionContext->facesNum(); aFaceIndex++) {
+    int aFound = 0, aNotFound = 0, aSameOrientation = 0;
+    TopoDS_Face aFace = 
+      TopoDS::Face(aConstructionContext->face(aFaceIndex)->impl<TopoDS_Shape>());
+    TopExp_Explorer anEdgesExp(aFace, TopAbs_EDGE);
+    TColStd_MapOfTransient alreadyProcessed; // to avoid counting edges with same curved (841)
+    for(; anEdgesExp.More(); anEdgesExp.Next()) {
+      TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current());
+      if (!anEdge.IsNull()) {
+        Standard_Real aFirst, aLast;
+        Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+        if (alreadyProcessed.Contains(aCurve))
+          continue;
+        alreadyProcessed.Add(aCurve);
+        if (theCurves.IsBound(aCurve)) {
+          aFound++;
+          int anOrient = theCurves.Find(aCurve);
+          if (anOrient != 0) {  // extra comparision score is orientation
+            if (edgeOrientation(aFace, anEdge) == anOrient)
+              aSameOrientation++;
+          }
+        } else {
+          aNotFound++;
+        }
+      }
+    }
+    if (aFound + aNotFound != 0) {
+      if (aFound > aBestFound || 
+        (aFound == aBestFound && aSameOrientation > aBestOrient)) {
+          aBestFound = aFound;
+          aBestOrient = aSameOrientation;
+          aResult = aConstructionContext->face(aFaceIndex);
+      }
+    }
+  }
+  return aResult;
+}
+
+std::string Model_SelectionNaming::shortName(
+  std::shared_ptr<ModelAPI_ResultConstruction>& theConstr, const int theEdgeVertexPos)
+{
+  std::string aName = theConstr->data()->name();
+  // remove "-", "/" and "&" command-symbols
+  aName.erase(std::remove(aName.begin(), aName.end(), '-'), aName.end());
+  aName.erase(std::remove(aName.begin(), aName.end(), '/'), aName.end());
+  aName.erase(std::remove(aName.begin(), aName.end(), '&'), aName.end());
+  // remove the last 's', 'e', 'f' and 'r' symbols: they are used as markers of start/end/forward/rewersed indicators
+  static const std::string aSyms("sefr");
+  std::string::iterator aSuffix = aName.end() - 1;
+  while(aSyms.find(*aSuffix) != std::string::npos) {
+    --aSuffix;
+  }
+  aName.erase(aSuffix + 1, aName.end());
+
+  if (theEdgeVertexPos == 1) {
+    aName += "s"; // start
+  } else if (theEdgeVertexPos == 2) {
+    aName += "e"; // end
+  }
+  return aName;
+}
+
 // type ::= COMP | COMS | SOLD | SHEL | FACE | WIRE | EDGE | VERT
 bool Model_SelectionNaming::selectSubShape(const std::string& theType, 
   const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
@@ -462,108 +629,277 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
 {
   if(theSubShapeName.empty() || theType.empty()) return false;
   TopAbs_ShapeEnum aType = translateType(theType);
-  std::string aContName = getContextName(theSubShapeName);
+
+  // check that it was selected in another document
+  size_t aSlash = theSubShapeName.find("/");
+  std::string aSubShapeName = theSubShapeName;
+  std::shared_ptr<Model_Document> aDoc = theDoc;
+  if (aSlash != std::string::npos) {
+    std::string aDocName = theSubShapeName.substr(0, aSlash);
+    DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+    if (aDocName == aRootDoc->kind()) {
+      aDoc = std::dynamic_pointer_cast<Model_Document>(aRootDoc);
+    } else {
+      for (int a = aRootDoc->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) {
+        ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(
+            aRootDoc->object(ModelAPI_ResultPart::group(), a));
+        if (aPart.get() && aPart->isActivated() && aPart->data()->name() == aDocName) {
+          aDoc = std::dynamic_pointer_cast<Model_Document>(aPart->partDoc());
+        }
+      }
+    }
+    if (aDoc != theDoc) { // so, the first word is the document name => reduce the string for the next manips
+      aSubShapeName = theSubShapeName.substr(aSlash + 1);
+    }
+  }
+
+  std::string aContName = getContextName(aSubShapeName);
   if(aContName.empty()) return false;
-  ResultPtr aCont = theDoc->findByName(aContName);
-  if(!aCont.get() || aCont->shape()->isNull()) return false;
-  TopoDS_Shape aContext  = aCont->shape()->impl<TopoDS_Shape>();
-  TopAbs_ShapeEnum aContType = aContext.ShapeType();
-  if(aType <= aContType) return false; // not applicable
+  ResultPtr aCont = aDoc->findByName(aContName);
+   // 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
+  if ((!aCont.get()/* || (aCont->groupName() == ModelAPI_ResultBody::group())*/) && 
+       aContName == aSubShapeName) {
+    size_t aPostIndex = aContName.rfind('_');
+    if (aPostIndex != std::string::npos) {
+      std::string aSubContName = aContName.substr(0, aPostIndex);
+      ResultPtr aSubCont = aDoc->findByName(aSubContName);
+      if (aSubCont.get()) {
+        try {
+          std::string aNum = aContName.substr(aPostIndex + 1);
+          aSubShapeId = std::stoi(aNum);
+        } catch (std::invalid_argument&) {
+          aSubShapeId = -1;
+        }
+        if (aSubShapeId > 0) {
+          aContName = aSubContName;
+          aCont = aSubCont;
+        }
+      }
+    }
+  }
 
 
   TopoDS_Shape aSelection;
   switch (aType) 
   {
-  case TopAbs_COMPOUND:
-    break;
-  case TopAbs_COMPSOLID:
-    break;
-  case TopAbs_SOLID:
-    break;
-  case TopAbs_SHELL:
-    break;
   case TopAbs_FACE:
+  case TopAbs_WIRE:
     {
-      const TopoDS_Shape aSelection = findFaceByName(theSubShapeName, theDoc);
-      if(!aSelection.IsNull()) {// Select it
-        std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
-        aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection));
-        theShapeToBeSelected = aShapeToBeSelected;
-        theCont = aCont;
-        return true;
-      }
+      aSelection = findFaceByName(aSubShapeName, aDoc);
     }
     break;
-  case TopAbs_WIRE:
-    break;
   case TopAbs_EDGE:
     {  
-      TopoDS_Shape aSelection;// = findFaceByName(theSubShapeName, aDoc);
-      const TDF_Label& aLabel = theDoc->findNamingName(theSubShapeName);
+      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
-          aSelection = getShapeFromNS(theSubShapeName, aNS);
-        }
-      }
-      if(aSelection.IsNull()) {
-        std::list<std::string> aListofNames;
-        size_t n = ParseName(theSubShapeName, aListofNames);
-        if(n > 1 && n < 5) {
-          TopTools_ListOfShape aList;
-          std::list<std::string>::iterator it =aListofNames.begin();
-          for(;it != aListofNames.end();it++){
-            const TopoDS_Shape aFace = findFaceByName(*it, theDoc);
-            aList.Append(aFace);               
-          }
-          aSelection = findCommonShape(TopAbs_EDGE, aList);
+          aSelection = getShapeFromNS(aSubShapeName, aNS);
         }
       }
-      if(!aSelection.IsNull()) {// Select it
-        std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
-        aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection));
-        theShapeToBeSelected = aShapeToBeSelected;
-        theCont = aCont;
-        return true;
-      }
     }
     break;
   case TopAbs_VERTEX:
     {
-      TopoDS_Shape aSelection;
-      const TDF_Label& aLabel = theDoc->findNamingName(theSubShapeName);
+      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
-          aSelection = getShapeFromNS(theSubShapeName, aNS);
+          aSelection = getShapeFromNS(aSubShapeName, aNS);
         }
       }
-      if(aSelection.IsNull()) {
-        std::list<std::string> aListofNames;
-        size_t n = ParseName(theSubShapeName, aListofNames);
-        if(n > 1 && n < 4) { // 2 || 3
-          TopTools_ListOfShape aList;
-          std::list<std::string>::iterator it = aListofNames.begin();
-          for(; it != aListofNames.end(); it++){
-            const TopoDS_Shape aFace = findFaceByName(*it, theDoc);
-            if(!aFace.IsNull())
-              aList.Append(aFace);             
-          }
-          aSelection = findCommonShape(TopAbs_VERTEX, aList);
-        }
-      }
-      if(!aSelection.IsNull()) {// Select it
-        std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
-        aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection));
-        theShapeToBeSelected = aShapeToBeSelected;
+    }
+    break;
+  case TopAbs_COMPOUND:
+  case TopAbs_COMPSOLID:
+  case TopAbs_SOLID:
+  case TopAbs_SHELL:
+  default: {//TopAbs_SHAPE
+    /// case when the whole sketch is selected, so, selection type is compound, but there is no value
+    if (aCont.get() && aCont->shape().get()) {
+      if (aCont->shape()->impl<TopoDS_Shape>().ShapeType() == aType) {
         theCont = aCont;
         return true;
+      } else if (aSubShapeId > 0) { // try to find sub-shape by the index
+        TopExp_Explorer anExp(aCont->shape()->impl<TopoDS_Shape>(), aType);
+        for(; aSubShapeId > 1 && anExp.More(); aSubShapeId--) {
+          anExp.Next();
+        }
+        if (anExp.More()) {
+          std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+          aShapeToBeSelected->setImpl(new TopoDS_Shape(anExp.Current()));
+          theShapeToBeSelected = aShapeToBeSelected;
+          theCont = aCont;
+          return true;
+        }
       }
     }
-    break;
-  default: //TopAbs_SHAPE
     return false;
+    }
+  }
+  // another try to find edge or vertex by faces
+  std::list<std::string> aListofNames;
+  size_t aN = aSelection.IsNull() ? ParseName(aSubShapeName, aListofNames) : 0;
+  if (aSelection.IsNull() && (aType == TopAbs_EDGE || aType == TopAbs_VERTEX)) {
+    if(aN > 1 && (aN < 4 || (aType == TopAbs_EDGE && aN < 5))) { // 2 || 3 or 4 for EDGE
+      TopTools_ListOfShape aList;
+      std::list<std::string>::iterator it = aListofNames.begin();
+      for(; it != aListofNames.end(); it++){
+        const TopoDS_Shape aFace = findFaceByName(*it, aDoc);
+        if(!aFace.IsNull())
+          aList.Append(aFace);         
+      }
+      aSelection = findCommonShape(aType, aList);
+    }
+  }
+  if (!aSelection.IsNull()) {// Select it
+    std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+    aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection));
+    theShapeToBeSelected = aShapeToBeSelected;
+    theCont = aCont;
+    return true;
+  }
+  // in case of construction, there is no registered names for all sub-elements,
+  // even for the main element; so, trying to find them by name (without "&" intersections)
+  if (aN == 0) {
+    size_t aConstrNamePos = aSubShapeName.find("/");
+    bool isFullName = aConstrNamePos == std::string::npos;
+    std::string aContrName = aContName;
+    ResultPtr aConstr = aDoc->findByName(aContrName);
+    if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
+      theCont = aConstr;
+      if (isFullName) {
+        // For the full construction selection shape must be empty.
+        //theShapeToBeSelected = aConstr->shape();
+        return true;
+      }
+      // for sketch sub-elements selected
+      CompositeFeaturePtr aComposite = 
+        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aDoc->feature(aConstr));
+      if (aComposite.get()) {
+        if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
+          // collect all IDs in the name
+          std::map<int, int> anIDs;
+          if (!parseSubIndices(aComposite, aSubShapeName, 
+              aType == TopAbs_EDGE ? "Edge" : "Vertex", anIDs))
+            return false;
+
+          const int aSubNum = aComposite->numberOfSubs();
+          for(int a = 0; a < aSubNum; a++) {
+            int aCompID = aComposite->subFeatureId(a);
+            if (anIDs.find(aCompID) != anIDs.end()) { // found the vertex/edge shape
+              FeaturePtr aSub = aComposite->subFeature(a);
+              const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+              std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIt = aResults.cbegin();
+              // there may be many shapes (circle and center)
+              for(; aRIt != aResults.cend(); aRIt++) {
+                ResultConstructionPtr aRes = 
+                  std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRIt);
+                if (aRes) {
+                  int anOrientation = abs(anIDs[aCompID]);
+                  TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
+                  if (anOrientation == 1) {
+                    if (aType == aShape.ShapeType()) {
+                      theShapeToBeSelected = aRes->shape();
+                      return true;
+                    }
+                  } else { // take first or second vertex of the edge
+                    TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
+                    TopExp_Explorer anExp(aShape, aType);
+                    for(; anExp.More() && anOrientation != 2; anOrientation--)
+                      anExp.Next();
+                    if (anExp.More()) {
+                      std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+                      aShapeToBeSelected->setImpl(new TopoDS_Shape(anExp.Current()));
+                      theShapeToBeSelected = aShapeToBeSelected;
+                      return true;
+                    }
+                  }
+                }
+              }
+            }
+          }
+          // sketch faces is identified by format "Sketch_1/Face-2f-8f-11r"
+        } else if (aType == TopAbs_FACE || aType == TopAbs_WIRE) {
+          std::map<int, int> anIDs;
+          if (!parseSubIndices(aComposite, aSubShapeName, 
+              aType == TopAbs_FACE ? "Face" : "Wire", anIDs, true))
+            return false;
+
+          NCollection_DataMap<Handle(Geom_Curve), int> allCurves; // curves and orientations of edges
+          const int aSubNum = aComposite->numberOfSubs();
+          for(int a = 0; a < aSubNum; a++) {
+            int aSubID = aComposite->subFeatureId(a);
+            if (anIDs.find(aSubID) != anIDs.end()) {
+              FeaturePtr aSub = aComposite->subFeature(a);
+              const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+              std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes;
+              for(aRes = aResults.cbegin(); aRes != aResults.cend(); aRes++) {
+                ResultConstructionPtr aConstr = 
+                  std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+                if (aConstr->shape() && aConstr->shape()->isEdge()) {
+                  const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+                  TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+                  if (!anEdge.IsNull()) {
+                    Standard_Real aFirst, aLast;
+                    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+                    allCurves.Bind(aCurve, anIDs[aSubID] > 0 ? 1 : -1);
+                  }
+                }
+              }
+            }
+          }
+          std::shared_ptr<GeomAPI_Shape> aFoundFace = findAppropriateFace(aConstr, allCurves);
+          if (aFoundFace.get()) {
+            if (aType == TopAbs_WIRE) { // just get a wire from face to have wire
+              TopExp_Explorer aWireExp(aFoundFace->impl<TopoDS_Shape>(), TopAbs_WIRE);
+              if (aWireExp.More()) {
+                theShapeToBeSelected.reset(new GeomAPI_Shape);
+                theShapeToBeSelected->setImpl<TopoDS_Shape>(new TopoDS_Shape(aWireExp.Current()));
+              } else return false;
+            } else {
+              theShapeToBeSelected = aFoundFace;
+            }
+            return true;
+          }
+        } else if (aType == TopAbs_WIRE) { // sketch faces is identified by format "Sketch_1/Face-2f-8f-11r"
+          std::map<int, int> anIDs;
+          if (!parseSubIndices(aComposite, aSubShapeName, "Wire", anIDs))
+            return false;
+
+          NCollection_DataMap<Handle(Geom_Curve), int> allCurves; // curves and orientations of edges
+          const int aSubNum = aComposite->numberOfSubs();
+          for(int a = 0; a < aSubNum; a++) {
+            int aSubID = aComposite->subFeatureId(a);
+            if (anIDs.find(aSubID) != anIDs.end()) {
+              FeaturePtr aSub = aComposite->subFeature(a);
+              const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+              std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes;
+              for(aRes = aResults.cbegin(); aRes != aResults.cend(); aRes++) {
+                ResultConstructionPtr aConstr = 
+                  std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+                if (aConstr->shape() && aConstr->shape()->isEdge()) {
+                  const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+                  TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+                  if (!anEdge.IsNull()) {
+                    Standard_Real aFirst, aLast;
+                    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+                    allCurves.Bind(aCurve, anIDs[aSubID] > 0 ? 1 : -1);
+                  }
+                }
+              }
+            }
+          }
+          std::shared_ptr<GeomAPI_Shape> aFoundFace = findAppropriateFace(aConstr, allCurves);
+          if (aFoundFace.get()) {
+            theShapeToBeSelected = aFoundFace;
+            return true;
+          }
+        }
+      }
+    }
   }
   return false;
 }
-
index 1ecf4ad42828f2bef21875b565f31bbc50bd9870..82f1eca7a09c028cbdc8e614aed149fc1005bb7f 100644 (file)
@@ -12,6 +12,9 @@
 #include <Model_Document.h>
 #include <TDF_Label.hxx>
 #include <TopoDS_Shape.hxx>
+#include <NCollection_DataMap.hxx>
+#include <Geom_Curve.hxx>
+#include <TopoDS_Edge.hxx>
 
 /**\class Model_SelectionNaming
  * \ingroup DataModel
@@ -39,9 +42,29 @@ public:
     std::shared_ptr<Model_Document> theDoc, std::shared_ptr<GeomAPI_Shape>& theShapeToBeSelected,
     std::shared_ptr<ModelAPI_Result>& theCont);
 
+  /// Searches the face more appropriate to the given curves (with higher level of matched parameters)
+  /// \param theConstr construction result that contains one or several  faces
+  /// \param theCurves map from the face edges curves to orientation (-1 reversed, 0 unknown, 1 forward)
+  /// \returns faces fron this construction if found
+  static std::shared_ptr<GeomAPI_Shape> findAppropriateFace(
+    std::shared_ptr<ModelAPI_Result>& theConstr, 
+    NCollection_DataMap<Handle(Geom_Curve), int>& theCurves);
+
+  /// Returns orientation of the edge in the context shape
+  static int edgeOrientation(const TopoDS_Shape& theContext, TopoDS_Edge& theEdge);
+
+  /// Returns the name of sketch sub-element, shortened by exclusion of some symbols and with added
+  /// the vertex position (if needed)
+  /// \param theConstr result with name - basis for the name
+  /// \param theEdgeVertexPos position of the vertex on edge: 1 - first , 2 - second
+  /// \returns the generated name
+  static std::string shortName(std::shared_ptr<ModelAPI_ResultConstruction>& theConstr,
+    const int theEdgeVertexPos = 0);
+
 protected:
   /// Gets the stored name from the document
-  std::string getShapeName(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape);
+  std::string getShapeName(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
+    const bool theAddContextName);
 };
 
 #endif
index 1f6c8319f6e7950e42d4505e79a2bafee60ca786..c081fbd7079b1dd1691ccb4a116d7452dad0d93e 100755 (executable)
@@ -185,6 +185,7 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
   static const Events_ID kPreviewBlockedEvent = aLoop->eventByName(EVENT_PREVIEW_BLOCKED);
   static const Events_ID kPreviewRequestedEvent = aLoop->eventByName(EVENT_PREVIEW_REQUESTED);
   static const Events_ID kReorderEvent = aLoop->eventByName(EVENT_ORDER_UPDATED);
+  static const Events_ID kRedisplayEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
 
 #ifdef DEB_UPDATE
   std::cout<<"****** Event "<<theMessage->eventID().eventText()<<std::endl;
@@ -212,8 +213,13 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
     const std::set<ObjectPtr>& anObjs = aMsg->objects();
     std::set<ObjectPtr>::const_iterator anObjIter = anObjs.cbegin();
     for(; anObjIter != anObjs.cend(); anObjIter++) {
-      if (std::dynamic_pointer_cast<Model_Document>((*anObjIter)->document())->executeFeatures())
-        ModelAPI_EventCreator::get()->sendUpdated(*anObjIter, kUpdatedEvent);
+      if (std::dynamic_pointer_cast<Model_Document>((*anObjIter)->document())->executeFeatures()) {
+        if ((*anObjIter)->groupName() == ModelAPI_Feature::group()) { // results creation means enabling, not update
+          ModelAPI_EventCreator::get()->sendUpdated(*anObjIter, kUpdatedEvent);
+        } else {
+          ModelAPI_EventCreator::get()->sendUpdated(*anObjIter, kRedisplayEvent);
+        }
+      }
     }
     return;
   }
@@ -296,7 +302,7 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
     // the redisplay signal should be flushed in order to erase the feature presentation in the viewer
     // if should be done after removeFeature() of document,
     // by this reason, upper processFeatures() do not perform this flush
-    Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+    Events_Loop::loop()->flush(kRedisplayEvent);
 
     // in the end of transaction everything is updated, so clear the old objects
     myIsParamUpdated = false;
index efd57540f94c848aca85c6707da89cb253fa8510..4f433271e34bc6ad4bb2f6d03df52ae7c8512509 100644 (file)
@@ -105,3 +105,6 @@ assert(aPln.direction().z() == 0.)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 25f843acf37e3313c333acdaead8a175c4502b5f..491061c9be2b6d83c838351296654d1e2c36171a 100755 (executable)
@@ -149,3 +149,6 @@ assert(aFuse.firstResult().shape().isConnectedTopology() == False)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 14bf232bb49471b50036ce6d386266be157335fc..7ff8a94505c6816b7c53ba99f7d49a111607695d 100644 (file)
@@ -88,3 +88,6 @@ aDoc2.addFeature("Remove")
 aSession.finishOperation()
 assert(aSession.moduleDocument().size("Parts") == 0)
 assert(aSession.activeDocument())
+
+import model
+assert(model.checkPythonDump())
index 6b540f8504a4bd5a9e6b361619ee519b71250773..879e6ef6022cca7d75b9aea790e6255fc6f9835d 100755 (executable)
@@ -21,9 +21,13 @@ aSession = ModelAPI_Session.get()
 aPartSet = aSession.moduleDocument()
 aSession.startOperation()
 aSketchFeature = featureToCompositeFeature(aPartSet.addFeature("Sketch"))
+aXOYPlane = objectToResult(aPartSet.objectByName("Construction", "XOY"))
+aSketchFeature.selection("External").setValue(aXOYPlane, None)
 aFeatureData = aSketchFeature.data()
 anArray = aFeatureData.addAttribute("IntArray_1", "IntArray")
 aFeatureData.intArray("IntArray_1").setSize(5)
+aSession.finishOperation()
+
 assert(aFeatureData.intArray("IntArray_1").size() == 5)
 
 #=========================================================================
index 7ba9cb5eaf234de5d026d5d8ee53cfc1e16e21bc..b7e928d57d2d76372b39e2d03968b03303f7e51c 100755 (executable)
@@ -17,9 +17,17 @@ aSession = ModelAPI_Session.get()
 #=========================================================================
 aPartSet = aSession.moduleDocument()
 aSession.startOperation()
-aPlaneX = aPartSet.objectByName("Construction", "YOZ");
+aPlaneX = aPartSet.addFeature("Plane")
+aPlaneX.string("creation_method").setValue("by_general_equation")
+aPlaneX.real("A").setValue(1.)
+aPlaneX.real("B").setValue(0.)
+aPlaneX.real("C").setValue(0.)
+aPlaneX.real("D").setValue(0.)
 assert(aPlaneX)
-aColors = aPlaneX.data().intArray("Color")
+aSession.finishOperation()
+
+aSession.startOperation()
+aColors = aPlaneX.lastResult().data().intArray("Color")
 assert(aColors)
 # default colors, not filled array
 assert(aColors.size() == 0)
@@ -31,6 +39,7 @@ assert(aColors.size() == 3)
 assert(aColors.value(0) == 100)
 assert(aColors.value(1) == 200)
 assert(aColors.value(2) == 250)
-
 aSession.finishOperation()
 
+import model
+assert(model.checkPythonDump())
index 2f86fbefc8f45719d2f9b421f5eee433153a5a46..3981f30d4f257df0c4604ce52f1cdb38ceefd727 100644 (file)
@@ -32,3 +32,6 @@ aSession.redo()
 assert(aDoc.size("Construction") == 8)\r
 assert(aSession.canUndo())\r
 assert(not aSession.canRedo())\r
+\r
+import model\r
+assert(model.checkPythonDump())\r
index c0344eab22410c05fcef344bf4947c1520d2413f..b43279ad5b058fb86d7dff8a86036e131cc5c7b4 100755 (executable)
@@ -15,3 +15,6 @@ from ModelGeomAlgo import *
 __updated__ = "2016-07-20"
 
 aSession = ModelAPI_Session.get()
+
+import model
+assert(model.checkPythonDump())
index dfd97daaf3479d08a7c7adc122a600755cd88bb6..a5280ec4ecc1879e47d7e02706c8fbd721845fbf 100644 (file)
@@ -5,6 +5,7 @@ INCLUDE(Common)
 SET(PROJECT_HEADERS
   ModelHighAPI.h
   ModelHighAPI_Double.h
+  ModelHighAPI_Dumper.h
   ModelHighAPI_Integer.h
   ModelHighAPI_Interface.h
   ModelHighAPI_Macro.h
@@ -13,10 +14,12 @@ SET(PROJECT_HEADERS
   ModelHighAPI_Selection.h
   ModelHighAPI_Services.h
   ModelHighAPI_Tools.h
+  ModelHighAPI_FeatureStore.h
 )
 
 SET(PROJECT_SOURCES
   ModelHighAPI_Double.cpp
+  ModelHighAPI_Dumper.cpp
   ModelHighAPI_Integer.cpp
   ModelHighAPI_Interface.cpp
   ModelHighAPI_RefAttr.cpp
@@ -24,6 +27,7 @@ SET(PROJECT_SOURCES
   ModelHighAPI_Selection.cpp
   ModelHighAPI_Services.cpp
   ModelHighAPI_Tools.cpp
+  ModelHighAPI_FeatureStore.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -31,10 +35,11 @@ SET(PROJECT_LIBRARIES
   Events
   GeomAPI
   GeomDataAPI
+  GeomAlgoAPI
   ModelAPI
 )
 
-ADD_DEFINITIONS(-DMODELHIGHAPI_EXPORTS)
+ADD_DEFINITIONS(-DMODELHIGHAPI_EXPORTS -DWNT)
 ADD_LIBRARY(ModelHighAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
 #TODO(spo): is it necessary?
 SET_TARGET_PROPERTIES(ModelHighAPI PROPERTIES LINKER_LANGUAGE CXX)
@@ -53,10 +58,14 @@ SET(SWIG_LINK_LIBRARIES
 )
 
 INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}/src/Config
   ${PROJECT_SOURCE_DIR}/src/Events
   ${PROJECT_SOURCE_DIR}/src/GeomAPI
+  ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
   ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
   ${PROJECT_SOURCE_DIR}/src/ModelAPI
+  ${PROJECT_SOURCE_DIR}/src/PartSetPlugin
+  ${CAS_INCLUDE_DIRS}
 )
 
 set(SWIG_MODULE_ModelHighAPI_EXTRA_DEPS
index 1dd6be785468439f60bae52811ee3e1bbb777ca8..2ad5dc461571a9b09b04abed28a3e974c014463a 100644 (file)
@@ -1,5 +1,12 @@
 /* ModelHighAPI.i */
-%module ModelHighAPI
+%module(directors="1") ModelHighAPI
+%feature("director:except") {
+    if ($error != NULL) {
+      PyErr_Print();
+      std::cerr << std::endl;
+      throw Swig::DirectorMethodException();
+    }
+}
 
 %{
   #include "ModelHighAPI_swig.h"
@@ -24,6 +31,9 @@
 %include "std_string.i"
 %include "std_shared_ptr.i"
 
+// directors
+%feature("director") ModelHighAPI_Dumper;
+
 // shared pointers
 %shared_ptr(ModelHighAPI_Interface)
 
   }
 }
 
+%typecheck(SWIG_TYPECHECK_POINTER) ModelHighAPI_RefAttr, const ModelHighAPI_RefAttr & {
+  std::shared_ptr<ModelAPI_Attribute> * temp_attribute;
+  std::shared_ptr<ModelAPI_Object> * temp_object;
+  std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
+  int newmem = 0;
+  if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_attribute, $descriptor(std::shared_ptr<ModelAPI_Attribute> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (temp_attribute) {
+      $1 = 1;
+    } else {
+      $1 = 0;
+    }
+  } else if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_object, $descriptor(std::shared_ptr<ModelAPI_Object> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (temp_object) {
+      $1 = 1;
+    } else {
+      $1 = 0;
+    }
+  } else if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_interface, $descriptor(std::shared_ptr<ModelHighAPI_Interface> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (temp_interface) {
+      $1 = 1;
+    } else {
+      $1 = 0;
+    }
+  } else {
+    $1 = 0;
+  }
+}
+
 %typemap(in) const ModelHighAPI_Reference & (ModelHighAPI_Reference temp) {
   std::shared_ptr<ModelAPI_Object> * temp_object;
   std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
 %template(RefAttrList) std::list<ModelHighAPI_RefAttr>;
 %template(RefList) std::list<ModelHighAPI_Reference>;
 
+// fix compilarion error: â€˜res*’ was not declared in this scope
+%typemap(freearg) const std::list<ModelHighAPI_RefAttr> & {}
+%typemap(freearg) const std::list<std::shared_ptr<ModelAPI_Object> > & {}
+
+%typemap(in) const std::list<ModelHighAPI_RefAttr> & (std::list<ModelHighAPI_RefAttr> temp) {
+  std::shared_ptr<ModelAPI_Attribute> * temp_attribute;
+  int newmem = 0;
+  if (PySequence_Check($input)) {
+    for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+      PyObject * item = PySequence_GetItem($input, i);
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_attribute, $descriptor(std::shared_ptr<ModelAPI_Attribute> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_attribute) {
+          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_RefAttr, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+          return NULL;
+        }
+        temp.push_back(ModelHighAPI_RefAttr(*temp_attribute));
+        if (newmem & SWIG_CAST_NEW_MEMORY) {
+          delete temp_attribute;
+        }
+      }
+      Py_DECREF(item);
+    }
+    $1 = &temp;
+  } else {
+    PyErr_SetString(PyExc_ValueError, "argument must be list of ModelHighAPI_RefAttr, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+    return NULL;
+  }
+}
+
+%typemap(in) const std::list<std::shared_ptr<ModelAPI_Object> > & (std::list<std::shared_ptr<ModelAPI_Object> > temp) {
+  std::shared_ptr<ModelAPI_Object> * temp_object;
+  std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
+  int newmem = 0;
+  if (PySequence_Check($input)) {
+    for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+      PyObject * item = PySequence_GetItem($input, i);
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_object, $descriptor(std::shared_ptr<ModelAPI_Object> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_object) {
+          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_Interface or ModelAPI_Object.");
+          return NULL;
+        }
+        temp.push_back(*temp_object);
+        if (newmem & SWIG_CAST_NEW_MEMORY) {
+          delete temp_object;
+        }
+      } else
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_interface, $descriptor(std::shared_ptr<ModelHighAPI_Interface> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_interface) {
+          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_Interface or ModelAPI_Object.");
+          return NULL;
+        }
+        temp.push_back((*temp_interface)->defaultResult());
+        if (newmem & SWIG_CAST_NEW_MEMORY) {
+          delete temp_interface;
+        }
+      }
+      Py_DECREF(item);
+    }
+    $1 = &temp;
+  } else {
+    PyErr_SetString(PyExc_ValueError, "argument must be list of ModelHighAPI_Interface or ModelAPI_Object.");
+    return NULL;
+  }
+}
+
+%typecheck(SWIG_TYPECHECK_POINTER) std::list<std::shared_ptr<ModelAPI_Object> >, const std::list<std::shared_ptr<ModelAPI_Object> >& {
+  std::shared_ptr<ModelAPI_Object> * temp_object;
+  std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
+  int newmem = 0;
+  if (PySequence_Check($input)) {
+    for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+      PyObject * item = PySequence_GetItem($input, i);
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_object, $descriptor(std::shared_ptr<ModelAPI_Object> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (temp_object) {
+          $1 = 1;
+        } else {
+          $1 = 0;
+          break;
+        }
+      } else
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_interface, $descriptor(std::shared_ptr<ModelHighAPI_Interface> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (temp_interface) {
+          $1 = 1;
+        } else {
+          $1 = 0;
+          break;
+        }
+      }
+      Py_DECREF(item);
+    }
+  } else {
+    $1 = 0;
+  }
+}
+
 // all supported interfaces
 %include "ModelHighAPI_Double.h"
+%include "ModelHighAPI_Dumper.h"
 %include "ModelHighAPI_Integer.h"
 %include "ModelHighAPI_Interface.h"
 %include "ModelHighAPI_RefAttr.h"
diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp
new file mode 100644 (file)
index 0000000..fe2875f
--- /dev/null
@@ -0,0 +1,785 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
+
+// File:        ModelHighAPI_Dumper.cpp
+// Created:     1 August 2016
+// Author:      Artem ZHIDKOV
+
+//--------------------------------------------------------------------------------------
+#include "ModelHighAPI_Dumper.h"
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Dir.h>
+
+#include <GeomDataAPI_Dir.h>
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Point2D.h>
+
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefAttrList.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Entity.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Result.h>
+#include <ModelAPI_ResultPart.h>
+
+#include <PartSetPlugin_Part.h>
+
+#include <OSD_OpenFile.hxx>
+
+#include <fstream>
+
+static int gCompositeStackDepth = 0;
+
+ModelHighAPI_Dumper* ModelHighAPI_Dumper::mySelf = 0;
+
+ModelHighAPI_Dumper::ModelHighAPI_Dumper()
+{
+  clear();
+}
+
+void ModelHighAPI_Dumper::setInstance(ModelHighAPI_Dumper* theDumper)
+{
+  if (mySelf == 0)
+    mySelf = theDumper;
+}
+
+ModelHighAPI_Dumper* ModelHighAPI_Dumper::getInstance()
+{
+  return mySelf;
+}
+
+void ModelHighAPI_Dumper::clear(bool bufferOnly)
+{
+  myDumpBuffer.str("");
+  myDumpBuffer << std::setprecision(16);
+
+  clearNotDumped();
+
+  if (!bufferOnly) {
+    myFullDump.str("");
+    myFullDump << std::setprecision(16);
+
+    myNames.clear();
+    myModules.clear();
+    myFeatureCount.clear();
+    while (!myEntitiesStack.empty())
+      myEntitiesStack.pop();
+  }
+}
+
+void ModelHighAPI_Dumper::clearNotDumped()
+{
+  myNotDumpedEntities.clear();
+}
+
+const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity,
+                                             bool theSaveNotDumped,
+                                             bool theUseEntityName)
+{
+  EntityNameMap::const_iterator aFound = myNames.find(theEntity);
+  if (aFound != myNames.end())
+    return aFound->second.myCurrentName;
+
+  // entity is not found, store it
+  std::string aName;
+  bool isDefaultName = false;
+  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();
+    int& aNbFeatures = myFeatureCount[aDoc][aKind];
+    aNbFeatures += 1;
+
+    size_t anIndex = aName.find(aKind);
+    if (anIndex == 0 && aName[aKind.length()] == '_') { // name starts with "FeatureKind_"
+      std::string anIdStr = aName.substr(aKind.length() + 1);
+      int anId = std::stoi(anIdStr);
+
+      // Check number of already registered objects of such kind. Index of current object
+      // should be the same to identify feature's name as automatically generated.
+      if (aNbFeatures == anId) {
+        // name is not user-defined
+        aName.clear();
+        isDefaultName = true;
+      }
+    }
+
+    // obtain default name for the feature
+    if (theUseEntityName)
+      aDefaultName << aName;
+    else {
+      int aFullIndex = 0;
+      NbFeaturesMap::const_iterator aFIt = myFeatureCount.begin();
+      for (; aFIt != myFeatureCount.end(); ++aFIt) {
+        std::map<std::string, int>::const_iterator aFound = aFIt->second.find(aKind);
+        if (aFound != aFIt->second.end())
+          aFullIndex += aFound->second;
+      }
+      aDefaultName << aKind << "_" << aFullIndex;
+    }
+  }
+
+  myNames[theEntity] = EntityName(aDefaultName.str(), aName, isDefaultName);
+  if (theSaveNotDumped)
+    myNotDumpedEntities.insert(theEntity);
+
+  // store names of results
+  if (aFeature)
+    saveResultNames(aFeature);
+
+  return myNames[theEntity].myCurrentName;
+}
+
+const std::string& ModelHighAPI_Dumper::parentName(const FeaturePtr& theEntity)
+{
+  const std::set<AttributePtr>& aRefs = theEntity->data()->refsToMe();
+  std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
+  for (; aRefIt != aRefs.end(); ++aRefIt) {
+    CompositeFeaturePtr anOwner = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(
+        ModelAPI_Feature::feature((*aRefIt)->owner()));
+    if (anOwner)
+      return name(anOwner);
+  }
+
+  static const std::string DUMMY;
+  return DUMMY;
+}
+
+void ModelHighAPI_Dumper::saveResultNames(const FeaturePtr& theFeature)
+{
+  const std::string& aFeatureName = myNames[theFeature].myCurrentName;
+  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;
+    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;
+      }
+    }
+
+    myNames[*aResIt] = EntityName(aResName,
+        (isUserDefined ? aResName : std::string()), !isUserDefined);
+  }
+}
+
+bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc,
+                                  const std::string& theFileName)
+{
+  // dump top level document feature
+  static const std::string aDocName("partSet");
+  myNames[theDoc] = EntityName(aDocName, std::string(), true);
+  *this << aDocName << " = model.moduleDocument()" << std::endl;
+
+  // dump subfeatures and store result to file
+  return process(theDoc) && exportTo(theFileName);
+}
+
+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();
+  // firstly, dump all parameters
+  for (; aFeatIt != aFeatures.end(); ++ aFeatIt)
+    dumpParameter(*aFeatIt);
+  // dump all other features
+  for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) {
+    CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
+    if (aCompFeat) // iteratively process composite features
+      isOk = process(aCompFeat) && isOk;
+    else if (!isDumped(*aFeatIt)) // dump common feature 
+      dumpFeature(*aFeatIt);
+  }
+  return isOk;
+}
+
+bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite, bool isForce)
+{
+  // increase composite features stack
+  ++gCompositeStackDepth;
+  // dump composite itself
+  if (!isDumped(theComposite) || isForce)
+    dumpFeature(theComposite, isForce);
+
+  // sub-part is processed independently, because it provides separate document
+  if (theComposite->getKind() == PartSetPlugin_Part::ID()) {
+    // decrease composite features stack because we run into separate document
+    --gCompositeStackDepth;
+
+    ResultPartPtr aPartResult =
+        std::dynamic_pointer_cast<ModelAPI_ResultPart>(theComposite->lastResult());
+    if (!aPartResult)
+      return false;
+    DocumentPtr aSubDoc = aPartResult->partDoc();
+    if (!aSubDoc)
+      return false;
+    // set name of document
+    const std::string& aPartName = myNames[theComposite].myCurrentName;
+    std::string aDocName = aPartName + "_doc";
+    myNames[aSubDoc] = EntityName(aDocName, std::string(), true);
+
+    // dump document in a separate line
+    *this << aDocName << " = " << aPartName << ".document()" << std::endl;
+    // dump features in the document
+    return process(aSubDoc);
+  }
+
+  // dump sub-features
+  bool isOk = processSubs(theComposite);
+  // decrease composite features stack
+  --gCompositeStackDepth;
+
+  return isOk;
+}
+
+bool ModelHighAPI_Dumper::processSubs(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite,
+                                      bool theDumpModelDo)
+{
+  bool isOk = true;
+  // dump all sub-features;
+  bool isSubDumped = false;
+  int aNbSubs = theComposite->numberOfSubs();
+  for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
+    FeaturePtr aFeature = theComposite->subFeature(anIndex);
+    if (isDumped(aFeature))
+      continue;
+
+    isSubDumped = true;
+    CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+    if (aCompFeat) // iteratively process composite features
+      isOk = process(aCompFeat) && isOk;
+    else
+      dumpFeature(aFeature, true);
+  }
+
+  bool isDumpSetName = !myEntitiesStack.empty() &&
+      myEntitiesStack.top().myEntity == EntityPtr(theComposite);
+  bool isForceModelDo = isSubDumped && isDumpSetName &&
+      (myEntitiesStack.top().myUserName || !myEntitiesStack.top().myResults.empty());
+  // It is necessary for the sketch to create its result when complete (command "model.do()").
+  // This option is set by flat theDumpModelDo.
+  // However, nested sketches are rebuilt by parent feature, so, they do not need
+  // explicit call of "model.do()". This will be controlled by the depth of the stack.
+  if (isForceModelDo || (theDumpModelDo && gCompositeStackDepth <= 1))
+    *this << "model.do()" << std::endl;
+
+  // dump "setName" for composite feature
+  if (isDumpSetName)
+    dumpEntitySetName();
+  return isOk;
+}
+
+void ModelHighAPI_Dumper::dumpSubFeatureNameAndColor(const std::string theSubFeatureGet,
+                                                     const FeaturePtr& theSubFeature)
+{
+  name(theSubFeature, false);
+  myNames[theSubFeature] = EntityName(theSubFeatureGet, theSubFeature->name(), false);
+
+  // store results if they have user-defined names or colors
+  std::list<ResultPtr> aResultsWithNameOrColor;
+  const std::list<ResultPtr>& aResults = theSubFeature->results();
+  std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
+  for (; aResIt != aResults.end(); ++aResIt) {
+    std::string aResName = (*aResIt)->data()->name();
+    myNames[*aResIt] = EntityName(aResName, aResName, false);
+    aResultsWithNameOrColor.push_back(*aResIt);
+  }
+
+  // store just dumped entity to stack
+  myEntitiesStack.push(LastDumpedEntity(theSubFeature, true, aResultsWithNameOrColor));
+
+  dumpEntitySetName();
+}
+
+bool ModelHighAPI_Dumper::exportTo(const std::string& theFileName)
+{
+  std::ofstream aFile;
+  OSD_OpenStream(aFile, theFileName.c_str(), std::ofstream::out);
+  if (!aFile.is_open())
+    return false;
+
+  // standard header
+  for (ModulesMap::const_iterator aModIt = myModules.begin();
+       aModIt != myModules.end(); ++aModIt) {
+    aFile << "from " << aModIt->first << " import ";
+    if (aModIt->second.empty() || 
+        aModIt->second.find(std::string()) != aModIt->second.end())
+      aFile << "*"; // import whole module
+    else {
+      // import specific features
+      std::set<std::string>::const_iterator anObjIt = aModIt->second.begin();
+      aFile << *anObjIt;
+      for (++anObjIt; anObjIt != aModIt->second.end(); ++anObjIt)
+        aFile << ", " << *anObjIt;
+    }
+    aFile << std::endl;
+  }
+  if (!myModules.empty())
+    aFile << std::endl;
+
+  aFile << "import model" << std::endl << std::endl;
+  aFile << "model.begin()" << std::endl;
+
+  // dump collected data
+  aFile << myFullDump.str();
+  aFile << myDumpBuffer.str();
+
+  // standard footer
+  aFile << "model.end()" << std::endl;
+
+  aFile.close();
+  clear();
+
+  return true;
+}
+
+void ModelHighAPI_Dumper::importModule(const std::string& theModuleName,
+                                       const std::string& theObject)
+{
+  myModules[theModuleName].insert(theObject);
+}
+
+void ModelHighAPI_Dumper::dumpEntitySetName()
+{
+  const LastDumpedEntity& aLastDumped = myEntitiesStack.top();
+
+  // dump "setName" for the entity
+  if (aLastDumped.myUserName) {
+    EntityName& anEntityNames = myNames[aLastDumped.myEntity];
+    if (!anEntityNames.myIsDefault)
+      myDumpBuffer << anEntityNames.myCurrentName << ".setName(\""
+                   << anEntityNames.myUserName << "\")" << std::endl;
+    // don't dump "setName" for the entity twice
+    anEntityNames.myUserName.clear();
+    anEntityNames.myIsDefault = true;
+  }
+  // dump "setName" for results
+  std::list<ResultPtr>::const_iterator aResIt = aLastDumped.myResults.begin();
+  std::list<ResultPtr>::const_iterator aResEnd = aLastDumped.myResults.end();
+  for (; aResIt != aResEnd; ++aResIt) {
+    // set result name
+    EntityName& anEntityNames = myNames[*aResIt];
+    if (!anEntityNames.myIsDefault) {
+      *this << *aResIt;
+      myDumpBuffer << ".setName(\"" << anEntityNames.myUserName << "\")" << std::endl;
+      // don't dump "setName" for the entity twice
+      anEntityNames.myUserName.clear();
+      anEntityNames.myIsDefault = true;
+    }
+    // set result color
+    if (!isDefaultColor(*aResIt)) {
+      AttributeIntArrayPtr aColor = (*aResIt)->data()->intArray(ModelAPI_Result::COLOR_ID());
+      if (aColor && aColor->isInitialized()) {
+        *this << *aResIt;
+        myDumpBuffer << ".setColor(" << aColor->value(0) << ", " << aColor->value(1)
+                     << ", " << aColor->value(2) << ")" << std::endl;
+      }
+    }
+  }
+
+  myEntitiesStack.pop();
+}
+
+bool ModelHighAPI_Dumper::isDumped(const EntityPtr& theEntity) const
+{
+  EntityNameMap::const_iterator aFound = myNames.find(theEntity);
+  return aFound != myNames.end();
+}
+
+bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const
+{
+  AttributeIntArrayPtr aColor = theResult->data()->intArray(ModelAPI_Result::COLOR_ID());
+  if (!aColor || !aColor->isInitialized())
+    return true;
+
+  std::string aSection, aName, aDefault;
+  theResult->colorConfigInfo(aSection, aName, aDefault);
+
+  // dump current color
+  std::ostringstream aColorInfo;
+  aColorInfo << aColor->value(0) << "," << aColor->value(1) << "," << aColor->value(2);
+
+  return aDefault == aColorInfo.str();
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char theChar)
+{
+  myDumpBuffer << theChar;
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char* theString)
+{
+  myDumpBuffer << theString;
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const std::string& theString)
+{
+  myDumpBuffer << theString;
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const bool theValue)
+{
+  myDumpBuffer << (theValue ? "True" : "False");
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const int theValue)
+{
+  myDumpBuffer << theValue;
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const double theValue)
+{
+  myDumpBuffer << theValue;
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const std::shared_ptr<GeomAPI_Pnt>& thePoint)
+{
+  importModule("GeomAPI", "GeomAPI_Pnt");
+  myDumpBuffer << "GeomAPI_Pnt(" << thePoint->x() << ", "
+               << thePoint->y() << ", " << thePoint->z() << ")";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const std::shared_ptr<GeomAPI_Dir>& theDir)
+{
+  importModule("GeomAPI", "GeomAPI_Dir");
+  myDumpBuffer << "GeomAPI_Dir(" << theDir->x() << ", "
+               << theDir->y() << ", " << theDir->z() << ")";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<GeomDataAPI_Dir>& theDir)
+{
+  myDumpBuffer << theDir->x() << ", " << theDir->y() << ", " << theDir->z();
+  return *this;
+}
+
+static void dumpArray(std::ostringstream& theOutput, int theSize,
+                      double* theValues, std::string* theTexts)
+{
+  for (int i = 0; i < theSize; ++i) {
+    if (i > 0)
+      theOutput << ", ";
+    if (theTexts[i].empty())
+      theOutput << theValues[i];
+    else
+      theOutput << "\"" << theTexts[i] << "\"";
+  }
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<GeomDataAPI_Point>& thePoint)
+{
+  static const int aSize = 3;
+  double aValues[aSize] = {thePoint->x(), thePoint->y(), thePoint->z()};
+  std::string aTexts[aSize] = {thePoint->textX(), thePoint->textY(), thePoint->textZ()};
+  dumpArray(myDumpBuffer, aSize, aValues, aTexts);
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<GeomDataAPI_Point2D>& thePoint)
+{
+  static const int aSize = 2;
+  double aValues[aSize] = {thePoint->x(), thePoint->y()};
+  std::string aTexts[aSize] = {thePoint->textX(), thePoint->textY()};
+  dumpArray(myDumpBuffer, aSize, aValues, aTexts);
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeBoolean>& theAttrBool)
+{
+  myDumpBuffer << (theAttrBool->value() ? "True" : "False");
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeInteger>& theAttrInt)
+{
+  std::string aText = theAttrInt->text();
+  if (aText.empty())
+    myDumpBuffer << theAttrInt->value();
+  else
+    myDumpBuffer << "\"" << aText << "\"";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeDouble>& theAttrReal)
+{
+  std::string aText = theAttrReal->text();
+  if (aText.empty())
+    myDumpBuffer << theAttrReal->value();
+  else
+    myDumpBuffer << "\"" << aText << "\"";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeString>& theAttrStr)
+{
+  myDumpBuffer << "\"" << theAttrStr->value() << "\"";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity)
+{
+  myDumpBuffer << name(theEntity);
+
+  bool isUserDefinedName = !myNames[theEntity].myIsDefault;
+  // store results if they have user-defined names or colors
+  std::list<ResultPtr> aResultsWithNameOrColor;
+  const std::list<ResultPtr>& aResults = theEntity->results();
+  std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
+  for (; aResIt != aResults.end(); ++aResIt)
+    if (!myNames[*aResIt].myIsDefault || !isDefaultColor(*aResIt))
+      aResultsWithNameOrColor.push_back(*aResIt);
+  // store just dumped entity to stack
+  myEntitiesStack.push(LastDumpedEntity(theEntity, isUserDefinedName, aResultsWithNameOrColor));
+
+  // remove entity from the list of not dumped items
+  myNotDumpedEntities.erase(theEntity);
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const ResultPtr& theResult)
+{
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theResult);
+  int anIndex = 0;
+  std::list<ResultPtr> aResults = aFeature->results();
+  for(std::list<ResultPtr>::const_iterator anIt = aResults.cbegin(); anIt != aResults.cend(); ++anIt, ++anIndex) {
+    if(theResult->isSame(*anIt)) {
+      break;
+    }
+  }
+  myDumpBuffer << name(aFeature) << ".result()[" << anIndex << "]";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const ObjectPtr& theObject)
+{
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+  if(aFeature.get()) {
+    myDumpBuffer << name(aFeature);
+    return *this;
+  }
+
+  ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+  if(aResult.get()) {
+    *this << aResult;
+    return *this;
+  }
+
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const AttributePtr& theAttr)
+{
+  FeaturePtr anOwner = ModelAPI_Feature::feature(theAttr->owner());
+  myDumpBuffer << name(anOwner) << "." << attributeGetter(anOwner, theAttr->id()) << "()";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeRefAttr>& theRefAttr)
+{
+  if (theRefAttr->isObject())
+    *this << theRefAttr->object();
+  else
+    *this << theRefAttr->attr();
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeRefAttrList>& theRefAttrList)
+{
+  myDumpBuffer << "[";
+  std::list<std::pair<ObjectPtr, AttributePtr> > aList = theRefAttrList->list();
+  bool isAdded = false;
+  std::list<std::pair<ObjectPtr, AttributePtr> >::const_iterator anIt = aList.begin();
+  for (; anIt != aList.end(); ++anIt) {
+    if (isAdded)
+      myDumpBuffer << ", ";
+    else
+      isAdded = true;
+    if (anIt->first)
+      *this << anIt->first;
+    else if (anIt->second)
+      * this << anIt->second;
+  }
+  myDumpBuffer << "]";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeReference>& theReference)
+{
+  *this << theReference->value();
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeRefList>& theRefList)
+{
+  static const int aThreshold = 2;
+  // if number of elements in the list if greater than a threshold,
+  // dump it in a separate line with specific name
+  std::string aDumped = myDumpBuffer.str();
+  if (aDumped.empty() || theRefList->size() <= aThreshold) {
+    myDumpBuffer << "[";
+    std::list<ObjectPtr> aList = theRefList->list();
+    bool isAdded = false;
+    std::list<ObjectPtr>::const_iterator anIt = aList.begin();
+    for (; anIt != aList.end(); ++anIt) {
+      if (isAdded)
+        myDumpBuffer << ", ";
+      else
+        isAdded = true;
+
+      *this << *anIt;
+    }
+    myDumpBuffer << "]";
+  } else {
+    // clear buffer and store list "as is"
+    myDumpBuffer.str("");
+    *this << theRefList;
+    // save buffer and clear it again
+    std::string aDumpedList = myDumpBuffer.str();
+    myDumpBuffer.str("");
+    // obtain name of list
+    FeaturePtr anOwner = ModelAPI_Feature::feature(theRefList->owner());
+    std::string aListName = name(anOwner) + "_objects";
+    // store all previous data
+    myDumpBuffer << aListName << " = " << aDumpedList << std::endl
+                 << aDumped << aListName;
+  }
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeSelection>& theAttrSelect)
+{
+  myDumpBuffer << "model.selection(";
+
+  if(!theAttrSelect->isInitialized()) {
+    myDumpBuffer << ")";
+    return *this;
+  }
+
+  GeomShapePtr aShape = theAttrSelect->value();
+  if(!aShape.get()) {
+    aShape = theAttrSelect->context()->shape();
+  }
+
+  if(!aShape.get()) {
+    myDumpBuffer << ")";
+    return *this;
+  }
+
+  myDumpBuffer << "\"" << aShape->shapeTypeStr() << "\", \"" << theAttrSelect->namingName() << "\")";
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeSelectionList>& theAttrSelList)
+{
+  myDumpBuffer << "[";
+
+  GeomShapePtr aShape;
+  std::string aShapeTypeStr;
+
+  bool isAdded = false;
+
+  for(int anIndex = 0; anIndex < theAttrSelList->size(); ++anIndex) {
+    AttributeSelectionPtr anAttribute = theAttrSelList->value(anIndex);
+    aShape = anAttribute->value();
+    if(!aShape.get()) {
+      aShape = anAttribute->context()->shape();
+    }
+
+    if(!aShape.get()) {
+      continue;
+    }
+
+    if(isAdded) {
+      myDumpBuffer << ", ";
+    } else {
+      isAdded = true;
+    }
+    myDumpBuffer << "model.selection(\"" << aShape->shapeTypeStr() << "\", \"" << anAttribute->namingName() << "\")";
+  }
+
+  myDumpBuffer << "]";
+  return *this;
+}
+
+/// Dump std::endl
+MODELHIGHAPI_EXPORT
+ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
+                                std::basic_ostream<char>& (*theEndl)(std::basic_ostream<char>&))
+{
+  theDumper.myDumpBuffer << theEndl;
+
+  if (!theDumper.myEntitiesStack.empty()) {
+    // Name for composite feature is dumped when all sub-entities are dumped
+    // (see method ModelHighAPI_Dumper::processSubs).
+    const ModelHighAPI_Dumper::LastDumpedEntity& aLastDumped = theDumper.myEntitiesStack.top();
+    CompositeFeaturePtr aComposite =
+        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aLastDumped.myEntity);
+    if (!aComposite)
+      theDumper.dumpEntitySetName();
+  }
+
+  // store all not-dumped entities first
+  std::set<EntityPtr> aNotDumped = theDumper.myNotDumpedEntities;
+  std::string aBufCopy = theDumper.myDumpBuffer.str();
+  theDumper.clear(true);
+  std::set<EntityPtr>::const_iterator anIt = aNotDumped.begin();
+  for (; anIt != aNotDumped.end(); ++anIt) {
+    // if the feature is composite, dump it with all subs
+    CompositeFeaturePtr aCompFeat =
+        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*anIt);
+    if (aCompFeat)
+      theDumper.process(aCompFeat, true);
+    else {
+      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
+      theDumper.dumpFeature(aFeature, true);
+    }
+  }
+
+  // avoid multiple empty lines
+  size_t anInd = std::string::npos;
+  while ((anInd = aBufCopy.find("\n\n\n")) != std::string::npos)
+    aBufCopy.erase(anInd, 1);
+  // then store currently dumped string
+  theDumper.myFullDump << aBufCopy;
+
+  return theDumper;
+}
diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h
new file mode 100644 (file)
index 0000000..026f955
--- /dev/null
@@ -0,0 +1,291 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
+
+// File:        ModelHighAPI_Dumper.h
+// Created:     1 August 2016
+// Author:      Artem ZHIDKOV
+
+#ifndef ModelHighAPI_Dumper_H_
+#define ModelHighAPI_Dumper_H_
+
+#include "ModelHighAPI.h"
+
+#include <list>
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <string>
+
+class GeomAPI_Pnt;
+class GeomAPI_Dir;
+
+class GeomDataAPI_Dir;
+class GeomDataAPI_Point;
+class GeomDataAPI_Point2D;
+
+class ModelAPI_Attribute;
+class ModelAPI_AttributeBoolean;
+class ModelAPI_AttributeDouble;
+class ModelAPI_AttributeInteger;
+class ModelAPI_AttributeRefAttr;
+class ModelAPI_AttributeRefAttrList;
+class ModelAPI_AttributeReference;
+class ModelAPI_AttributeRefList;
+class ModelAPI_AttributeSelection;
+class ModelAPI_AttributeSelectionList;
+class ModelAPI_AttributeString;
+class ModelAPI_CompositeFeature;
+class ModelAPI_Document;
+class ModelAPI_Entity;
+class ModelAPI_Feature;
+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_Result>   ResultPtr;
+
+/**\class ModelHighAPI_Dumper
+ * \ingroup CPPHighAPI
+ * \brief Dump engine for the model
+ */
+class ModelHighAPI_Dumper
+{
+public:
+  /// Default constructor
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper();
+
+  /// Sets instance of a dumper
+  MODELHIGHAPI_EXPORT
+  static void setInstance(ModelHighAPI_Dumper* theDumper);
+
+  /// Returns instance of a dumper
+  MODELHIGHAPI_EXPORT
+  static ModelHighAPI_Dumper* getInstance();
+
+  /// Destructor
+  virtual ~ModelHighAPI_Dumper() {}
+
+  /// Dump given document into the file
+  /// \return \c true, if succeed
+  MODELHIGHAPI_EXPORT
+  bool process(const std::shared_ptr<ModelAPI_Document>& theDoc, const std::string& theFileName);
+
+  /// Add module to list of imported modules
+  /// \param theModuleName  name of the module to be imported
+  /// \param theObject      name of the entity to be imported from the module (if empty, while module will be imported)
+  MODELHIGHAPI_EXPORT
+  void importModule(const std::string& theModuleName,
+                    const std::string& theObject = std::string());
+
+  /// Returns name of specified entity
+  /// \param theEntity        [in] named entity
+  /// \param theSaveNotDumped [in] if \c true, the entity should be stored as not dumped (will be dumped automatically)
+  /// \param theUseEntityName [in] if \c true, the entity name should be used "as is" without changing default name
+  /// \return name of the entity
+  MODELHIGHAPI_EXPORT
+  const std::string& name(const EntityPtr& theEntity, bool theSaveNotDumped = true, bool theUseEntityName = false);
+
+  /// Returns name of parent composite feature for specified entity
+  MODELHIGHAPI_EXPORT
+  const std::string& parentName(const FeaturePtr& theFeature);
+
+  /// Dump parameter feature only
+  virtual void dumpParameter(const FeaturePtr& theFeature) = 0;
+  /// Dump given feature
+  virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0;
+
+  /// Dump sub-feature name and color, without dumping feature creation.
+  /// Used for features which creates sub-features in their execute method.
+  /// \param theSubFeatureGet [in] method for getting sub-feature (e.g. "Feature_1.subFeature(0)")
+  /// \param theSubFeature    [in] sub-feature
+  MODELHIGHAPI_EXPORT
+  void dumpSubFeatureNameAndColor(const std::string theSubFeatureGet,
+                                  const FeaturePtr& theSubFeature);
+
+  /// Return name of getter for corresponding attribute
+  virtual std::string attributeGetter(const FeaturePtr& theFeature,
+                                      const std::string& theAttrName) const = 0;
+
+  /// Save all dumps into specified file
+  MODELHIGHAPI_EXPORT
+  bool exportTo(const std::string& theFileName);
+
+  /// Dump character
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const char theChar);
+  /// Dump string
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const char* theString);
+  /// Dump string
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::string& theString);
+  /// Dump boolean
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const bool theValue);
+  /// Dump integer
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const int theValue);
+  /// Dump real
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const double theValue);
+  /// Dump std::endl
+  friend
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
+                                  std::basic_ostream<char>& (*theEndl)(std::basic_ostream<char>&));
+
+  /// Dump GeomAPI_Pnt in the following form:
+  /// "GeomAPI_Pnt(X, Y, Z)"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomAPI_Pnt>& thePoint);
+  /// Dump GeomAPI_Dir
+  /// "GeomAPI_Dir(X, Y, Z)"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomAPI_Dir>& theDir);
+
+  /// Dump GeomDataAPI_Dir in the following form:
+  /// "X, Y, Z"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Dir>& theDir);
+  /// Dump GeomDataAPI_Point in the following form:
+  /// "X, Y, Z"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Point>& thePoint);
+  /// Dump GeomDataAPI_Point2D in the following form:
+  /// "X, Y"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Point2D>& thePoint);
+
+  /// Dump AttributeBoolean
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeBoolean>& theAttrBool);
+  /// Dump AttributeInteger
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeInteger>& theAttrInt);
+  /// Dump AttributeDouble
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeDouble>& theAttrReal);
+  /// Dump AttributeString
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeString>& theAttrStr);
+  /// Dump name of entity and remember to dump "setName" if the entity has user-defined name
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const FeaturePtr& theEntity);
+
+  /// Dump result
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const ResultPtr& theResult);
+
+  /// Dump Attribute
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_Attribute>& theAttr);
+  /// Dump Object
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_Object>& theObject);
+
+  /// Dump AttributeRefAttr
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeRefAttr>& theRefAttr);
+  /// Dump AttributeRefAttrList as follows:
+  /// "[obj1, obj2, obj3, ...]"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeRefAttrList>& theRefAttrList);
+  /// Dump AttributeRefList as follows:
+  /// "[obj1, obj2, obj3, ...]"
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeRefList>& theRefList);
+  /// Dump AttributeSelection
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeSelection>& theAttrSelect);
+  /// Dump AttributeSelectionList
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeSelectionList>& theAttrSelList);
+  /// Dump AttributeReference
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeReference>& theReference);
+
+  /// Clear dump buffer
+  MODELHIGHAPI_EXPORT
+  void clear(bool bufferOnly = false);
+  /// clear list of not dumped entities
+  MODELHIGHAPI_EXPORT void clearNotDumped();
+
+protected:
+  /// Dump "setName" command if last entity had user-defined name
+  MODELHIGHAPI_EXPORT void dumpEntitySetName();
+
+private:
+  ModelHighAPI_Dumper(const ModelHighAPI_Dumper&);
+  const ModelHighAPI_Dumper& operator=(const ModelHighAPI_Dumper&);
+
+  /// Iterate all features in document and dump them into intermediate buffer
+  bool process(const std::shared_ptr<ModelAPI_Document>& theDoc);
+
+  /// Dump composite feature and all it sub-features
+  bool process(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite, bool isForce = false);
+
+  /// Iterate all features in composite feature and dump them into intermediate buffer
+  /// \param theComposite   [in] parent composite feature
+  /// \param theDumpModelDo [in] shows that command "model.do()" should be written at the end
+  MODELHIGHAPI_EXPORT
+  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);
+
+  /// Check the result feature has default color
+  bool isDefaultColor(const ResultPtr& theResult) const;
+
+private:
+  struct EntityName {
+    std::string myCurrentName; ///< default name of current feature
+    std::string myUserName;    ///< user-defined name
+    bool        myIsDefault;   ///< \c true if the name is default
+
+    EntityName() {}
+
+    EntityName(const std::string& theCurName, const std::string& theUserName, bool theDefault)
+      : myCurrentName(theCurName), myUserName(theUserName), myIsDefault(theDefault)
+    {}
+  };
+
+  typedef std::map<EntityPtr, EntityName>                     EntityNameMap;
+  typedef std::map<std::string, std::set<std::string> >       ModulesMap;
+  typedef std::map<DocumentPtr, std::map<std::string, int> >  NbFeaturesMap;
+
+  struct LastDumpedEntity {
+    EntityPtr            myEntity;   ///< last dumped entity
+    bool                 myUserName; ///< the entity hase user-defined name
+    std::list<ResultPtr> myResults;  ///< results of this entity, which has user-defined names or specific colors
+
+    LastDumpedEntity(EntityPtr theEntity, bool theUserName, const std::list<ResultPtr>& theResults)
+      : myEntity(theEntity), myUserName(theUserName), myResults(theResults)
+    {}
+  };
+  typedef std::stack<LastDumpedEntity>                              DumpStack;
+
+  static ModelHighAPI_Dumper* mySelf;
+
+  std::ostringstream  myDumpBuffer;         ///< intermediate buffer to store dumping data
+  std::ostringstream  myFullDump;           ///< full buffer of dumped data
+
+  ModulesMap          myModules;            ///< modules and entities to be imported
+  EntityNameMap       myNames;              ///< names of the entities
+  DumpStack           myEntitiesStack;      ///< stack of dumped entities
+
+  NbFeaturesMap       myFeatureCount;       ///< number of features of each kind
+
+protected:
+  std::set<EntityPtr> myNotDumpedEntities;  ///< list of entities, used by other features but not dumped yet
+
+  friend class SketchAPI_Sketch;
+};
+
+#endif
diff --git a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp
new file mode 100644 (file)
index 0000000..bf32bdb
--- /dev/null
@@ -0,0 +1,313 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
+
+// File:        ModelHighAPI_FeatureStore.cpp
+// Created:     12 August 2016
+// Author:      Mikhail PONIKAROV
+
+#include <ModelHighAPI_FeatureStore.h>
+
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefAttrList.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomDataAPI_Dir.h>
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Point2D.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_Pnt.h>
+
+#include <TopoDS_Shape.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <ios>
+#include <cmath>
+
+#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);
+  }
+}
+
+std::string ModelHighAPI_FeatureStore::compare(FeaturePtr theFeature) {
+  std::string anError = compareData(theFeature->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() + "'";
+  }
+  if (aResIter != myRes.end()) {
+    return "Original model had more results '" + (*aResIter)["__name__"] + "'";
+  }
+  return ""; // ok
+}
+
+void ModelHighAPI_FeatureStore::storeData(std::shared_ptr<ModelAPI_Data> theData, 
+  std::map<std::string, std::string>& theAttrs)
+{
+  theAttrs["__name__"] = theData->name(); // store name to keep also this information and output if needed
+  std::list<std::shared_ptr<ModelAPI_Attribute> > allAttrs = theData->attributes("");
+  std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = allAttrs.begin();
+  for(; anAttr != allAttrs.end(); anAttr++) {
+    theAttrs[(*anAttr)->id()] = dumpAttr(*anAttr);
+  }
+  ResultPtr aShapeOwner = std::dynamic_pointer_cast<ModelAPI_Result>(theData->owner());
+  if (aShapeOwner.get() && aShapeOwner->shape().get()) {
+    std::shared_ptr<GeomAPI_Shape> aShape = aShapeOwner->shape();
+    theAttrs["__shape__"] = dumpShape(aShape);
+  }
+}
+
+std::string ModelHighAPI_FeatureStore::compareData(std::shared_ptr<ModelAPI_Data> theData, 
+  std::map<std::string, std::string>& theAttrs)
+{
+  std::map<std::string, std::string> aThis;
+  storeData(theData, aThis);
+  std::map<std::string, std::string>::iterator aThisIter = aThis.begin();
+  for(; aThisIter != aThis.end(); aThisIter++) {
+    if (theAttrs.find(aThisIter->first) == theAttrs.end()) {
+      return "original model had no attribute '" + aThisIter->first + "'";
+    }
+    if (theAttrs[aThisIter->first] != aThisIter->second) {
+      return "attribute '" + aThisIter->first + "' is different (original != current) '" + 
+        theAttrs[aThisIter->first] + "' != '" + aThisIter->second + "'";
+    }
+  }
+  // iterate back to find lack attribute in the current model
+  std::map<std::string, std::string>::iterator anOrigIter = theAttrs.begin();
+  for(; anOrigIter != theAttrs.end(); anOrigIter++) {
+    if (aThis.find(anOrigIter->first) == aThis.end()) {
+      return "current model had no attribute '" + anOrigIter->first + "'";
+    }
+  }
+  return "";
+}
+
+static void dumpArray(std::ostringstream& theOutput, const double theArray[], int theSize, int thePrecision = PRECISION)
+{
+  for (int i = 0; i < theSize; ++i) {
+    if (i > 0)
+      theOutput << " ";
+    theOutput << std::fixed << setprecision(thePrecision)
+              << (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]);
+  }
+}
+
+std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
+  static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
+  FeaturePtr aFeatOwner = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttr->owner());
+  if (aFeatOwner.get() && !aFactory->isCase(aFeatOwner, theAttr->id())) {
+    return "__notcase__";
+  }
+  std::string aType = theAttr->attributeType();
+  std::ostringstream aResult;
+  if (!theAttr->isInitialized()) {
+    if (aType == ModelAPI_AttributeBoolean::typeId()) {
+      // special case for Boolean attribute (mean it false if not initialized)
+      aResult << false;
+      return aResult.str();
+    } else if (aType == ModelAPI_AttributeString::typeId()) {
+      // special case for attribute "SolverError"
+      if (theAttr->id() == "SolverError" && 
+          std::dynamic_pointer_cast<ModelAPI_Feature>(theAttr->owner())->getKind() == "Sketch")
+        return "";
+    }
+
+    return "__notinitialized__";
+  }
+  if (aType == ModelAPI_AttributeDocRef::typeId()) {
+    AttributeDocRefPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDocRef>(theAttr);
+    DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument();
+    if (anAttr->value() != aDoc) {
+      ResultPtr aRes = ModelAPI_Tools::findPartResult(aDoc, anAttr->value());
+      if (aRes.get()) {
+        aResult<<aRes->data()->name(); // Part result name (the same as saved file name)
+      }
+    } else {
+      aResult<<aDoc->kind(); // PartSet
+    }
+  } else if (aType == ModelAPI_AttributeInteger::typeId()) {
+    AttributeIntegerPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttr);
+    if (anAttr->text().empty())
+      aResult<<anAttr->value();
+    else
+      aResult<<anAttr->text();
+  } else if (aType == ModelAPI_AttributeDouble::typeId()) {
+    AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
+    int aPrecision = PRECISION;
+    // Special case - precision for the arc angle. It is calculated with tolerance 1e-4,
+    // so the value has only 4 correct digits
+    if (anAttr->id() == "ArcAngle")
+      aPrecision = 1;
+    if (anAttr->text().empty()) {
+      double aVal = anAttr->value();
+      dumpArray(aResult, &aVal, 1, aPrecision);
+    } else
+      aResult<<anAttr->text();
+  } else if (aType == ModelAPI_AttributeBoolean::typeId()) {
+    AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
+    aResult<<anAttr->value();
+  } else if (aType == ModelAPI_AttributeString::typeId()) {
+    AttributeStringPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(theAttr);
+    aResult<<anAttr->value();
+  } else if (aType == ModelAPI_AttributeReference::typeId()) {
+    AttributeReferencePtr anAttr =
+      std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttr);
+    if (anAttr->value().get()) {
+      aResult<<anAttr->value()->data()->name();
+    } else {
+      aResult<<"__empty__";
+    }
+  } else if (aType == ModelAPI_AttributeSelection::typeId()) {
+    AttributeSelectionPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttr);
+    aResult<<anAttr->namingName();
+  } else if (aType == ModelAPI_AttributeSelectionList::typeId()) {
+    AttributeSelectionListPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttr);
+    for(int a = 0; a < anAttr->size(); a++) {
+      if (a != 0)
+        aResult<<" ";
+      aResult<<anAttr->value(a)->namingName();
+    }
+  } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
+    AttributeRefAttrPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttr);
+    ObjectPtr anObj = anAttr->isObject() ? anAttr->object() : anAttr->attr()->owner();
+    if (anObj.get()) {
+      aResult<<anObj->data()->name();
+      if (!anAttr->isObject()) {
+        aResult<<" "<<anAttr->attr()->id();
+      }
+    } else {
+      aResult<<"__empty__";
+    }
+  } else if (aType == ModelAPI_AttributeRefList::typeId()) {
+    AttributeRefListPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttr);
+    // for sketch sub-features the empty values may be skipped and order is not important
+    bool isSketchFeatures = anAttr->id() == "Features" && 
+      std::dynamic_pointer_cast<ModelAPI_Feature>(anAttr->owner())->getKind() == "Sketch";
+    std::list<ObjectPtr> aList = anAttr->list();
+    std::list<std::string> aResList; // list of resulting strings
+    for(std::list<ObjectPtr>::iterator aL = aList.begin(); aL != aList.end(); aL++) {
+      if (aL->get()) {
+        aResList.push_back((*aL)->data()->name());
+      } else if (!isSketchFeatures) {
+        aResList.push_back("__empty__");
+      }
+    }
+    if (isSketchFeatures)
+      aResList.sort();
+    for(std::list<std::string>::iterator aR = aResList.begin(); aR != aResList.end(); aR++) {
+      aResult<<*aR<<" ";
+    }
+  } else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
+    AttributeRefAttrListPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttr);
+    std::list<std::pair<ObjectPtr, AttributePtr> > aList = anAttr->list();
+    std::list<std::pair<ObjectPtr, AttributePtr> >::iterator aL = aList.begin();
+    for(; aL != aList.end(); aL++) {
+      if (aL != aList.begin())
+        aResult<<" ";
+      ObjectPtr anObj = aL->second.get() ? aL->second->owner() : aL->first;
+      if (anObj.get()) {
+        aResult<<anObj->data()->name();
+        if (aL->second.get()) {
+          aResult<<" "<<aL->second->id();
+        }
+      } else {
+        aResult<<"__empty__";
+      }
+    }
+  } else if (aType == ModelAPI_AttributeIntArray::typeId()) {
+    AttributeIntArrayPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttr);
+    for(int a = 0; a < anAttr->size(); a++)
+      aResult<<anAttr->value(a)<<" ";
+  } else if (aType == ModelAPI_AttributeDoubleArray::typeId()) {
+    AttributeDoubleArrayPtr anAttr = 
+      std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(theAttr);
+    for(int a = 0; a < anAttr->size(); a++)
+      aResult<<anAttr->value(a)<<" ";
+  } else if (aType == GeomDataAPI_Point::typeId()) {
+    AttributePointPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttr);
+    double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
+    dumpArray(aResult, aValues, 3);
+  } else if (aType == GeomDataAPI_Dir::typeId()) {
+    AttributeDirPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theAttr);
+    double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
+    dumpArray(aResult, aValues, 3);
+  } else if (aType == GeomDataAPI_Point2D::typeId()) {
+    // do not dump flyout point for constraints as it may be changed unexpectedly
+    if (theAttr->id() == "ConstraintFlyoutValuePnt")
+      return "";
+    AttributePoint2DPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttr);
+    double aValues[2] = {anAttr->x(), anAttr->y()};
+    dumpArray(aResult, aValues, 2);
+  } else {
+    aResult<<"__unknownattribute__";
+  }
+  return aResult.str();
+}
+
+std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>& theShape) {
+  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+  if (aShape.IsNull()) {
+    return "null";
+  }
+  std::ostringstream aResult;
+  // output the number of shapes of different types
+  TopAbs_ShapeEnum aType = TopAbs_COMPOUND;
+  for(; aType <= TopAbs_VERTEX; aType = TopAbs_ShapeEnum((int)aType + 1)) {
+    TopExp_Explorer anExp(aShape, aType);
+    int aCount = 0;
+    for(; anExp.More(); anExp.Next()) aCount++;
+    TopAbs::Print(aType, aResult);
+    aResult<<": "<<aCount<<std::endl;
+  }
+  // output the main characteristics
+  if (GeomAlgoAPI_ShapeTools::volume(theShape) > 1.e-7) {
+    aResult<<"Volume: "<<std::fixed<<setprecision(3)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
+  }
+  std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
+  aResult<<"Center of mass: ";
+  double aCenterVals[3] = {aCenter->x(), aCenter->y(), aCenter->z()};
+  dumpArray(aResult, aCenterVals, 3);
+  aResult<<std::endl;
+  return aResult.str();
+}
diff --git a/src/ModelHighAPI/ModelHighAPI_FeatureStore.h b/src/ModelHighAPI/ModelHighAPI_FeatureStore.h
new file mode 100644 (file)
index 0000000..fbe83c0
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
+
+// File:        ModelHighAPI_FeatureStore.h
+// Created:     12 August 2016
+// Author:      Mikhail PONIKAROV
+
+#ifndef ModelHighAPI_FeatureStore_H_
+#define ModelHighAPI_FeatureStore_H_
+
+#include "ModelHighAPI.h"
+
+#include <map>
+#include <list>
+#include <string>
+#include <memory>
+
+class ModelAPI_Feature;
+class ModelAPI_Data;
+class GeomAPI_Shape;
+class ModelAPI_Attribute;
+
+typedef std::shared_ptr<ModelAPI_Feature>  FeaturePtr;
+typedef std::shared_ptr<ModelAPI_Attribute>  AttributePtr;
+
+/**\class ModelHighAPI_FeatureStore
+ * \ingroup CPPHighAPI
+ * \brief Allows to compare the original and the dumped/executed feature
+ */
+class ModelHighAPI_FeatureStore {
+  /// dumps of attributes of the stored feature (id -> dump)
+  std::map<std::string, std::string> myAttrs;
+   /// dumps of attributes of results (list of results id -> dumps)
+  std::list<std::map<std::string, std::string> > myRes;
+public:
+  // unused constructor for the map container needs
+  ModelHighAPI_FeatureStore() {}
+  // constructor that initializes this object by feature to store
+  ModelHighAPI_FeatureStore(FeaturePtr theFeature);
+  // compares the stored feature information with the given feature
+  std::string compare(FeaturePtr theFeature);
+
+private:
+  /// stores the information about all attributes of data in map
+  void storeData(std::shared_ptr<ModelAPI_Data> theData, 
+                 std::map<std::string, std::string>& theAttrs);
+  /// compares the information about all attributes of data with map
+  /// returns not empty string with error if something is different
+  std::string compareData(std::shared_ptr<ModelAPI_Data> theData, 
+                 std::map<std::string, std::string>& theAttrs);
+  /// dumps the attribute content to the string
+  std::string dumpAttr(const AttributePtr& theAttr);
+  /// dumps the shape main charatceristics to string
+  std::string dumpShape(std::shared_ptr<GeomAPI_Shape>& theShape);
+};
+
+#endif
\ No newline at end of file
index 228fdcc913bed9a8ee4b03b5eec242a4d49fe5b9..cfea20834ff7b433975d54317d79da7f3c02b9ee 100644 (file)
@@ -9,7 +9,11 @@
 //--------------------------------------------------------------------------------------
 #include <Events_InfoMessage.h>
 
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Events.h>
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
 
 #include "ModelHighAPI_Selection.h"
 //--------------------------------------------------------------------------------------
@@ -30,14 +34,46 @@ std::shared_ptr<ModelAPI_Feature> ModelHighAPI_Interface::feature() const
   return myFeature;
 }
 
+std::shared_ptr<ModelHighAPI_Interface> ModelHighAPI_Interface::subFeature(const int theIndex) const
+{
+  CompositeFeaturePtr aCompositeFeature = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+  if(!aCompositeFeature.get()) {
+    return InterfacePtr();
+  }
+
+  FeaturePtr aSubFeature = aCompositeFeature->subFeature(theIndex);
+  if(!aSubFeature.get()) {
+    return InterfacePtr();
+  }
+
+  return InterfacePtr(new ModelHighAPI_Interface(aSubFeature));
+}
+
 const std::string& ModelHighAPI_Interface::getKind() const
 {
   return feature()->getKind();
 }
 
-void ModelHighAPI_Interface::execute()
+void ModelHighAPI_Interface::execute(bool isForce)
 {
-  feature()->execute();
+  if (isForce) {
+    SessionPtr aMgr = ModelAPI_Session::get();
+    ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+    FeaturePtr aFeature = feature();
+    if(aFactory->validate(aFeature))
+      aFeature->execute();
+  }
+
+  Events_Loop* aLoop = Events_Loop::loop();
+  aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+  aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  //aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  //aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+}
+
+void ModelHighAPI_Interface::setName(const std::string& theName)
+{
+  feature()->data()->setName(theName);
 }
 
 std::list<ModelHighAPI_Selection> ModelHighAPI_Interface::result() const
@@ -57,6 +93,8 @@ std::list<ModelHighAPI_Selection> ModelHighAPI_Interface::result() const
 
 std::shared_ptr<ModelAPI_Result> ModelHighAPI_Interface::defaultResult() const
 {
+  const_cast<ModelHighAPI_Interface*>(this)->execute();
+
   return feature()->lastResult();
 }
 
@@ -64,3 +102,8 @@ void ModelHighAPI_Interface::throwException(const std::string & theDescription)
 {
   Events_InfoMessage("ModelHighAPI_Interface", theDescription).send();
 }
+
+const std::string& ModelHighAPI_Interface::attributeGetter(const std::string& theAttrName)
+{
+  return myAttrGetter[theAttrName];
+}
index 7d61ffbfb69ee940f6f987d0075f216881beb53a..43d267642b495617a8b0c65c34d9f60d09578aa6 100644 (file)
@@ -11,6 +11,7 @@
 #include "ModelHighAPI.h"
 
 #include <list>
+#include <map>
 #include <memory>
 #include <string>
 #include <iostream>
@@ -18,6 +19,7 @@
 class ModelAPI_Feature;
 class ModelAPI_Result;
 class ModelHighAPI_Selection;
+class ModelHighAPI_Dumper;
 //--------------------------------------------------------------------------------------
 /**\class ModelHighAPI_Interface
  * \ingroup CPPHighAPI
@@ -37,13 +39,23 @@ public:
   MODELHIGHAPI_EXPORT
   std::shared_ptr<ModelAPI_Feature> feature() const;
 
+  /// If feature is composite return intefrace for sub-feature by zero-based index,
+  /// or empty pointer if feature not composite or does not have sub-feature with such index.
+  MODELHIGHAPI_EXPORT
+  std::shared_ptr<ModelHighAPI_Interface> subFeature(const int theIndex) const;
+
   /// Shortcut for feature()->getKind()
   MODELHIGHAPI_EXPORT
   const std::string& getKind() const;
 
   /// Shortcut for feature()->execute()
+  /// \param isForce start execution of feature instead of sending events
   MODELHIGHAPI_EXPORT
-  void execute();
+  void execute(bool isForce = false);
+
+  /// Shortcut for feature()->data()->setName()
+  MODELHIGHAPI_EXPORT
+  void setName(const std::string& theName);
 
   // TODO(spo): rename to selectAll()
   /// Return all objects of the feature
@@ -58,8 +70,18 @@ public:
   MODELHIGHAPI_EXPORT
   void throwException(const std::string & theDescription);
 
+  /// Return name of getter for specified attribute
+  MODELHIGHAPI_EXPORT
+  const std::string& attributeGetter(const std::string& theAttrName);
+
+  /// Dump wrapped feature
+  MODELHIGHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const {}
+
 protected:
   std::shared_ptr<ModelAPI_Feature> myFeature;
+
+  std::map<std::string, std::string> myAttrGetter; ///< names of attributes and their getters
 };
 
 //! Pointer on Interface object
index aed82f368a6ec258be3e296e50bbfc21ea65200e..f6bfc6cee8272650c71c1930d19c73dd69dcb97a 100644 (file)
 //--------------------------------------------------------------------------------------
 #define VAR_NAME(NAME) my##NAME
 
+//--------------------------------------------------------------------------------------
+#define TO_STRING_(NAME) #NAME
+#define TO_STRING(NAME) TO_STRING_(NAME)
+
 //--------------------------------------------------------------------------------------
 // Used in INTERFACE_N for create variable and getter
 #define DEFINE_ATTRIBUTE(NAME, TYPE, COMMENT) \
@@ -43,7 +47,8 @@
 #define SET_ATTRIBUTE(NAME, TYPE, ATT_NAME) \
   VAR_NAME(NAME) = std::dynamic_pointer_cast<TYPE>(feature()->attribute(ATT_NAME)); \
   if (!VAR_NAME(NAME)) \
-    return false;
+    return false; \
+  myAttrGetter[ATT_NAME] = TO_STRING(NAME);
 
 //--------------------------------------------------------------------------------------
 #define INTERFACE_COMMON(KIND) \
index 999cc718effb225a7dbef99b34f4539dc94cdae4..6bb6aeb3b2597aedc5ccd7e8e52c48dd9582e94e 100644 (file)
@@ -62,3 +62,9 @@ void ModelHighAPI_RefAttr::appendToList(
     case VT_OBJECT: theAttribute->append(myObject); return;
   }
 }
+
+//--------------------------------------------------------------------------------------
+bool ModelHighAPI_RefAttr::isEmpty() const
+{
+  return !(myAttribute && myObject);
+}
index bc54e20789d32777a9d11b4a387ddd3a8235689b..816e5f59a6fa7e0cb5fbd0702ff67fc7b5338255 100644 (file)
@@ -50,6 +50,10 @@ public:
   MODELHIGHAPI_EXPORT
   virtual void appendToList(const std::shared_ptr<ModelAPI_AttributeRefAttrList> & theAttribute) const;
 
+  /// Check the object is empty
+  MODELHIGHAPI_EXPORT
+  bool isEmpty() const;
+
 private:
   enum VariantType { VT_ATTRIBUTE, VT_OBJECT } myVariantType;
   std::shared_ptr<ModelAPI_Attribute> myAttribute;
index 3e13a0b463d95f32fef462b83c9500c287d0d2d8..f427b7e921fe59265c042d29cbd9e38cc50a4eea 100644 (file)
@@ -25,6 +25,11 @@ ModelHighAPI_Reference::ModelHighAPI_Reference(
     const std::shared_ptr<ModelHighAPI_Interface> & theValue)
 : myObject(std::shared_ptr<ModelAPI_Object>(theValue->defaultResult()))
 {
+  // the result is not constructed yet, forcibly do it
+  if (!myObject) {
+    theValue->execute(true);
+    myObject = std::shared_ptr<ModelAPI_Object>(theValue->defaultResult());
+  }
 }
 
 ModelHighAPI_Reference::~ModelHighAPI_Reference()
@@ -44,3 +49,9 @@ void ModelHighAPI_Reference::appendToList(
 {
   theAttribute->append(myObject);
 }
+
+//--------------------------------------------------------------------------------------
+std::shared_ptr<ModelAPI_Feature> ModelHighAPI_Reference::feature() const
+{
+  return ModelAPI_Feature::feature(myObject);
+}
index 71a6f2acaed2eb8394d06a258744c7325f416a5a..f960791ce14b8b8e6db7fd64de81e75a1218ec4b 100644 (file)
@@ -16,6 +16,7 @@
 class ModelAPI_Attribute;
 class ModelAPI_AttributeReference;
 class ModelAPI_AttributeRefList;
+class ModelAPI_Feature;
 class ModelAPI_Object;
 class ModelHighAPI_Interface;
 //--------------------------------------------------------------------------------------
@@ -47,6 +48,10 @@ public:
   MODELHIGHAPI_EXPORT
   virtual void appendToList(const std::shared_ptr<ModelAPI_AttributeRefList> & theAttribute) const;
 
+  /// Returns feature for this object.
+  MODELHIGHAPI_EXPORT
+  virtual std::shared_ptr<ModelAPI_Feature> feature() const;
+
 private:
   std::shared_ptr<ModelAPI_Object> myObject;
 };
index 1a7e90cc0391f88be5ce50a3cb4bd60c77f85eda..536e22710957bd1e3740e992a7434f96a7dcf0be 100644 (file)
@@ -7,11 +7,17 @@
 //--------------------------------------------------------------------------------------
 #include "ModelHighAPI_Selection.h"
 
+#include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeSelectionList.h>
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------
+ModelHighAPI_Selection::ModelHighAPI_Selection()
+: myVariantType(VT_Empty)
+{
+}
+
 ModelHighAPI_Selection::ModelHighAPI_Selection(const std::shared_ptr<ModelAPI_Result>& theContext,
                                                const std::shared_ptr<GeomAPI_Shape>& theSubShape)
 : myVariantType(VT_ResultSubShapePair)
@@ -35,6 +41,7 @@ void ModelHighAPI_Selection::fillAttribute(
     const std::shared_ptr<ModelAPI_AttributeSelection> & theAttribute) const
 {
   switch(myVariantType) {
+    case VT_Empty: return;
     case VT_ResultSubShapePair: theAttribute->setValue(myResultSubShapePair.first, myResultSubShapePair.second); return;
     case VT_TypeSubShapeNamePair: theAttribute->selectSubShape(myTypeSubShapeNamePair.first, myTypeSubShapeNamePair.second); return;
   }
@@ -45,6 +52,7 @@ void ModelHighAPI_Selection::appendToList(
     const std::shared_ptr<ModelAPI_AttributeSelectionList> & theAttribute) const
 {
   switch(myVariantType) {
+    case VT_Empty: return;
     case VT_ResultSubShapePair: theAttribute->append(myResultSubShapePair.first, myResultSubShapePair.second); return;
     case VT_TypeSubShapeNamePair:
       // Note: the reverse order (first - type, second - sub-shape name)
@@ -70,3 +78,36 @@ TypeSubShapeNamePair ModelHighAPI_Selection::typeSubShapeNamePair() const
 {
   return myTypeSubShapeNamePair;
 }
+
+//==================================================================================================
+std::string ModelHighAPI_Selection::shapeType() const
+{
+  switch(myVariantType) {
+  case VT_ResultSubShapePair: 
+    return myResultSubShapePair.second.get() ? myResultSubShapePair.second->shapeTypeStr() : 
+                                               myResultSubShapePair.first->shape()->shapeTypeStr();
+  case VT_TypeSubShapeNamePair: return myTypeSubShapeNamePair.first;
+  }
+
+  return "SHAPE";
+}
+
+//==================================================================================================
+void ModelHighAPI_Selection::setName(const std::string& theName)
+{
+  if (myVariantType == VT_ResultSubShapePair)
+    myResultSubShapePair.first->data()->setName(theName);
+}
+
+void ModelHighAPI_Selection::setColor(int theRed, int theGreen, int theBlue)
+{
+  if (myVariantType != VT_ResultSubShapePair)
+    return;
+
+  AttributeIntArrayPtr aColor =
+      myResultSubShapePair.first->data()->intArray(ModelAPI_Result::COLOR_ID());
+  aColor->setSize(3);
+  aColor->setValue(0, theRed);
+  aColor->setValue(1, theGreen);
+  aColor->setValue(2, theBlue);
+}
index 2a72733197c78190291cd789f8c0827845a054fe..b138b8f009962002f990485681593e80e997f573 100644 (file)
@@ -30,14 +30,19 @@ class ModelHighAPI_Selection
 {
 public:
   enum VariantType {
+    VT_Empty,
     VT_ResultSubShapePair,
     VT_TypeSubShapeNamePair
   };
 
 public:
+  /// Default constructor with empty selection.
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Selection();
+
   /// Constructor for result and sub-shape
   MODELHIGHAPI_EXPORT
-  ModelHighAPI_Selection(const std::shared_ptr<ModelAPI_Result>& theContext = std::shared_ptr<ModelAPI_Result>(),
+  ModelHighAPI_Selection(const std::shared_ptr<ModelAPI_Result>& theContext,
                          const std::shared_ptr<GeomAPI_Shape>& theSubShape = std::shared_ptr<GeomAPI_Shape>());
   /// Constructor for sub-shape by the textual Name
   MODELHIGHAPI_EXPORT
@@ -67,6 +72,18 @@ public:
   MODELHIGHAPI_EXPORT
   virtual TypeSubShapeNamePair typeSubShapeNamePair() const;
 
+  /// \return shape type.
+  MODELHIGHAPI_EXPORT
+  virtual std::string shapeType() const;
+
+  /// Shortcut for result()->data()->setName()
+  MODELHIGHAPI_EXPORT
+  void setName(const std::string& theName);
+
+  /// Change result's color
+  MODELHIGHAPI_EXPORT
+  void setColor(int theRed, int theGreen, int theBlue);
+
 private:
   VariantType myVariantType;
   ResultSubShapePair myResultSubShapePair;
index 09be73726729380ce997b7d211ac4383deba5a6c..c1c6e64b3a1d1f5f4df34ccf2f12bf2f40c0a0ee 100644 (file)
 #include <GeomAPI_Ax3.h>
 #include <GeomAPI_Pnt.h>
 #include <ModelAPI_Session.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <cmath>
 
 //--------------------------------------------------------------------------------------
 std::shared_ptr<ModelAPI_Document> moduleDocument()
@@ -42,6 +46,39 @@ std::shared_ptr<GeomAPI_Ax3> defaultPlane( const std::string& theName )
   return std::shared_ptr<GeomAPI_Ax3>(new GeomAPI_Ax3(o, x, n));
 }
 
+std::string defaultPlane(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                         const std::shared_ptr<GeomAPI_Dir>& theNormal,
+                         const std::shared_ptr<GeomAPI_Dir>& theDirX)
+{
+  static const double aTol = 1.e-10;
+
+  if (fabs(theOrigin->x()) > aTol || fabs(theOrigin->y()) > aTol || fabs(theOrigin->z()) > aTol)
+    return std::string();
+
+  // XOY or XOZ
+  if (fabs(theNormal->x()) < aTol && 
+      fabs(theDirX->x() - 1.0) < aTol && fabs(theDirX->y()) < aTol && fabs(theDirX->z()) < aTol) {
+    // XOY
+    if (fabs(theNormal->y()) < aTol && fabs(theNormal->z() - 1.0) < aTol)
+      return std::string("XOY");
+    else if (fabs(theNormal->y() + 1.0) < aTol && fabs(theNormal->z()) < aTol)
+      return std::string("XOZ");
+  }
+  // YOZ
+  else if (fabs(theNormal->x() - 1.0) < aTol && fabs(theNormal->y()) < aTol && fabs(theNormal->z()) < aTol &&
+           fabs(theDirX->x()) < aTol && fabs(theDirX->y() - 1.0) < aTol && fabs(theDirX->z()) < aTol)
+    return std::string("YOZ");
+
+  return std::string();
+}
+
+std::shared_ptr<ModelAPI_Result> standardPlane(const std::string & theName){
+  DocumentPtr aPartSet = ModelAPI_Session::get()->moduleDocument();
+  // searching for the construction element
+  return std::dynamic_pointer_cast<ModelAPI_Result>(
+    aPartSet->objectByName(ModelAPI_ResultConstruction::group(), theName));
+}
+
 //--------------------------------------------------------------------------------------
 void begin()
 {
index 4d0578382469dcabd6218c6c5e7ee429e795f573..4e719429dc984aa4c72ce4c5153062d709a089d1 100644 (file)
 #include <string>
 //--------------------------------------------------------------------------------------
 class GeomAPI_Ax3;
+class GeomAPI_Dir;
+class GeomAPI_Pnt;
 class ModelAPI_Document;
+class ModelAPI_Result;
 //--------------------------------------------------------------------------------------
 /// Return the main document (the Partset) created or open from the Modeler.
 MODELHIGHAPI_EXPORT
@@ -35,6 +38,19 @@ std::shared_ptr<ModelAPI_Document> activeDocument();
 MODELHIGHAPI_EXPORT
 std::shared_ptr<GeomAPI_Ax3> defaultPlane(const std::string & theName);
 
+/// Return name of coordinate plane ("XOY", "XOZ" or "YOZ") or empty string for other planes.
+MODELHIGHAPI_EXPORT
+std::string defaultPlane(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                         const std::shared_ptr<GeomAPI_Dir>& theNormal,
+                         const std::shared_ptr<GeomAPI_Dir>& theDirX);
+
+/** Return one of the three standard results defined in PartSet document.
+ *
+ *  These planes are respectively referred to by name "XOY" (Z=0), "XOZ" (Y=0) or "YOZ" (X=0).
+ */
+MODELHIGHAPI_EXPORT
+std::shared_ptr<ModelAPI_Result> standardPlane(const std::string & theName);
+
 /** Start a data structure transaction.
  *
  *  Make a control point for being able to discard or undo
index be4e0186f020be400cbafd5d67dee676583dcb72..23f65ebc61497dc1e3c0066451243f2feb610068 100644 (file)
@@ -6,6 +6,7 @@
 
 //--------------------------------------------------------------------------------------
 #include "ModelHighAPI_Tools.h"
+#include <ModelHighAPI_FeatureStore.h>
 //--------------------------------------------------------------------------------------
 #include <GeomAPI_Dir.h>
 #include <GeomAPI_Pnt.h>
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_ResultPart.h>
+//--------------------------------------------------------------------------------------
+#include <Config_ModuleReader.h>
 //--------------------------------------------------------------------------------------
 #include "ModelHighAPI_Double.h"
 #include "ModelHighAPI_Integer.h"
 #include "ModelHighAPI_Reference.h"
 #include "ModelHighAPI_Selection.h"
 
+#include <Events_InfoMessage.h>
+
+// Have to be included before std headers
+#include <Python.h>
+
 #include <algorithm>
+#include <iostream>
 
 //--------------------------------------------------------------------------------------
 void fillAttribute(const std::shared_ptr<GeomAPI_Pnt2d> & theValue,
@@ -88,6 +101,11 @@ void fillAttribute(const ModelHighAPI_Integer & theValue,
 {
   theValue.fillAttribute(theAttribute);
 }
+void fillAttribute(int theValue,
+                   const std::shared_ptr<ModelAPI_AttributeInteger> & theAttribute)
+{
+  theAttribute->setValue(theValue);
+}
 
 //--------------------------------------------------------------------------------------
 void fillAttribute(const ModelHighAPI_RefAttr & theValue,
@@ -158,6 +176,13 @@ void fillAttribute(const std::list<ModelHighAPI_Selection> & theValue,
                    const std::shared_ptr<ModelAPI_AttributeSelectionList> & theAttribute)
 {
   theAttribute->clear();
+
+  if(!theValue.empty()) {
+    std::string aSelectionType;
+    const ModelHighAPI_Selection& aSelection = theValue.front();
+    theAttribute->setSelectionType(aSelection.shapeType());
+  }
+
   for (auto it = theValue.begin(); it != theValue.end(); ++it)
     it->appendToList(theAttribute);
 }
@@ -175,12 +200,11 @@ void fillAttribute(const char * theValue,
 }
 
 //==================================================================================================
-GeomAPI_Shape::ShapeType shapeTypeByStr(const std::string& theShapeTypeStr)
+GeomAPI_Shape::ShapeType shapeTypeByStr(std::string theShapeTypeStr)
 {
   GeomAPI_Shape::ShapeType aShapeType = GeomAPI_Shape::SHAPE;
 
-  std::string aShapeTypeStr = theShapeTypeStr;
-  std::transform(aShapeTypeStr.begin(), aShapeTypeStr.end(), aShapeTypeStr.begin(), ::tolower);
+  std::transform(theShapeTypeStr.begin(), theShapeTypeStr.end(), theShapeTypeStr.begin(), ::tolower);
 
   if(theShapeTypeStr == "compound") {
     aShapeType = GeomAPI_Shape::COMPOUND;
@@ -234,4 +258,118 @@ GeomAPI_Shape::ShapeType getShapeType(const ModelHighAPI_Selection& theSelection
   return aShapeType;
 }
 
+/// stores the features information, recoursively stores sub-documetns features
+std::string storeFeatures(const std::string& theDocName, DocumentPtr theDoc,
+  std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> >& theStore,
+  const bool theCompare) // if false => store
+{
+  std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> >::iterator aDocFind;
+  if (theCompare) {
+     aDocFind = theStore.find(theDocName);
+     if (aDocFind == theStore.end()) {
+       return "Document '" + theDocName + "' not found";
+     }
+  }
+  // store the model features information: iterate all features
+  int aFeaturesCount = 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;
+    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";
+      }
+      std::string anError = aFeatFind->second.compare(aFeat);
+      if (!anError.empty()) {
+        return anError;
+      }
+      aFeaturesCount++;
+      aProcessed.insert(aFeat->name());
+    } else {
+      theStore[theDocName][aFeat->name()] = ModelHighAPI_FeatureStore(aFeat);
+    }
+    // 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++) {
+      if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) { // recoursively store features of sub-documents
+        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) {
+      // search for disappeared feature
+      std::string aLostName;
+      std::map<std::string, ModelHighAPI_FeatureStore>::iterator aLostIter;
+      for(aLostIter = aDocFind->second.begin(); aLostIter != aDocFind->second.end(); aLostIter++) {
+        if (aProcessed.find(aLostIter->first) == aProcessed.end()) {
+          aLostName = aLostIter->first;
+        }
+      }
+      return "For document '" + theDocName + 
+        "' the number of features is decreased, there is no feature '" + aLostName + "'";
+    }
+  }
+  return ""; // ok
+}
+
+//==================================================================================================
+bool checkPythonDump()
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  // dump all to the python file
+  aSession->startOperation("Check python dump");
+  FeaturePtr aDump = aSession->moduleDocument()->addFeature("Dump");
+  if (aDump.get()) {
+    aDump->string("file_path")->setValue("check_dump.py"); // to the current folder
+    aDump->string("file_format")->setValue("py"); // to the current folder
+    aDump->execute();
+  }
+  bool isProblem = !aDump.get() || !aDump->error().empty(); // after "finish" dump will be removed
+  aSession->finishOperation();
+  if (isProblem)
+    return false; // something is wrong during dump
+
+   // map from document name to feature name to feature data
+  std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> > aStore;
+  std::string anError = storeFeatures(
+    aSession->moduleDocument()->kind(), aSession->moduleDocument(), aStore, false);
+  if (!anError.empty()) {
+    Events_InfoMessage anErrorMsg(std::string("checkPythonDump"), anError);
+    anErrorMsg.send();
+    return false;
+  }
+  // close all before importation of the script
+  aSession->closeAll();
+  // execute the dumped
+  PyGILState_STATE gstate = PyGILState_Ensure(); /* acquire python thread */
+  PyObject* PyFileObject = PyFile_FromString("./check_dump.py", "r");
+  PyRun_SimpleFileEx(PyFile_AsFile(PyFileObject), "./check_dump.py", 1);
+  PyGILState_Release(gstate); /* release python thread */
+
+  // compare with the stored data
+  anError = storeFeatures(
+    aSession->moduleDocument()->kind(), aSession->moduleDocument(), aStore, true);
+  if (!anError.empty()) {
+    std::cout<<anError<<std::endl;
+    Events_InfoMessage anErrorMsg(std::string("checkPythonDump"), anError);
+    anErrorMsg.send();
+    return false;
+  }
+
+  return true;
+}
+
 //--------------------------------------------------------------------------------------
index f5467566d61bc31c1ee3bcb845d86c8f91574c25..5db774d70d2bbe974d5003172a9ec49fce21b5c1 100644 (file)
@@ -25,7 +25,6 @@ class GeomDataAPI_Point;
 class GeomDataAPI_Point2D;
 //--------------------------------------------------------------------------------------
 class ModelAPI_AttributeBoolean;
-class ModelAPI_AttributeDocRef;
 class ModelAPI_AttributeDouble;
 class ModelAPI_AttributeIntArray;
 class ModelAPI_AttributeInteger;
@@ -77,6 +76,10 @@ MODELHIGHAPI_EXPORT
 void fillAttribute(const ModelHighAPI_Integer & theValue,
                    const std::shared_ptr<ModelAPI_AttributeInteger> & theAttribute);
 
+MODELHIGHAPI_EXPORT
+void fillAttribute(int theValue,
+                   const std::shared_ptr<ModelAPI_AttributeInteger> & theAttribute);
+
 MODELHIGHAPI_EXPORT
 void fillAttribute(const ModelHighAPI_RefAttr & theValue,
                    const std::shared_ptr<ModelAPI_AttributeRefAttr> & theAttribute);
@@ -121,11 +124,17 @@ void fillAttribute(const char * theValue,
                    const std::shared_ptr<ModelAPI_AttributeString> & theAttribute);
 
 MODELHIGHAPI_EXPORT
-GeomAPI_Shape::ShapeType shapeTypeByStr(const std::string& theShapeTypeStr);
+GeomAPI_Shape::ShapeType shapeTypeByStr(std::string theShapeTypeStr);
 
 MODELHIGHAPI_EXPORT
 GeomAPI_Shape::ShapeType getShapeType(const ModelHighAPI_Selection& theSelection);
 
+/// Performs the high level API dump, then closes all and executes the script:
+/// model must be recreated fully, with all attributes
+/// \returns true if check is well done
+MODELHIGHAPI_EXPORT
+bool checkPythonDump();
+
 //--------------------------------------------------------------------------------------
 //--------------------------------------------------------------------------------------
 #endif /* SRC_MODELHIGHAPI_MODELHIGHAPI_TOOLS_H_ */ 
index d430240cc3793feae9c66c8b5447dbdca9cb04e6..c9230d49ef728b4bfd1af5784d03ebd4668d7a58 100644 (file)
@@ -13,6 +13,7 @@
 
   #include "ModelHighAPI.h"
   #include "ModelHighAPI_Double.h"
+  #include "ModelHighAPI_Dumper.h"
   #include "ModelHighAPI_Integer.h"
   #include "ModelHighAPI_Interface.h"
   #include "ModelHighAPI_Macro.h"
index 296f0e0caaeb1d1b90399c10a9fe6b0d3b8f27cf..9dc18d5981db4b0c238bdf77e58dcb2c4787bac8 100644 (file)
@@ -155,7 +155,7 @@ bool ModuleBase_WidgetDoubleValue::restoreValueCustom()
   if (!aTextRepr.empty()) {
     ModuleBase_Tools::setSpinText(mySpinBox, QString::fromStdString(aTextRepr));
   } else {
-    ModuleBase_Tools::setSpinValue(mySpinBox, aRef->value());
+    ModuleBase_Tools::setSpinValue(mySpinBox, aRef->isInitialized() ? aRef->value() : 0);
   }
   return true;
 }
index 0faa1346af1cc6a013a1499e88444aa5ea049016..03158e47d62dfe127c9019d7a67915fbb63325c5 100644 (file)
@@ -7,6 +7,7 @@
 //--------------------------------------------------------------------------------------
 #include "ParametersAPI_Parameter.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 ParametersAPI_Parameter::ParametersAPI_Parameter(
@@ -26,7 +27,8 @@ ParametersAPI_Parameter::ParametersAPI_Parameter(
   if (initialize()) {
     fillAttribute(theName, name());
     fillAttribute(theExpression, expression());
-    fillAttribute(theComment, comment());
+    if (!theComment.empty())
+      fillAttribute(theComment, comment());
 
     execute();
   }
@@ -36,6 +38,21 @@ ParametersAPI_Parameter::~ParametersAPI_Parameter()
 {
 }
 
+void ParametersAPI_Parameter::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+  const std::string& aParamName = theDumper.name(aBase, false, true);
+
+  AttributeStringPtr anExpr   = aBase->string(ParametersPlugin_Parameter::EXPRESSION_ID());
+  AttributeStringPtr aComment = aBase->string(ParametersPlugin_Parameter::COMMENT_ID());
+
+  theDumper << "model.addParameter(" << aDocName << ", \"" << aParamName << "\", " << anExpr;
+  if (aComment->isInitialized() && !aComment->value().empty())
+    theDumper << ", " << aComment;
+  theDumper << ")" << std::endl;
+}
+
 //--------------------------------------------------------------------------------------
 ParameterPtr addParameter(const std::shared_ptr<ModelAPI_Document> & thePart,
                           const std::string & theName,
index f3e92af1840391f9ac98134791929f883573c344..52626709991851da67991ae802f52753e06707fd 100644 (file)
@@ -43,6 +43,10 @@ public:
               comment, ParametersPlugin_Parameter::COMMENT_ID(), ModelAPI_AttributeString, /** Comment */
   )
 
+  /// Dump wrapped feature
+  PARAMETERSAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
 };
 
 //! Pointer on Parameter object
index 4e810d765ac3be7cf8b10a32e1b53248e5ceb68e..d9941dad112085e00d5ac943d495db508f3ea6c0 100644 (file)
@@ -23,6 +23,7 @@ from GeomDataAPI import *
 from ModelAPI import *
 import math
 import unittest
+import model
 
 __updated__ = "2015-04-27"
 
@@ -45,6 +46,7 @@ class TestParameterRename(unittest.TestCase):
         self.createFeature()
 
     def tearDown(self):
+        assert(model.checkPythonDump())
         self.aSession.closeAll()
 
     def createParameters(self):
@@ -79,13 +81,58 @@ class TestParameterRename(unittest.TestCase):
         aSketchCircle = aSketchFeature.addFeature("SketchCircle")
         anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
         aRadiusAttr = aSketchCircle.real("CircleRadius")
-        anCircleCentr.setText("x1 + 10.0", "x1 + 20.0")
-        aRadiusAttr.setText("x1")
+        anCircleCentr.setValue(10., 20.)
+        aRadiusAttr.setValue(10.)
         self.aSession.finishOperation()
 
         self.anCircleCentr = anCircleCentr
         self.aRadiusAttr = aRadiusAttr
 
+        # constraints to fix circle position and radius
+        self.aSession.startOperation()
+        # fix X coordinate
+        aDistanceConstraint1 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint1.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint1.refattr("ConstraintEntityB")
+        anOY = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOY.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOY.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.setValue(0., 100.)
+        anOYRes = modelAPI_Result(self.aDocument.objectByName("Construction", "OY"))
+        anOY.selection("External").setValue(anOYRes, anOYRes.shape())
+        anOY.execute()
+        refattrB.setObject(modelAPI_ResultConstruction(anOY.firstResult()))
+        value = aDistanceConstraint1.real("ConstraintValue")
+        value.setText("x1 + 10.0")
+        aDistanceConstraint1.execute();
+        # fix Y coordinate
+        aDistanceConstraint2 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint2.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint2.refattr("ConstraintEntityB")
+        anOX = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOX.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOX.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.setValue(100., 0.)
+        anOXRes = modelAPI_Result(self.aDocument.objectByName("Construction", "OX"))
+        anOX.selection("External").setValue(anOXRes, anOXRes.shape())
+        anOX.execute()
+        refattrB.setObject(modelAPI_ResultConstruction(anOX.firstResult()))
+        value = aDistanceConstraint2.real("ConstraintValue")
+        value.setText("x1 + 20.0")
+        aDistanceConstraint2.execute();
+        # fix radius
+        aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+        refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+        refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+        aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+        aRadiusConstrAttr.setText("x1")
+        aRadiusConstraint.execute()
+        self.aSession.finishOperation()
+
         self.assertEqual(self.anCircleCentr.x(), 160.)
         self.assertEqual(self.anCircleCentr.y(), 170.)
         self.assertEqual(aRadiusAttr.value(), 150.)
index d775d7301d117af8a18a32e6f33b247754f53486..e4ac3fee07f89eb09ef28aa5c07bfe1416029436 100644 (file)
@@ -114,7 +114,7 @@ assert (aTmValue == round(2 * math.pi, 6))
 #=========================================================================
 # Use parameters to set radius of a circle :
 # 1. Create a circle (250., 250), r = 25.
-# 2. Set a 'cr1' as text value of radius attribute
+# 2. Create a radius constraint and set 'cr1' as text value of constraint
 #=========================================================================
 aSession.startOperation()
 aSketchCircle = aSketchFeature.addFeature("SketchCircle")
@@ -125,7 +125,12 @@ aRadiusAttr.setValue(25.)
 aSession.finishOperation()
 # Apply parameter
 aSession.startOperation()
-aRadiusAttr.setText("cr1")
+aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+aRadiusConstrAttr.setText("cr1")
+aRadiusConstraint.execute()
 aSession.finishOperation()
 assert(aRadiusAttr.value() == 100.)
 #=========================================================================
@@ -158,3 +163,6 @@ assert(aLengthAttr.value() == 250.)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 5521426308a481a6ae59758b712fe18dc300e320..3343e3b86627df81ae408d67f5b727abea594927 100644 (file)
@@ -23,6 +23,7 @@ from GeomDataAPI import *
 from ModelAPI import *
 import math
 import unittest
+import model
 
 __updated__ = "2015-04-27"
 
@@ -47,6 +48,7 @@ class TestParameterRename(unittest.TestCase):
         self.createFeature()
 
     def tearDown(self):
+        assert(model.checkPythonDump())
         self.aSession.closeAll()
 
     def createParameters(self):
@@ -81,13 +83,62 @@ class TestParameterRename(unittest.TestCase):
         aSketchCircle = aSketchFeature.addFeature("SketchCircle")
         anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
         aRadiusAttr = aSketchCircle.real("CircleRadius")
-        anCircleCentr.setText("x1 + 10.0", "x1 + 20.0")
-        aRadiusAttr.setText("x1")
+        anCircleCentr.setValue(10., 20.)
+        aRadiusAttr.setValue(10.)
         self.aSession.finishOperation()
 
         self.anCircleCentr = anCircleCentr
         self.aRadiusAttr = aRadiusAttr
 
+        # constraints to fix circle position and radius
+        self.aSession.startOperation()
+        # fix X coordinate
+        aDistanceConstraint1 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint1.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint1.refattr("ConstraintEntityB")
+        anOY = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOY.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOY.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.setValue(0., 100.)
+        anOYRes = modelAPI_Result(self.aDocument.objectByName("Construction", "OY"))
+        anOY.selection("External").setValue(anOYRes, anOYRes.shape())
+        anOY.execute()
+        refattrB.setObject(modelAPI_ResultConstruction(anOY.firstResult()))
+        valueX = aDistanceConstraint1.real("ConstraintValue")
+        valueX.setText("x1 + 10.0")
+        aDistanceConstraint1.execute();
+        # fix Y coordinate
+        aDistanceConstraint2 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint2.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint2.refattr("ConstraintEntityB")
+        anOX = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOX.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOX.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.setValue(100., 0.)
+        anOXRes = modelAPI_Result(self.aDocument.objectByName("Construction", "OX"))
+        anOX.selection("External").setValue(anOXRes, anOXRes.shape())
+        anOX.execute()
+        refattrB.setObject(modelAPI_ResultConstruction(anOX.firstResult()))
+        valueY = aDistanceConstraint2.real("ConstraintValue")
+        valueY.setText("x1 + 20.0")
+        aDistanceConstraint2.execute();
+        # fix radius
+        aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+        refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+        refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+        aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+        aRadiusConstrAttr.setText("x1")
+        aRadiusConstraint.execute()
+        self.aSession.finishOperation()
+
+        self.aCircleCenterX = valueX
+        self.aCircleCenterY = valueY
+        self.aCircleRadius = aRadiusConstrAttr
+
         self.assertEqual(self.anCircleCentr.x(), 160.)
         self.assertEqual(self.anCircleCentr.y(), 170.)
         self.assertEqual(aRadiusAttr.value(), 150.)
@@ -108,9 +159,13 @@ class TestParameterRename(unittest.TestCase):
         aParam = self.dtParams["x2"]
         self.assertEqual(aParam.string("expression").value(), "a1 + y1 + 100.0")
         # Check rename in the feature
-        self.assertEqual(self.anCircleCentr.textX(), "a1 + 10.0")
-        self.assertEqual(self.anCircleCentr.textY(), "a1 + 20.0")
-        self.assertEqual(self.aRadiusAttr.text(), "a1")
+        self.assertEqual(self.aCircleCenterX.text(), "a1 + 10.0")
+        self.assertEqual(self.aCircleCenterY.text(), "a1 + 20.0")
+        self.assertEqual(self.aCircleRadius.text(), "a1")
+        # Check values
+        self.assertEqual(self.anCircleCentr.x(), 160.)
+        self.assertEqual(self.anCircleCentr.y(), 170.)
+        self.assertEqual(self.aRadiusAttr.value(), 150.)
 
     def test_rename_not_unique(self):
         # Rename to not unique name
@@ -127,9 +182,13 @@ class TestParameterRename(unittest.TestCase):
         aParam = self.dtParams["x2"]
         self.assertEqual(aParam.string("expression").value(), "x1 + y1 + 100.0")
         # Check rename in the feature (Expected: not renamed)
-        self.assertEqual(self.anCircleCentr.textX(), "x1 + 10.0")
-        self.assertEqual(self.anCircleCentr.textY(), "x1 + 20.0")
-        self.assertEqual(self.aRadiusAttr.text(), "x1")
+        self.assertEqual(self.aCircleCenterX.text(), "x1 + 10.0")
+        self.assertEqual(self.aCircleCenterY.text(), "x1 + 20.0")
+        self.assertEqual(self.aCircleRadius.text(), "x1")
+        # Check values
+        self.assertEqual(self.anCircleCentr.x(), 160.)
+        self.assertEqual(self.anCircleCentr.y(), 170.)
+        self.assertEqual(self.aRadiusAttr.value(), 150.)
 
 if __name__ == '__main__':
     unittest.main()
index f4490eb7301c5869cafa46bfb40448b33c06b1bf..6bdd0009b324aa759c1a2eb6b647313f13d68c89 100644 (file)
@@ -137,11 +137,6 @@ bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr
   /// the selection is not possible if the current feature has no presentation for the current
   /// attribute not in AIS not in results. If so, no object in current feature where make
   /// coincidence, so selection is not necessary
-  std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
-  std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      aData->attribute(attributeID()));
-  std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointAttr->pnt();
-
   bool aFoundPoint = false;
   GeomShapePtr anAISShape;
   GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(myFeature);
@@ -157,6 +152,10 @@ bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr
     return true;
 
   /// analysis of AIS
+  std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+  std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      aData->attribute(attributeID()));
+  std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointAttr->pnt();
   if (anAISShape.get())
     aFoundPoint = shapeContainsPoint(anAISShape, aPoint, mySketch);
 
@@ -275,8 +274,8 @@ bool PartSet_WidgetPoint2D::restoreValueCustom()
   std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
   std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aData->attribute(attributeID()));
-  QString aTextX = QString::fromStdString(aPoint->textX());
-  QString aTextY = QString::fromStdString(aPoint->textY());
+  QString aTextX = QString::fromStdString(aPoint->isInitialized() ? aPoint->textX() : "0");
+  QString aTextY = QString::fromStdString(aPoint->isInitialized() ? aPoint->textY() : "0");
 
   bool isDouble = false;
   double aVal = 0;
index e55cc920ff6d1a69e2de3e3e17a117fc039b082d..9460819c648d4ed791b81dc9dc3de6e09d8ac86a 100644 (file)
@@ -8,6 +8,7 @@
 #include "PartSetAPI_Part.h"
 //--------------------------------------------------------------------------------------
 #include <ModelAPI_ResultPart.h>
+#include <ModelHighAPI_Dumper.h>
 //--------------------------------------------------------------------------------------
 #include <PartSetPlugin_Duplicate.h>
 #include <PartSetPlugin_Remove.h>
@@ -29,6 +30,14 @@ std::shared_ptr<ModelAPI_Document> PartSetAPI_Part::document() const
   return std::dynamic_pointer_cast<ModelAPI_ResultPart>(defaultResult())->partDoc();
 }
 
+void PartSetAPI_Part::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  theDumper << aBase << " = model.addPart(" << aDocName << ")" << std::endl;
+}
+
 //--------------------------------------------------------------------------------------
 PartPtr addPart(const std::shared_ptr<ModelAPI_Document> & thePart)
 {
index b65fce9b9053aeae6fde879f03744bc59e4b45aa..46b1dd5586ca273aa29a25d26232398f89a1780c 100644 (file)
@@ -36,6 +36,10 @@ public:
   /// Return document
   PARTSETAPI_EXPORT
   std::shared_ptr<ModelAPI_Document> document() const;
+
+  /// Dump wrapped feature
+  PARTSETAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Part object
index 35ff9679ed2a1f4db704c3447597ad29e6a98182..4a071252f9d859c0f064974d4eaecc7c2b0e871d 100644 (file)
@@ -18,6 +18,9 @@ class FeaturesFixture(unittest.TestCase):
 
     def tearDown(self):
         model.end()
+        # assert(model.checkPythonDump())
+        # This test checks creation of High API classes from low-level.
+        # It does not set any attributes, so features invalid, and dump also invalid.
         model.reset()
 
 #-----------------------------------------------------------------------------
@@ -72,7 +75,7 @@ class FeaturesTestCase(FeaturesFixture):
         FeaturesAPI.FeaturesAPI_Rotation(self.part.addFeature("Rotation"))
         FeaturesAPI.FeaturesAPI_Translation(self.part.addFeature("Translation"))
         FeaturesAPI.FeaturesAPI_Group(self.part.addFeature("Group"))
-        
+
         import PrimitivesAPI
         PrimitivesAPI.PrimitivesAPI_Box(self.part.addFeature("Box"))
 
index ce3935cd9578b770336b0452fe938dfab241dcd7..54e4f3ccc36d68544bdd0a4534affb6e18fc92bf 100644 (file)
@@ -18,6 +18,7 @@ class FeaturesAddExtrusionFixture(unittest.TestCase):
 
     def tearDown(self):
         model.end()
+        assert(model.checkPythonDump())
         model.reset()
 
 
@@ -55,9 +56,9 @@ class FeaturesAddExtrusionTestCase(FeaturesAddExtrusionFixture):
         self.assertEqual(extrusion.toSize().value(), 10)
         self.assertEqual(extrusion.fromSize().value(), 0)
         self.assertEqual(extrusion.toObject().context(), None)
-        self.assertEqual(extrusion.toOffset().value(), 0)
+        self.assertEqual(extrusion.toOffset().isInitialized(), False)
         self.assertEqual(extrusion.fromObject().context(), None)
-        self.assertEqual(extrusion.fromOffset().value(), 0)
+        self.assertEqual(extrusion.fromOffset().isInitialized(), False)
 
     def test_add_extrusion_by_face_and_planes(self):
         # base
@@ -84,8 +85,8 @@ class FeaturesAddExtrusionTestCase(FeaturesAddExtrusionFixture):
                                        from_object, 20)
 
         self.assertEqual(extrusion.creationMethod().value(), "ByPlanesAndOffsets")
-        self.assertEqual(extrusion.toSize().value(), 0)
-        self.assertEqual(extrusion.fromSize().value(), 0)
+        self.assertEqual(extrusion.toSize().isInitialized(), False)
+        self.assertEqual(extrusion.fromSize().isInitialized(), False)
 #         self.assertEqual(extrusion.getToObject().context(),
 #                          to_sketch.result())
         self.assertEqual(extrusion.toOffset().value(), 15)
@@ -125,9 +126,9 @@ class FeaturesExtrusionTestCase(FeaturesExtrusionFixture):
         self.assertEqual(self.extrusion.toSize().value(), 15)
         self.assertEqual(self.extrusion.fromSize().value(), 20)
         self.assertEqual(self.extrusion.toObject().context(), None)
-        self.assertEqual(self.extrusion.toOffset().value(), 0)
+        self.assertEqual(self.extrusion.toOffset().isInitialized(), False)
         self.assertEqual(self.extrusion.fromObject().context(), None)
-        self.assertEqual(self.extrusion.fromOffset().value(), 0)
+        self.assertEqual(self.extrusion.fromOffset().isInitialized(), False)
 
     def test_extrusion_set_planes_and_offsets(self):
         # to
@@ -145,6 +146,9 @@ class FeaturesExtrusionTestCase(FeaturesExtrusionFixture):
 
         to_object = to_sketch.selectFace()[0]
         from_object = from_sketch.selectFace()[0]
+
+        self.part.moveFeature(self.extrusion.feature(), from_sketch.feature())
+
         self.extrusion.setPlanesAndOffsets(to_object, 15, from_object, 20)
 
 
index 0a09c80486fd83f5fa37a071ba75f9ea86651210..90d9af9f6d3b08c4061ee3c966df2cb516ad495a 100644 (file)
@@ -18,6 +18,7 @@ class FeaturesAddRevolutionFixture(unittest.TestCase):
 
     def tearDown(self):
         model.end()
+        assert(model.checkPythonDump())
         model.reset()
 
 
index d76377736c7a7c41150b22c65a7245f7f2def4ea..0a204cf0bdbb02f195c4bfb56b0d505ae1fc1e9b 100644 (file)
@@ -9,6 +9,7 @@ class ModelTestCase(unittest.TestCase):
 
     def tearDown(self):
         model.end()
+        assert(model.checkPythonDump())
 
     def test_add_sketch(self):
         plane = model.defaultPlane("XOY")
index 826493a48c1ca5d6b7062397f4e071bc72523d00..d41f7ddcf309dcfa4e1c48e9c628bd15bb11a959 100644 (file)
@@ -14,4 +14,5 @@ class SketcherTestCase(unittest.TestCase):
 
     def tearDown(self):
         model.end()
+        assert(model.checkPythonDump())
         model.reset()
index 9e440ab32cd6bd816eaab47a1d29b7a65a491e1c..859773b01d7297187d17d457b589922d697eacf7 100644 (file)
@@ -5,7 +5,7 @@ from TestSketcher import SketcherTestCase
 class SketcherSetParallel(SketcherTestCase):
     def runTest(self):
         l1 = self.sketch.addLine(0, 0, 0, 1)
-        l2 = self.sketch.addLine(0, 1, 1, 1)
+        l2 = self.sketch.addLine(0, 1, 1, 0)
         self.sketch.setParallel(l1, l2)
         model.do()
 
index 10eb81b079664b3b23ba289f4f132395760cf764..5ef2f3c459fe26a2f0071d94dbfa91a04b4ec834 100644 (file)
@@ -20,10 +20,10 @@ mypart = model.addPart(mypartset).document()
 
 mybase = model.addSketch(mypart, model.defaultPlane("XOY"))
 
-l1 = mybase.addLine(0, 0, 0, 1)
-l2 = mybase.addLine(0, 1, 1, 1)
-l3 = mybase.addLine(1, 1, 1, 0)
-l4 = mybase.addLine(1, 0, 0, 0)
+l1 = mybase.addLine(0, 0, 0, 25)
+l2 = mybase.addLine(0, 25, 25, 25)
+l3 = mybase.addLine(25, 25, 25, 0)
+l4 = mybase.addLine(25, 0, 0, 0)
 
 mybase.setCoincident(l1.endPoint(), l2.startPoint())
 mybase.setCoincident(l2.endPoint(), l3.startPoint())
@@ -35,29 +35,37 @@ mybase.setParallel(l2, l4)
 
 mybase.setPerpendicular(l1, l4)
 
+mybase.setVertical(l1)
+mybase.setFixed(l1.startPoint())
+
 mywidth = mybase.setLength(l1, 50)
 mylength = mybase.setDistance(l1.startPoint(), l3, 50)
+model.do()
 
 # Creating the extrusion
 
 mybox = model.addExtrusion(mypart, mybase.selectFace(), 50)
+model.do()
 
 # Creating a cylinder on a face of the box
 
 thisface = "Extrusion_1_1/Generated_Face_2"
-thisxmin = "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2"
-thisxmax = "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1"
-thiszmin = "Sketch_1/Edge5_1"
+thisxmax = "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2"
 thiszmax = "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1_1"
 
 mystand = model.addSketch(mypart, thisface)
 
 c1 = mystand.addCircle(0, 25, 5)
-mystand.setDistance(c1.center(), mystand.addLine(thisxmin), 10)
-mystand.setDistance(c1.center(), mystand.addLine(thiszmax), 10)
+l1 = mystand.addLine(thisxmax)
+l2 = mystand.addLine(thiszmax)
+model.do()
+mystand.setDistance(c1.center(), l1, 10)
+mystand.setDistance(c1.center(), l2, 10)
+model.do()
 
 
 myboss = model.addExtrusion(mypart, mystand.selectFace(), -5)
+model.do()
 
 # Subtracting the cylinder to the box
 
@@ -69,5 +77,8 @@ model.end()
 
 model.begin()
 mybase.setValue(mylength, 100)
+model.do()
 mybox.setSize(80)
 model.end()
+
+assert(model.checkPythonDump())
index 2086b83c0c5775334e4c4da3647be42bdd7de2f2..1be7e05fde0aad6cf8db3afeb863997ede6693a9 100644 (file)
@@ -22,9 +22,9 @@ mypart = model.addPart(mypartset).document()
 mybase = model.addSketch(mypart, model.defaultPlane("XOY"))
 
 p1 = geom.Pnt2d(0, 0)
-p2 = geom.Pnt2d(0, 1)
-p3 = geom.Pnt2d(1, 1)
-p4 = geom.Pnt2d(1, 0)
+p2 = geom.Pnt2d(0, 25)
+p3 = geom.Pnt2d(25, 25)
+p4 = geom.Pnt2d(25, 0)
 
 line = model.addPolygon(mybase, p1, p2, p3, p4)
 
@@ -32,13 +32,17 @@ mybase.setParallel(line[0], line[2])
 mybase.setParallel(line[1], line[3])
 mybase.setPerpendicular(line[0], line[3])
 
+mybase.setVertical(line[0])
+mybase.setFixed(line[0].startPoint())
+
 mywidth = mybase.setLength(line[0], 50)
 mylength = mybase.setDistance(line[0].startPoint(), line[2], 50)
-
+model.do()
 
 # Creating the extrusion
 
 mybox = model.addExtrusion(mypart, mybase.selectFace(), 50)
+model.do()
 
 
 # Creating a cylinder on a face of the box
@@ -51,9 +55,10 @@ mystand = model.addSketch(mypart, thisface)
 circle = mystand.addCircle(0, 25, 5)
 mystand.setDistance(circle.center(), mystand.addLine(thisxmin), 10)
 mystand.setDistance(circle.center(), mystand.addLine(thiszmax), 10)
+model.do()
 
 myboss = model.addExtrusion(mypart, mystand.selectFace(), -5)
-
+model.do()
 
 # Subtracting the cylinder to the box
 
@@ -65,5 +70,8 @@ model.end()
 
 model.begin()
 mybase.setValue(mylength, 100)
-mybox.setSize(20)
+model.do()
+mybox.setSize(40)
 model.end()
+
+assert(model.checkPythonDump())
index edfc0b3e5857079d31b8066809435d0e2f1361d9..898e83bfe8378d063ccf5d39b762cd8aabecc3b2 100644 (file)
@@ -22,3 +22,4 @@ mypart = model.addPart(mypartset).document()
 extension.addBoxScript( mypart, 10, 20, 30 )
 model.end()
 
+assert(model.checkPythonDump())
\ No newline at end of file
index c84684334f4e982325f2b277427adb5a6478c142..f0c236b51e0987dfc0132595c06dd216bd8f1117 100644 (file)
@@ -218,3 +218,5 @@ b4 = body_4()
 
 boolean = model.addFuse(part, boolean.result() + b4.result())
 model.end()
+
+assert(model.checkPythonDump())
index 58ddaac9994c1eec692fbba35cbcb39b525e09b8..fc24671cd8fb42eaf4e30429ee10d085ef583f28 100644 (file)
@@ -13,6 +13,7 @@ from roots     import *
 
 # Built-in features
 
+from build import *
 from sketcher import *
 from connection import *
 from construction import *
diff --git a/src/PythonAPI/model/build/__init__.py b/src/PythonAPI/model/build/__init__.py
new file mode 100644 (file)
index 0000000..1556669
--- /dev/null
@@ -0,0 +1,5 @@
+"""Package for Build plugin for the Parametric Geometry API of the Modeler.
+"""
+
+from BuildAPI import addVertex, addEdge, addWire, addFace, addShell
+from BuildAPI import addSubShapes
diff --git a/src/PythonAPI/model/dump/DumpAssistant.py b/src/PythonAPI/model/dump/DumpAssistant.py
new file mode 100644 (file)
index 0000000..b4a27ad
--- /dev/null
@@ -0,0 +1,67 @@
+"""Package for dumping purposes.
+"""
+
+import ModelHighAPI
+
+import ModelAPI
+import SketchAPI
+
+import sys
+import inspect
+
+def singleton(cls):
+    instance = cls()
+    instance.__call__ = lambda: instance
+    return instance
+
+
+## @ingroup CPPHighAPI
+#  Collect information about features that may be dumped and stores the model as a Python script
+@singleton
+class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
+
+    ## Constructor
+    def __init__(self):
+        ModelHighAPI.ModelHighAPI_Dumper.__init__(self)
+        ModelHighAPI.ModelHighAPI_Dumper.setInstance(self)
+        self.collectFeatures()
+
+    ## Collect feature wrappers, which allow dumping (have method dump)
+    def collectFeatures(self):
+        self.myFeatures = {}
+        for aModule in sys.modules:
+            for aName, anObj in inspect.getmembers(sys.modules[aModule], inspect.isclass):
+                if issubclass(anObj, ModelHighAPI.ModelHighAPI_Interface) and hasattr(anObj, "ID") and anObj.dump != ModelHighAPI.ModelHighAPI_Interface.dump:
+                    self.myFeatures[anObj.ID()] = anObj
+
+    ## Create wrapper for a given feature and dump it
+    def dumpFeature(self, theFeature, theForce):
+        aFeatureKind = theFeature.getKind()
+        if aFeatureKind in self.myFeatures:
+            # Dump only feature created by user (in history).
+            # For all other features, just keep their name.
+            if theForce or theFeature.isInHistory():
+                self.myFeatures[aFeatureKind](theFeature).dump(self)
+            else:
+                self.name(theFeature)
+                self.clearNotDumped()
+        else:
+            # Probably the feature is a constraint, try to dump it with SketchAPI_Constraint.
+            # In case of theFeature is not a constraint, it will not be dumped.
+            self.myFeatures[SketchAPI.SketchAPI_Constraint.ID()](theFeature).dump(self)
+
+    ## Dump all parameters
+    def dumpParameter(self, theFeature):
+        aFeatureKind = theFeature.getKind()
+        if aFeatureKind == "Parameter" and aFeatureKind in self.myFeatures:
+            self.myFeatures[aFeatureKind](theFeature).dump(self)
+
+    ## Return getter for specified attribute
+    def attributeGetter(self, theFeature, theAttrName):
+        aFeatureKind = theFeature.getKind()
+        if aFeatureKind in self.myFeatures:
+            return self.myFeatures[aFeatureKind](theFeature).attributeGetter(theAttrName)
+        return std_string()
+
+# Instance of dumper
+dumper = DumpAssistant
\ No newline at end of file
diff --git a/src/PythonAPI/model/dump/__init__.py b/src/PythonAPI/model/dump/__init__.py
new file mode 100644 (file)
index 0000000..78a1de4
--- /dev/null
@@ -0,0 +1,4 @@
+"""Package for dumping purposes.
+"""
+
+from DumpAssistant import *
index 9d1dd8d174aa7ae83757d9edc0af96c7780dc378..f0b31740715257ac1a46573634ed93d2027910fc 100644 (file)
@@ -2,13 +2,9 @@
 """
 
 from FeaturesAPI import addPlacement, addRotation, addTranslation
-
-from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addFill
-
-from FeaturesAPI import addPartition
-
 from FeaturesAPI import addExtrusion, addExtrusionCut, addExtrusionFuse
 from FeaturesAPI import addRevolution, addRevolutionCut, addRevolutionFuse
-
+from FeaturesAPI import addPipe
+from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addFill
+from FeaturesAPI import addIntersection, addPartition, addUnion, addRemoveSubShapes
 from FeaturesAPI import addGroup, addRecover
-
index e33077b31af8856afe171b1e159ff670c06d2359..cf963610652599bb6a658c4c4504fe8f456e2004 100644 (file)
@@ -2,8 +2,10 @@
 """
 
 from ModelHighAPI import moduleDocument, activeDocument
-from ModelHighAPI import defaultPlane
+from ModelHighAPI import defaultPlane, standardPlane
 from ModelHighAPI import begin, end
 from ModelHighAPI import apply as do
 from ModelHighAPI import undo, redo
-from ModelHighAPI import reset
\ No newline at end of file
+from ModelHighAPI import reset
+from ModelHighAPI import ModelHighAPI_Selection as selection
+from ModelHighAPI import checkPythonDump as checkPythonDump
index 7bfd90b7617c71dccc7c886556bb3459845ea765..18f4b24f6223444fa28cb66f78c4772ed64c7296 100644 (file)
@@ -67,15 +67,22 @@ class BoxFeature(model.Feature):
 
         line = model.addPolygon(self.base, p1, p2, p3, p4)
 
-        self.base.setParallel(line[0], line[2])
-        self.base.setParallel(line[1], line[3])
-        self.base.setPerpendicular(line[0], line[3])
+        self.base.setFixed(line[0].startPoint())
+        self.base.setVertical(line[0])
 
         # Setting the size of the base with default values
         # Width
-        self.width = self.base.setLength(line[0], 50)  # Keeps the constraint for edition
+        self.width = self.base.setLength(line[3], 50)  # Keeps the constraint for edition
         # Length
-        self.length = self.base.setLength(line[3], 50)  # Keeps the constraint for edition
+        self.length = self.base.setLength(line[0], 50)  # Keeps the constraint for edition
+
+        # Keeping the rectangle
+        self.base.setParallel(line[0], line[2])
+        self.base.setParallel(line[1], line[3])
+        self.base.setPerpendicular(line[0], line[3])
+
+        # execute sketch
+        model.do()
 
         # Creating the extrusion (the box) at default size
         # A box result
index 12918c9917f84533de9dfe035e4986663eefdd1f..18db87fc55a7507001a22d4a3a258095c5a5bb9b 100644 (file)
@@ -6,6 +6,7 @@ SET(PROJECT_HEADERS
   SketchAPI.h
   SketchAPI_Arc.h
   SketchAPI_Circle.h
+  SketchAPI_Constraint.h
   SketchAPI_IntersectionPoint.h
   SketchAPI_Line.h
   SketchAPI_Mirror.h
@@ -21,6 +22,7 @@ SET(PROJECT_HEADERS
 SET(PROJECT_SOURCES
   SketchAPI_Arc.cpp
   SketchAPI_Circle.cpp
+  SketchAPI_Constraint.cpp
   SketchAPI_IntersectionPoint.cpp
   SketchAPI_Line.cpp
   SketchAPI_Mirror.cpp
@@ -44,6 +46,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/ModelAPI
   ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
   ${PROJECT_SOURCE_DIR}/src/ModelHighAPI
+  ${PROJECT_SOURCE_DIR}/src/SketcherPrs
 )
 
 # Plugin headers dependency
index 5c4c6353479e9e806237e65fecd5dd2e021a582e..c9638a205a48b7f4d9dd17020a96d8717b1f0013 100644 (file)
@@ -22,6 +22,7 @@
 // shared pointers
 %shared_ptr(SketchAPI_Arc)
 %shared_ptr(SketchAPI_Circle)
+%shared_ptr(SketchAPI_Constraint)
 %shared_ptr(SketchAPI_IntersectionPoint)
 %shared_ptr(SketchAPI_Line)
 %shared_ptr(SketchAPI_Mirror)
 %shared_ptr(SketchAPI_Rotation)
 %shared_ptr(SketchAPI_Translation)
 
-// TODO(spo): move typemaps into ModelHighAPI package
-
-// fix compilarion error: â€˜res*’ was not declared in this scope
-%typemap(freearg) const std::list<ModelHighAPI_RefAttr> & {}
-%typemap(freearg) const std::list<std::shared_ptr<ModelAPI_Object> > & {}
-
-%typemap(in) const std::list<ModelHighAPI_RefAttr> & (std::list<ModelHighAPI_RefAttr> temp) {
+%typemap(in) const ModelHighAPI_RefAttr & (ModelHighAPI_RefAttr temp) {
   std::shared_ptr<ModelAPI_Attribute> * temp_attribute;
+  std::shared_ptr<ModelAPI_Object> * temp_object;
+  std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
+  ModelHighAPI_Selection* temp_selection;
   int newmem = 0;
-  if (PySequence_Check($input)) {
-    for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
-      PyObject * item = PySequence_GetItem($input, i);
-      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_attribute, $descriptor(std::shared_ptr<ModelAPI_Attribute> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
-        if (!temp_attribute) {
-          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_RefAttr, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
-          return NULL;
-        }
-        temp.push_back(ModelHighAPI_RefAttr(*temp_attribute));
-        if (newmem & SWIG_CAST_NEW_MEMORY) {
-          delete temp_attribute;
-        }
-      }
-      Py_DECREF(item);
+  if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_selection, $descriptor(ModelHighAPI_Selection*), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (!temp_selection) {
+      PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_RefAttr, ModelHighAPI_Selection, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+      return NULL;
+    }
+    temp = ModelHighAPI_RefAttr(std::shared_ptr<ModelAPI_Object>(temp_selection->resultSubShapePair().first));
+    if (newmem & SWIG_CAST_NEW_MEMORY) {
+      delete temp_selection;
     }
     $1 = &temp;
+  } else
+  if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_attribute, $descriptor(std::shared_ptr<ModelAPI_Attribute> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (!temp_attribute) {
+      PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_RefAttr, ModelHighAPI_Selection, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+      return NULL;
+    }
+    temp = ModelHighAPI_RefAttr(*temp_attribute);
+    if (newmem & SWIG_CAST_NEW_MEMORY) {
+      delete temp_attribute;
+    }
+    $1 = &temp;
+  } else
+  if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_object, $descriptor(std::shared_ptr<ModelAPI_Object> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (!temp_object) {
+      PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_RefAttr, ModelHighAPI_Selection, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+      return NULL;
+    }
+    temp = ModelHighAPI_RefAttr(*temp_object);
+    if (newmem & SWIG_CAST_NEW_MEMORY) {
+      delete temp_object;
+    }
+    $1 = &temp;
+  } else
+  if ((SWIG_ConvertPtrAndOwn($input, (void **)&temp_interface, $descriptor(std::shared_ptr<ModelHighAPI_Interface> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+    if (!temp_interface) {
+      PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_RefAttr, ModelHighAPI_Selection, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+      return NULL;
+    }
+    temp = ModelHighAPI_RefAttr(*temp_interface);
+    if (newmem & SWIG_CAST_NEW_MEMORY) {
+      delete temp_interface;
+    }
+    $1 = &temp;
+  } else
+  if ((SWIG_ConvertPtr($input, (void **)&$1, $1_descriptor, SWIG_POINTER_EXCEPTION)) == 0) {
   } else {
-    PyErr_SetString(PyExc_ValueError, "argument must be list of ModelHighAPI_RefAttr, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
+    PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_RefAttr, ModelHighAPI_Selection, ModelHighAPI_Interface, ModelAPI_Attribute or ModelAPI_Object.");
     return NULL;
   }
 }
 %typemap(in) const std::list<std::shared_ptr<ModelAPI_Object> > & (std::list<std::shared_ptr<ModelAPI_Object> > temp) {
   std::shared_ptr<ModelAPI_Object> * temp_object;
   std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
+  ModelHighAPI_Selection* temp_selection;
   int newmem = 0;
   if (PySequence_Check($input)) {
     for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
       PyObject * item = PySequence_GetItem($input, i);
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_selection, $descriptor(ModelHighAPI_Selection*), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_selection) {
+          PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Interface, ModelHighAPI_Selection or ModelAPI_Object.");
+          return NULL;
+        }
+        temp.push_back(temp_selection->resultSubShapePair().first);
+        if (newmem & SWIG_CAST_NEW_MEMORY) {
+          delete temp_selection;
+        }
+      } else
       if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_object, $descriptor(std::shared_ptr<ModelAPI_Object> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
         if (!temp_object) {
-          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_Interface or ModelAPI_Object.");
+          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_Interface, ModelHighAPI_Selection or ModelAPI_Object.");
           return NULL;
         }
         temp.push_back(*temp_object);
       } else
       if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_interface, $descriptor(std::shared_ptr<ModelHighAPI_Interface> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
         if (!temp_interface) {
-          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_Interface or ModelAPI_Object.");
+          PyErr_SetString(PyExc_TypeError, "argument must be list of ModelHighAPI_Interface, ModelHighAPI_Selection or ModelAPI_Object.");
           return NULL;
         }
         temp.push_back((*temp_interface)->defaultResult());
 %include "SketchAPI_Rectangle.h"
 %include "SketchAPI_Rotation.h"
 %include "SketchAPI_Sketch.h"
+%include "SketchAPI_Constraint.h"
index 438c28d9ff094c2e7208ce93e499adfd444228ce..628e43238efb0e887ea83ca98c464b6e22934870 100644 (file)
@@ -9,6 +9,7 @@
 #include <GeomAPI_Pnt2d.h>
 
 #include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 
@@ -232,3 +233,37 @@ void SketchAPI_Arc::setAngle(double theAngle)
 
   execute();
 }
+
+//==================================================================================================
+void SketchAPI_Arc::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  if (isCopy())
+    return; // no need to dump copied feature
+
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->context()) {
+    // arc is external
+    theDumper << aBase << " = " << aSketchName << ".addArc(" << anExternal << ")" << std::endl;
+  } else {
+    AttributeStringPtr aType = arcType();
+    if (aType->value() == SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()) {
+      // arc given by center and start, end points
+      theDumper << aBase << " = " << aSketchName << ".addArc(" << center() << ", "
+                << startPoint() << ", " << endPoint() << ", " << inversed() << ")" << std::endl;
+    } else if (aType->value() == SketchPlugin_Arc::ARC_TYPE_THREE_POINTS()) {
+      // arc given by three points
+      theDumper << aBase << " = " << aSketchName << ".addArc(" << startPoint() << ", "
+                << endPoint() << ", " << passedPoint() << ")" << std::endl;
+    } else {
+      // tangent arc
+      AttributeRefAttrPtr aTangentPoint = tangentPoint();
+      theDumper << aBase << " = " << aSketchName << ".addArc("
+                << aTangentPoint << ", " << endPoint() << ", " << inversed() << ")" << std::endl;
+    }
+  }
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+}
index 4cff2004402bbd5ce9f7a7c8e59b296cc59f200d..5fc0e5b0d7a9d066f0438e6362b0c6f89c1a86dc 100644 (file)
@@ -150,6 +150,10 @@ public:
   /// Set angle.
   SKETCHAPI_EXPORT
   void setAngle(double theAngle);
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Arc object.
index d8a07f13b787bcf4e9948b1b901221b2e00558ab..9cac0bd31cbf58bee789d7d87dd9fe9d78f92ba7 100644 (file)
@@ -9,6 +9,7 @@
 #include <GeomAPI_Pnt2d.h>
 
 #include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 
@@ -235,3 +236,32 @@ void SketchAPI_Circle::setThirdPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePo
 
   execute();
 }
+
+//==================================================================================================
+void SketchAPI_Circle::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  if (isCopy())
+    return; // no need to dump copied feature
+
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->context()) {
+    // circle is external
+    theDumper << aBase << " = " << aSketchName << ".addCircle(" << anExternal << ")" << std::endl;
+  } else {
+    AttributeStringPtr aType = circleType();
+    if (aType->value() == SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS()) {
+      // circle given by center and radius
+      theDumper << aBase << " = " << aSketchName << ".addCircle("
+                << center() << ", " << radius() << ")" << std::endl;
+    } else {
+      // circle given by three points
+      theDumper << aBase << " = " << aSketchName << ".addCircle(" << firstPoint() << ", "
+                << secondPoint() << ", " << thirdPoint() << ")" << std::endl;
+    }
+  }
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+}
index b4332c67553898e49db83fed180a4f378381739e..76c7f1fac50101c274614bbdf36bf23f2b0be253 100644 (file)
@@ -137,6 +137,10 @@ public:
   /// Set third point.
   SKETCHAPI_EXPORT
   void setThirdPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 /// Pointer on Circle object.
diff --git a/src/SketchAPI/SketchAPI_Constraint.cpp b/src/SketchAPI/SketchAPI_Constraint.cpp
new file mode 100644 (file)
index 0000000..617a0bf
--- /dev/null
@@ -0,0 +1,172 @@
+// Name   : SketchAPI_Constraint.cpp
+// Purpose: 
+//
+// History:
+// 08/08/16 - Artem ZHIDKOV - Creation of the file
+
+#include "SketchAPI_Constraint.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <SketchPlugin_Constraint.h>
+#include <SketchPlugin_ConstraintAngle.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintCollinear.h>
+#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintEqual.h>
+#include <SketchPlugin_ConstraintHorizontal.h>
+#include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintMiddle.h>
+#include <SketchPlugin_ConstraintParallel.h>
+#include <SketchPlugin_ConstraintPerpendicular.h>
+#include <SketchPlugin_ConstraintRadius.h>
+#include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_ConstraintTangent.h>
+#include <SketchPlugin_ConstraintVertical.h>
+
+#include <SketcherPrs_Tools.h>
+
+SketchAPI_Constraint::SketchAPI_Constraint(
+    const std::shared_ptr<ModelAPI_Feature> & theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+  ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
+  if (aConstraint)
+    initialize();
+}
+
+SketchAPI_Constraint::~SketchAPI_Constraint()
+{
+}
+
+bool SketchAPI_Constraint::initialize()
+{
+  if (!feature()) {
+    throwException("Constraint exception: The feature is NULL.");
+    return false;
+  }
+  return true;
+}
+
+static const std::string& constraintTypeToSetter(const std::string& theType)
+{
+  if (theType == SketchPlugin_ConstraintCoincidence::ID()) {
+    static const std::string COINCIDENCE_SETTER("setCoincident");
+    return COINCIDENCE_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintAngle::ID()) {
+    static const std::string ANGLE_SETTER("setAngle");
+    return ANGLE_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintCollinear::ID()) {
+    static const std::string COLLINEAR_SETTER("setCollinear");
+    return COLLINEAR_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintDistance::ID()) {
+    static const std::string DISTANCE_SETTER("setDistance");
+    return DISTANCE_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintEqual::ID()) {
+    static const std::string EQUAL_SETTER("setEqual");
+    return EQUAL_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintHorizontal::ID()) {
+    static const std::string HORIZONTAL_SETTER("setHorizontal");
+    return HORIZONTAL_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintLength::ID()) {
+    static const std::string LENGTH_SETTER("setLength");
+    return LENGTH_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintMiddle::ID()) {
+    static const std::string MIDDLE_SETTER("setMiddlePoint");
+    return MIDDLE_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintParallel::ID()) {
+    static const std::string PARALLEL_SETTER("setParallel");
+    return PARALLEL_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintPerpendicular::ID()) {
+    static const std::string PERPENDICULAR_SETTER("setPerpendicular");
+    return PERPENDICULAR_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintRadius::ID()) {
+    static const std::string RADIUS_SETTER("setRadius");
+    return RADIUS_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintRigid::ID()) {
+    static const std::string FIXED_SETTER("setFixed");
+    return FIXED_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintTangent::ID()) {
+    static const std::string TANGENT_SETTER("setTangent");
+    return TANGENT_SETTER;
+  }
+  if (theType == SketchPlugin_ConstraintVertical::ID()) {
+    static const std::string VERTICAL_SETTER("setVertical");
+    return VERTICAL_SETTER;
+  }
+
+  static const std::string DUMMY;
+  return DUMMY;
+}
+
+static std::string angleTypeToString(int theAngleType)
+{
+  switch (theAngleType) {
+  case SketcherPrs_Tools::ANGLE_COMPLEMENTARY:
+    return std::string("Complementary");
+  case SketcherPrs_Tools::ANGLE_BACKWARD:
+    return std::string("Backward");
+  default:
+    break;
+  }
+  return std::string();
+}
+
+void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(aBase);
+  if (!aConstraint)
+    return; // dump constraints only
+
+  // do not need to dump "Fixed" constraint for external object
+  if (aConstraint->getKind() == SketchPlugin_ConstraintRigid::ID()) {
+    AttributeRefAttrPtr aRefAttr = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
+    std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+        std::dynamic_pointer_cast<SketchPlugin_Feature>(
+        ModelAPI_Feature::feature(aRefAttr->object()));
+    if (!aSketchFeature || aSketchFeature->isExternal())
+      return;
+  }
+
+  const std::string& aSetter = constraintTypeToSetter(aConstraint->getKind());
+  if (aSetter.empty())
+    return; // incorrect constraint type
+  bool isAngle = aConstraint->getKind() == SketchPlugin_ConstraintAngle::ID();
+  std::string aSetterSuffix;
+  if (isAngle)
+    aSetterSuffix = angleTypeToString(aConstraint->integer(
+                    SketchPlugin_ConstraintAngle::TYPE_ID())->value());
+
+  const std::string& aSketchName = theDumper.parentName(aConstraint);
+  theDumper << aBase << " = " << aSketchName << "." << aSetter << aSetterSuffix << "(";
+
+  bool isFirstAttr = true;
+  for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
+    AttributeRefAttrPtr aRefAttr = aConstraint->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+    if (aRefAttr && aRefAttr->isInitialized()) {
+      theDumper << (isFirstAttr ? "" : ", ") << aRefAttr;
+      isFirstAttr = false;
+    }
+  }
+
+  AttributeDoublePtr aValueAttr = aConstraint->real(
+      isAngle ? SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID() :SketchPlugin_Constraint::VALUE());
+  if (aValueAttr && aValueAttr->isInitialized())
+    theDumper << ", " << aValueAttr;
+
+  theDumper << ")" << std::endl;
+}
diff --git a/src/SketchAPI/SketchAPI_Constraint.h b/src/SketchAPI/SketchAPI_Constraint.h
new file mode 100644 (file)
index 0000000..2f87652
--- /dev/null
@@ -0,0 +1,48 @@
+// Name   : SketchAPI_Constraint.h
+// Purpose: 
+//
+// History:
+// 08/08/16 - Artem ZHIDKOV - Creation of the file
+
+#ifndef SRC_SKETCHAPI_SKETCHAPI_CONSTRAINT_H_
+#define SRC_SKETCHAPI_SKETCHAPI_CONSTRAINT_H_
+
+#include "SketchAPI.h"
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+#include <ModelHighAPI_RefAttr.h>
+
+#include <SketchPlugin_Constraint.h>
+
+/**\class SketchAPI_Constraint
+ * \ingroup CPPHighAPI
+ * \brief Interface for Constraint feature
+ */
+class SketchAPI_Constraint : public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values
+  SKETCHAPI_EXPORT
+  explicit SketchAPI_Constraint(const std::shared_ptr<ModelAPI_Feature> & theFeature);
+
+  /// Destructor
+  SKETCHAPI_EXPORT
+  virtual ~SketchAPI_Constraint();
+
+  static std::string ID()
+  {
+    static const std::string DUMMY;
+    return DUMMY;
+  }
+  virtual std::string getID() { return ID(); }
+
+  SKETCHAPI_EXPORT
+  bool initialize();
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+#endif
index 75ddb603ce5d90885d4bd94a725be5efa345c1d2..ce33717b16b1287ae120f1939f6f98a03866079f 100644 (file)
@@ -9,6 +9,7 @@
 //--------------------------------------------------------------------------------------
 #include <GeomAPI_Pnt2d.h>
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
@@ -60,3 +61,14 @@ void SketchAPI_IntersectionPoint::setByExternalLineName(const std::string & theE
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_IntersectionPoint::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr aLine = externalLine();
+  theDumper << aBase << " = " << aSketchName << ".addIntersectionPoint(" << aLine << ")" << std::endl;
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+}
index 7f0bdfbd86fbb4502cedb33f64a3c75b68353c45..4460f3df577daf76a3cbe9aa793de663baa08232 100644 (file)
@@ -50,6 +50,10 @@ public:
   /// Set by external name
   SKETCHAPI_EXPORT
   void setByExternalLineName(const std::string & theExternalLineName);
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on IntersectionPoint object
index d6be6744de7bd96ae6d6bbc202520c2f5949a114..1e5a2da04fc01a250631b6940ea62338ae6df9c1 100644 (file)
@@ -9,6 +9,7 @@
 //--------------------------------------------------------------------------------------
 #include <GeomAPI_Pnt2d.h>
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
@@ -127,3 +128,23 @@ void SketchAPI_Line::setEndPoint(const std::shared_ptr<GeomAPI_Pnt2d> & thePoint
 
 //--------------------------------------------------------------------------------------
 
+void SketchAPI_Line::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  if (isCopy())
+    return; // no need to dump copied feature
+
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->context()) {
+    // line is external
+    theDumper << aBase << " = " << aSketchName << ".addLine(" << anExternal << ")" << std::endl;
+  } else {
+    // segment given by its points
+    theDumper << aBase << " = " << aSketchName << ".addLine("
+              << startPoint() << ", " << endPoint() << ")" << std::endl;
+  }
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+}
index c2f3d98f5dc866d4cae2c8b0f70cd734e3986555..23f9042400ca9378001c450ac8b85d4cead7a331 100644 (file)
@@ -87,6 +87,10 @@ public:
   /// Set end point
   SKETCHAPI_EXPORT
   void setEndPoint(const std::shared_ptr<GeomAPI_Pnt2d> & thePoint);
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Line object
index d6166e79c594a2d8b81f46f0f75abf2b5bef6cf6..32abfc90bf3ddebb0f6ff9a1e36acc88dfcebab0 100644 (file)
@@ -7,12 +7,13 @@
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_Mirror.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 SketchAPI_Mirror::SketchAPI_Mirror(
     const std::shared_ptr<ModelAPI_Feature> & theFeature)
-: SketchAPI_SketchEntity(theFeature)
+: ModelHighAPI_Interface(theFeature)
 {
   initialize();
 }
@@ -21,7 +22,7 @@ SketchAPI_Mirror::SketchAPI_Mirror(
     const std::shared_ptr<ModelAPI_Feature> & theFeature,
     const ModelHighAPI_RefAttr & theMirrorLine,
     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects)
-: SketchAPI_SketchEntity(theFeature)
+: ModelHighAPI_Interface(theFeature)
 {
   if (initialize()) {
     fillAttribute(theMirrorLine, mirrorLine());
@@ -37,3 +38,14 @@ SketchAPI_Mirror::~SketchAPI_Mirror()
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Mirror::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeRefAttrPtr aMirrorLine = mirrorLine();
+  AttributeRefListPtr aMirrorObjects = mirrorList();
+  theDumper << aBase << " = " << aSketchName << ".addMirror(" << aMirrorLine << ", "
+            << aMirrorObjects << ")" << std::endl;
+}
index 9cd2d54887bcfc74fb185d4589a29050462d131b..ab77061ea8671ad68ffb505cd9b2061d58201e15 100644 (file)
@@ -14,7 +14,8 @@
 
 #include <SketchPlugin_ConstraintMirror.h>
 
-#include "SketchAPI_SketchEntity.h"
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
 //--------------------------------------------------------------------------------------
 class ModelAPI_Object;
 class ModelHighAPI_RefAttr;
@@ -23,7 +24,7 @@ class ModelHighAPI_RefAttr;
  * \ingroup CPPHighAPI
  * \brief Interface for Mirror feature
  */
-class SketchAPI_Mirror : public SketchAPI_SketchEntity
+class SketchAPI_Mirror : public ModelHighAPI_Interface
 {
 public:
   /// Constructor without values
@@ -45,6 +46,8 @@ public:
               mirroredObjects, SketchPlugin_ConstraintMirror::ENTITY_C(), ModelAPI_AttributeRefList, /** Mirrored objects */
   )
 
+  /// Dump wrapped feature
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Mirror object
index c133a74c08b8e51cad0f5c1293b758aeff1f591a..346ae4442983e89735d5f97afc67f2aa128e8232 100644 (file)
@@ -9,6 +9,7 @@
 //--------------------------------------------------------------------------------------
 #include <GeomAPI_Pnt2d.h>
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
@@ -96,3 +97,24 @@ void SketchAPI_Point::setByExternalName(const std::string & theExternalName)
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  if (isCopy())
+    return; // no need to dump copied feature
+
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->context()) {
+    // point is external
+    theDumper << aBase << " = " << aSketchName << ".addPoint(" << anExternal << ")" << std::endl;
+  } else {
+    // point given by coordinates
+    std::shared_ptr<GeomDataAPI_Point2D> aPoint = coordinates();
+    theDumper << aBase << " = " << aSketchName << ".addPoint(" << aPoint << ")" << std::endl;
+  }
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+}
index 1596b0f9b5c8dc6d676856e79f0c080628b623c5..a680aacc6d69e6b2160071c9a4407cc8a0a60b93 100644 (file)
@@ -68,6 +68,10 @@ public:
   /// Set by external name
   SKETCHAPI_EXPORT
   void setByExternalName(const std::string & theExternalName);
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Point object
index 7ac33fc9193e46eed7cdfb64fd5ce972453e55e5..3a2f457025483a0150cd9e878d5f30b14a492655 100644 (file)
@@ -7,6 +7,8 @@
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_Projection.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 SketchAPI_Projection::SketchAPI_Projection(
@@ -26,6 +28,16 @@ SketchAPI_Projection::SketchAPI_Projection(
   }
 }
 
+SketchAPI_Projection::SketchAPI_Projection(
+    const std::shared_ptr<ModelAPI_Feature> & theFeature,
+    const std::string & theExternalName)
+: SketchAPI_SketchEntity(theFeature)
+{
+  if (initialize()) {
+    setByExternalName(theExternalName);
+  }
+}
+
 SketchAPI_Projection::~SketchAPI_Projection()
 {
 
@@ -39,4 +51,22 @@ void SketchAPI_Projection::setExternalFeature(const ModelHighAPI_Selection & the
   execute();
 }
 
+void SketchAPI_Projection::setByExternalName(const std::string& theExternalName)
+{
+  fillAttribute(ModelHighAPI_Selection("EDGE", theExternalName), external());
+
+  execute();
+}
+
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Projection::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = externalFeature();
+  theDumper << aBase << " = " << aSketchName << ".addProjection(" << anExternal << ")" << std::endl;
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+}
index cf18e20f3a0671d4b93c594781af709d1b6a43ee..59508e767a1fea46bf378ffd159d97264777a9d1 100644 (file)
@@ -30,19 +30,31 @@ public:
   SKETCHAPI_EXPORT
   SketchAPI_Projection(const std::shared_ptr<ModelAPI_Feature> & theFeature,
                        const ModelHighAPI_Selection & theExternalFeature);
+  /// Constructor with values
+  SKETCHAPI_EXPORT
+  SketchAPI_Projection(const std::shared_ptr<ModelAPI_Feature> & theFeature,
+                       const std::string & theExternalName);
   /// Destructor
   SKETCHAPI_EXPORT
   virtual ~SketchAPI_Projection();
 
   INTERFACE_3(SketchPlugin_Projection::ID(),
               externalFeature, SketchPlugin_Projection::EXTERNAL_FEATURE_ID(), ModelAPI_AttributeSelection, /** External feature */,
-              projectedFeature, SketchPlugin_Projection::EXTERNAL_FEATURE_ID(), ModelAPI_AttributeRefAttr, /** Projected feature */,
+              projectedFeature, SketchPlugin_Projection::PROJECTED_FEATURE_ID(), ModelAPI_AttributeRefAttr, /** Projected feature */,
               external, SketchPlugin_Projection::EXTERNAL_ID(), ModelAPI_AttributeSelection, /** External */
   )
 
   /// Set external feature
   SKETCHAPI_EXPORT
   void setExternalFeature(const ModelHighAPI_Selection & theExternalLine);
+
+  /// Set by external name
+  SKETCHAPI_EXPORT
+  void setByExternalName(const std::string & theExternalName);
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Projection object
index b7b5c546b4bfaa6ddf2c404f398849804adc8133..87f7e805b366a896c91dcd5d52ce0811ed030fb1 100644 (file)
@@ -7,11 +7,12 @@
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_Rotation.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 SketchAPI_Rotation::SketchAPI_Rotation(
     const std::shared_ptr<ModelAPI_Feature> & theFeature)
-: SketchAPI_SketchEntity(theFeature)
+: ModelHighAPI_Interface(theFeature)
 {
   initialize();
 }
@@ -23,17 +24,16 @@ SketchAPI_Rotation::SketchAPI_Rotation(
     const ModelHighAPI_Double & theAngle,
     const ModelHighAPI_Integer & theNumberOfObjects,
     bool theFullValue)
-: SketchAPI_SketchEntity(theFeature)
+: ModelHighAPI_Interface(theFeature)
 {
   if (initialize()) {
     fillAttribute(theObjects, rotationList());
     fillAttribute(theCenter, center());
     fillAttribute(theAngle, angle());
     fillAttribute(theNumberOfObjects, numberOfObjects());
-    if (theFullValue)
-      fillAttribute("SingleAngle", valueType());
+    fillAttribute(theFullValue ? "FullAngle" : "SingleAngle", valueType());
 
-    execute();
+    execute(true);
   }
 }
 
@@ -43,3 +43,21 @@ SketchAPI_Rotation::~SketchAPI_Rotation()
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Rotation::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeRefListPtr aRotObjects = rotationList();
+  AttributeRefAttrPtr aCenter = center();
+  AttributeDoublePtr anAngle = angle();
+  AttributeIntegerPtr aNbCopies = numberOfObjects();
+  bool isFullValue = valueType()->value() != "SingleAngle";
+
+  theDumper << aBase << " = " << aSketchName << ".addRotation("
+            << aRotObjects << ", " << aCenter << ", " << anAngle << ", " << aNbCopies;
+  if (isFullValue)
+    theDumper << ", " << isFullValue;
+  theDumper << ")" << std::endl;
+}
index e5a3281b4531fa462ffb8366d8925c50f85f39ae..800c4c521ba25065dd1f600eefb3a7fe0fa5f593 100644 (file)
@@ -14,7 +14,8 @@
 
 #include <SketchPlugin_MultiRotation.h>
 
-#include "SketchAPI_SketchEntity.h"
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
 //--------------------------------------------------------------------------------------
 class ModelAPI_Object;
 class ModelHighAPI_Double;
@@ -25,7 +26,7 @@ class ModelHighAPI_RefAttr;
  * \ingroup CPPHighAPI
  * \brief Interface for Rotation feature
  */
-class SketchAPI_Rotation : public SketchAPI_SketchEntity
+class SketchAPI_Rotation : public ModelHighAPI_Interface
 {
 public:
   /// Constructor without values
@@ -53,6 +54,8 @@ public:
               rotatedObjects, SketchPlugin_MultiRotation::ENTITY_B(), ModelAPI_AttributeRefList, /** Rotated objects */
   )
 
+  /// Dump wrapped feature
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Rotation object
index 2a8e7e141f12046de459a3b6955c654cb3951079..ad2e2b55d2e96fa4bd26b95d5b9cd8cee212be22 100644 (file)
 #include <SketchPlugin_ConstraintRigid.h>
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintVertical.h>
+#include <SketcherPrs_Tools.h>
 //--------------------------------------------------------------------------------------
 #include <ModelAPI_CompositeFeature.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_RefAttr.h>
 #include <ModelHighAPI_Selection.h>
+#include <ModelHighAPI_Services.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_Arc.h"
@@ -69,6 +72,16 @@ SketchAPI_Sketch::SketchAPI_Sketch(
   }
 }
 
+SketchAPI_Sketch::SketchAPI_Sketch(
+    const std::shared_ptr<ModelAPI_Feature> & theFeature,
+    std::shared_ptr<ModelAPI_Object> thePlaneObject)
+: ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    setExternal(thePlaneObject);
+  }
+}
+
 SketchAPI_Sketch::~SketchAPI_Sketch()
 {
 
@@ -97,6 +110,13 @@ void SketchAPI_Sketch::setExternal(const ModelHighAPI_Selection & theExternal)
   execute();
 }
 
+void SketchAPI_Sketch::setExternal(std::shared_ptr<ModelAPI_Object> thePlaneObject)
+{
+  ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(thePlaneObject);
+  ModelHighAPI_Selection aSel(aRes);
+  setExternal(aSel);
+}
+
 //--------------------------------------------------------------------------------------
 void SketchAPI_Sketch::setValue(
     const std::shared_ptr<ModelAPI_Feature> & theConstraint,
@@ -154,6 +174,14 @@ SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
   return SketchPtr(new SketchAPI_Sketch(aFeature, ModelHighAPI_Selection("FACE", theExternalName)));
 }
 
+SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
+                    std::shared_ptr<ModelAPI_Object> thePlaneObject)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
+  return SketchPtr(new SketchAPI_Sketch(aFeature, thePlaneObject));
+}
+
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
     double theX, double theY)
@@ -208,16 +236,12 @@ std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(
 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const ModelHighAPI_Selection & theExternal)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchPlugin_Line::ID());
-  LinePtr aLine(new SketchAPI_Line(aFeature, theExternal));
-  setFixed(InterfacePtr(aLine));
-  return aLine;
+  return LinePtr(new SketchAPI_Line(aFeature, theExternal));
 }
 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const std::string & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchPlugin_Line::ID());
-  LinePtr aLine(new SketchAPI_Line(aFeature, theExternalName));
-  setFixed(InterfacePtr(aLine));
-  return aLine;
+  return LinePtr(new SketchAPI_Line(aFeature, theExternalName));
 }
 
 //--------------------------------------------------------------------------------------
@@ -358,6 +382,13 @@ std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
   return ProjectionPtr(new SketchAPI_Projection(aFeature, theExternalFeature));
 }
 
+std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
+    const std::string & theExternalName)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchPlugin_Projection::ID());
+  return ProjectionPtr(new SketchAPI_Projection(aFeature, theExternalName));
+}
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Mirror> SketchAPI_Sketch::addMirror(
     const ModelHighAPI_RefAttr & theMirrorLine,
@@ -397,9 +428,10 @@ std::shared_ptr<ModelAPI_Feature> SketchAPI_Sketch::setAngle(
     const ModelHighAPI_RefAttr & theLine2,
     const ModelHighAPI_Double & theValue)
 {
-  // TODO(spo): is support of angle type necessary?
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
+  fillAttribute(SketcherPrs_Tools::ANGLE_DIRECT,
+      aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
@@ -407,6 +439,40 @@ std::shared_ptr<ModelAPI_Feature> SketchAPI_Sketch::setAngle(
   return aFeature;
 }
 
+std::shared_ptr<ModelAPI_Feature> SketchAPI_Sketch::setAngleComplementary(
+    const ModelHighAPI_RefAttr & theLine1,
+    const ModelHighAPI_RefAttr & theLine2,
+    const ModelHighAPI_Double & theValue)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
+  fillAttribute(SketcherPrs_Tools::ANGLE_COMPLEMENTARY,
+      aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
+  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
+  fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
+  fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
+//  fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
+  aFeature->execute();
+  return aFeature;
+}
+
+std::shared_ptr<ModelAPI_Feature> SketchAPI_Sketch::setAngleBackward(
+    const ModelHighAPI_RefAttr & theLine1,
+    const ModelHighAPI_RefAttr & theLine2,
+    const ModelHighAPI_Double & theValue)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
+  fillAttribute(SketcherPrs_Tools::ANGLE_BACKWARD,
+      aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
+  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
+  fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
+  fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
+//  fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
+  aFeature->execute();
+  return aFeature;
+}
+
 std::shared_ptr<ModelAPI_Feature> SketchAPI_Sketch::setCoincident(
     const ModelHighAPI_RefAttr & thePoint1,
     const ModelHighAPI_RefAttr & thePoint2)
@@ -572,3 +638,60 @@ std::shared_ptr<ModelAPI_Feature> SketchAPI_Sketch::setVertical(
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->value()) {
+    theDumper << aBase << " = model.addSketch(" << aDocName << ", " << anExternal << ")" << std::endl;
+  } else {
+    // Sketch is base on a plane.
+    std::shared_ptr<GeomAPI_Pnt> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+        aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()))->pnt();
+    std::shared_ptr<GeomAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        aBase->attribute(SketchPlugin_Sketch::NORM_ID()))->dir();
+    std::shared_ptr<GeomAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        aBase->attribute(SketchPlugin_Sketch::DIRX_ID()))->dir();
+
+    // Check the plane is coordinate plane
+    std::string aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
+    if (anExternal->context()) { // checking for selected planes
+      if (!aPlaneName.empty()) {
+        // dump sketch based on coordinate plane
+        theDumper << aBase << " = model.addSketch(" << aDocName
+                  << ", model.standardPlane(\"" << aPlaneName << "\"))" << std::endl;
+      } else { // some other plane
+        theDumper << aBase << " = model.addSketch(" << aDocName << ", " << anExternal<< ")" << std::endl;
+      }
+    } else {
+      if (aPlaneName.empty()) {
+        // needs import additional module
+        theDumper.importModule("GeomAPI");
+        // dump plane parameters
+        const std::string& aSketchName = theDumper.name(aBase);
+        std::string anOriginName = aSketchName + "_origin";
+        std::string aNormalName  = aSketchName + "_norm";
+        std::string aDirXName    = aSketchName + "_dirx";
+        // use "\n" instead of std::endl to avoid automatic dumping sketch here
+        // and then dumplicate dumping it in the next line
+        theDumper << anOriginName << " = " << anOrigin << "\n"
+                  << aNormalName  << " = " << aNormal  << "\n"
+                  << aDirXName    << " = " << aDirX    << "\n";
+        // dump sketch based on arbitrary plane
+        theDumper << aBase << " = model.addSketch(" << aDocName << ", GeomAPI_Ax3("
+                  << anOriginName << ", " << aDirXName << ", " << aNormalName << "))" << std::endl;
+      } else {
+        // dump sketch based on coordinate plane
+        theDumper << aBase << " = model.addSketch(" << aDocName
+                  << ", model.defaultPlane(\"" << aPlaneName << "\"))" << std::endl;
+      }
+    }
+  }
+
+  // dump sketch's subfeatures
+  CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
+  theDumper.processSubs(aCompFeat, true);
+}
index e23f9dd905861f19220192606950b8ff975afeca..545095521762a3209bf3e5306123323bbaa9db17 100644 (file)
@@ -53,6 +53,10 @@ public:
   SKETCHAPI_EXPORT
   SketchAPI_Sketch(const std::shared_ptr<ModelAPI_Feature> & theFeature,
                    const ModelHighAPI_Selection & theExternal);
+  /// Constructor with values
+  SKETCHAPI_EXPORT
+  SketchAPI_Sketch(const std::shared_ptr<ModelAPI_Feature> & theFeature,
+                   std::shared_ptr<ModelAPI_Object> thePlaneObject);
   /// Destructor
   SKETCHAPI_EXPORT
   virtual ~SketchAPI_Sketch();
@@ -75,6 +79,10 @@ public:
   SKETCHAPI_EXPORT
   void setExternal(const ModelHighAPI_Selection & theExternal);
 
+  /// Set external
+  SKETCHAPI_EXPORT
+  void setExternal(std::shared_ptr<ModelAPI_Object> thePlaneObject);
+
   /// Add point
   SKETCHAPI_EXPORT
   std::shared_ptr<SketchAPI_Point> addPoint(
@@ -209,6 +217,10 @@ public:
   std::shared_ptr<SketchAPI_Projection> addProjection(
       const ModelHighAPI_Selection & theExternalFeature);
 
+  /// Add projection
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_Projection> addProjection(const std::string & theExternalName);
+
   /// Add mirror
   SKETCHAPI_EXPORT
   std::shared_ptr<SketchAPI_Mirror> addMirror(
@@ -240,6 +252,20 @@ public:
       const ModelHighAPI_RefAttr & theLine2,
       const ModelHighAPI_Double & theValue);
 
+  /// Set complementary angle
+  SKETCHAPI_EXPORT
+  std::shared_ptr<ModelAPI_Feature> setAngleComplementary(
+      const ModelHighAPI_RefAttr & theLine1,
+      const ModelHighAPI_RefAttr & theLine2,
+      const ModelHighAPI_Double & theValue);
+
+  /// Set backward angle (= 360 - angle)
+  SKETCHAPI_EXPORT
+  std::shared_ptr<ModelAPI_Feature> setAngleBackward(
+      const ModelHighAPI_RefAttr & theLine1,
+      const ModelHighAPI_RefAttr & theLine2,
+      const ModelHighAPI_Double & theValue);
+
   /// Set coincident
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelAPI_Feature> setCoincident(
@@ -333,6 +359,10 @@ public:
   SKETCHAPI_EXPORT
   std::list<ModelHighAPI_Selection> selectFace() const;
 
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
 protected:
   std::shared_ptr<ModelAPI_CompositeFeature> compositeFeature() const;
 
@@ -362,6 +392,13 @@ SKETCHAPI_EXPORT
 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
                     const std::string & theExternalName);
 
+/**\ingroup CPPHighAPI
+ * \brief Create Sketch feature
+ */
+SKETCHAPI_EXPORT
+SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
+                    std::shared_ptr<ModelAPI_Object> thePlaneObject);
+
 //--------------------------------------------------------------------------------------
 //--------------------------------------------------------------------------------------
 #endif /* SRC_SKETCHAPI_SKETCHAPI_SKETCH_H_ */
index a017576abdf6308d998230b3acb665d45e90ef27..3e5f4f82446cbb63600d70da8e938a6104636b91 100644 (file)
@@ -7,6 +7,7 @@
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_SketchEntity.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 SketchAPI_SketchEntity::SketchAPI_SketchEntity(
@@ -43,3 +44,20 @@ void SketchAPI_SketchEntity::setAuxiliary(bool theAuxiliary)
 }
 
 //--------------------------------------------------------------------------------------
+void SketchAPI_SketchEntity::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  AttributeBooleanPtr anAux = aBase->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
+  if (anAux->value()) {
+    const std::string& aName = theDumper.name(aBase);
+    theDumper << aName << ".setAuxiliary(" << anAux << ")" <<std::endl;
+  }
+}
+
+bool SketchAPI_SketchEntity::isCopy() const
+{
+  // check the feature is a copy of another entity
+  std::shared_ptr<SketchPlugin_SketchEntity> aSketchEntity =
+      std::dynamic_pointer_cast<SketchPlugin_SketchEntity>(feature());
+  return aSketchEntity && aSketchEntity->isCopy();
+}
index 5ac166aa381e3fab27e9dc1b694d4144be37a4dd..fcc8639008b85b916dccf3e3249039ee7581297d 100644 (file)
@@ -37,10 +37,16 @@ public:
   SKETCHAPI_EXPORT
   void setAuxiliary(bool theAuxiliary);
 
+  /// Dump wrapped feature
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
 protected:
   std::shared_ptr<ModelAPI_AttributeBoolean> myAuxiliary;
 
   bool initialize();
+
+  /// Check the entity is a copy of another feature
+  bool isCopy() const;
 };
 
 //! Pointer on SketchEntity object
index 0ba3e3b3faf624e36229b5052967bf8492d7fa7d..4fff83bbeb4f2b5b281d5fd4e7bc6b12f25b68f3 100644 (file)
@@ -7,11 +7,12 @@
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_Translation.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 SketchAPI_Translation::SketchAPI_Translation(
     const std::shared_ptr<ModelAPI_Feature> & theFeature)
-: SketchAPI_SketchEntity(theFeature)
+: ModelHighAPI_Interface(theFeature)
 {
   initialize();
 }
@@ -23,17 +24,16 @@ SketchAPI_Translation::SketchAPI_Translation(
     const ModelHighAPI_RefAttr & thePoint2,
     const ModelHighAPI_Integer & theNumberOfObjects,
     bool theFullValue)
-: SketchAPI_SketchEntity(theFeature)
+: ModelHighAPI_Interface(theFeature)
 {
   if (initialize()) {
     fillAttribute(theObjects, translationList());
     fillAttribute(thePoint1, startPoint());
     fillAttribute(thePoint2, endPoint());
     fillAttribute(theNumberOfObjects, numberOfObjects());
-    if (theFullValue)
-      fillAttribute("SingleValue", valueType());
+    fillAttribute(theFullValue ? "FullValue" : "SingleValue", valueType());
 
-    execute();
+    execute(true);
   }
 }
 
@@ -43,3 +43,21 @@ SketchAPI_Translation::~SketchAPI_Translation()
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Translation::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeRefListPtr aTransObjects = translationList();
+  AttributeRefAttrPtr aStart = startPoint();
+  AttributeRefAttrPtr aEnd   = endPoint();
+  AttributeIntegerPtr aNbCopies = numberOfObjects();
+  bool isFullValue = valueType()->value() != "SingleValue";
+
+  theDumper << aBase << " = " << aSketchName << ".addTranslation("
+            << aTransObjects << ", " << aStart << ", " << aEnd << ", " << aNbCopies;
+  if (isFullValue)
+    theDumper << ", " << isFullValue;
+  theDumper << ")" << std::endl;
+}
index 7b6da8f5eb526c884907f229ddfcf22c99b17459..4e3fd270f9391d825b8faca65584b2189b88c272 100644 (file)
@@ -14,7 +14,8 @@
 
 #include <SketchPlugin_MultiTranslation.h>
 
-#include "SketchAPI_SketchEntity.h"
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
 //--------------------------------------------------------------------------------------
 class ModelAPI_Object;
 class ModelHighAPI_Integer;
@@ -24,7 +25,7 @@ class ModelHighAPI_RefAttr;
  * \ingroup CPPHighAPI
  * \brief Interface for Translation feature
  */
-class SketchAPI_Translation : public SketchAPI_SketchEntity
+class SketchAPI_Translation : public ModelHighAPI_Interface
 {
 public:
   /// Constructor without values
@@ -52,6 +53,8 @@ public:
               translatedObjects, SketchPlugin_MultiTranslation::ENTITY_B(), ModelAPI_AttributeRefList, /** Translationed objects */
   )
 
+  /// Dump wrapped feature
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
 };
 
 //! Pointer on Translation object
index 34c00398f46f3324a79ad3393943103a86420efa..c1695defaf3fa42a2b05fe3e70f43dd676fe5ccf 100644 (file)
@@ -12,6 +12,7 @@
   #include "SketchAPI.h"
   #include "SketchAPI_Arc.h"
   #include "SketchAPI_Circle.h"
+  #include "SketchAPI_Constraint.h"
   #include "SketchAPI_IntersectionPoint.h"
   #include "SketchAPI_Line.h"
   #include "SketchAPI_Mirror.h"
index 5ba8163ea1618e85e1d821d47da324ec60e15d3b..ab27bbbe8e6e7dd98f50a45f761603efefc98a6b 100644 (file)
@@ -338,6 +338,12 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
   // the second condition for unability to move external segments anywhere
   if (theID == EXTERNAL_ID() || isFixed()) {
     std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+    if (!aSelection) {
+      // empty shape in selection shows that the shape is equal to context
+      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
+      if (anExtRes)
+        aSelection = anExtRes->shape();
+    }
     // update arguments due to the selection value
     if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
       std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
@@ -486,11 +492,11 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
       double aNewAngle = aPassedParam >= aStartParam && aPassedParam <= aEndParam ?
         ((aEndParam - aStartParam) * 180.0 / PI) :
         ((aEndParam - aStartParam - 2.0 * PI) * 180.0 / PI);
-      if (fabs(aNewAngle - anAngleAttr->value()) > tolerance)
+      if (!anAngleAttr->isInitialized() || fabs(aNewAngle - anAngleAttr->value()) > tolerance)
         anAngleAttr->setValue(aNewAngle);
     } else {
       double aNewAngle = (aEndParam - aStartParam) * 180.0 / PI;
-      if (fabs(aNewAngle - anAngleAttr->value()) > tolerance)
+      if (!anAngleAttr->isInitialized() || fabs(aNewAngle - anAngleAttr->value()) > tolerance)
         anAngleAttr->setValue(aNewAngle);
     }
     // do not need to inform that other parameters were changed in this basis mode: these arguments
index ccb1a6efe0ba58991c853535229a022c4d67b408..babdd6f14e01dcff3da73c1b76c1f4f01ac1a09f 100644 (file)
@@ -189,6 +189,12 @@ void SketchPlugin_Circle::attributeChanged(const std::string& theID) {
   // the second condition for unability to move external segments anywhere
   if (theID == EXTERNAL_ID() || isFixed()) {
     std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+    if (!aSelection) {
+      // empty shape in selection shows that the shape is equal to context
+      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
+      if (anExtRes)
+        aSelection = anExtRes->shape();
+    }
     // update arguments due to the selection value
     if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
       std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
index 8fb29c48c33e5866c795c9acc2c01e5798af491e..2bf082f6145f721c1805406b3766aaeae2b5e009 100644 (file)
@@ -105,9 +105,12 @@ void SketchPlugin_ConstraintAngle::attributeChanged(const std::string& theID)
 
   if (theID == SketchPlugin_Constraint::ENTITY_A() || 
       theID == SketchPlugin_Constraint::ENTITY_B()) {
-    std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
-        ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
-    if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
+    AttributeDoublePtr aValueAttr = real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+    AttributeDoublePtr aConstrValueAttr = real(SketchPlugin_Constraint::VALUE());
+    // only if one of attributes is not initialized, try to compute the current value
+    if (!aValueAttr->isInitialized() || !aConstrValueAttr->isInitialized()) {
+      if (aValueAttr->isInitialized() && !aConstrValueAttr->isInitialized()) // initialize base value of constraint
+        updateConstraintValueByAngleValue();
       double anAngle = calculateAngle();
       aValueAttr->setValue(anAngle);
       updateConstraintValueByAngleValue();
@@ -252,7 +255,8 @@ bool SketchPlugin_ConstraintAngle::compute(const std::string& theAttributeId)
 
   std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
                            GeomDataAPI_Point2D>(attribute(theAttributeId));
-  if (fabs(aFlyOutAttr->x()) >= tolerance || fabs(aFlyOutAttr->y()) >= tolerance)
+  if (aFlyOutAttr->isInitialized() &&
+      (fabs(aFlyOutAttr->x()) >= tolerance || fabs(aFlyOutAttr->y()) >= tolerance))
     return false;
 
   DataPtr aData = data();
index 530895f30d1f68e7d934e886ad70b813bd292161..0481c4a14a0f48e193f4ac149edd4563b978d87f 100644 (file)
@@ -13,7 +13,6 @@
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttrList.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Events.h>
index 949908b293f628672969fdd7e52a85d5b3204d34..ba18dae3e82b711fe03b25772d411ff0aaee6932 100644 (file)
@@ -93,7 +93,8 @@ bool SketchPlugin_ConstraintLength::compute(const std::string& theAttributeId)
 
   std::shared_ptr<GeomAPI_Lin2d> aLine = 
     std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aStartPoint->pnt(), anEndPoint->pnt()));
-  if (fabs(aFlyOutAttr->x()) < tolerance && fabs(aFlyOutAttr->y()) < tolerance) {
+  if (!aFlyOutAttr->isInitialized() || 
+      (fabs(aFlyOutAttr->x()) < tolerance && fabs(aFlyOutAttr->y()) < tolerance)) {
     double aDist = aPoint1->distance(aPoint2)/5.;
     std::shared_ptr<GeomAPI_Pnt2d> aFPnt = aLine->shiftedLocation(aDist);
     aFlyOutAttr->setValue(aFPnt);
index 2161806ebd3a21c805f4d2661645e482e216cda1..42ed4d5b48911f67d7396b26352780bfe8502dc5 100755 (executable)
@@ -234,18 +234,14 @@ void SketchPlugin_ConstraintMirror::attributeChanged(const std::string& theID)
   if (theID == MIRROR_LIST_ID()) {
     AttributeRefListPtr aMirrorObjectRefs = reflist(MIRROR_LIST_ID());
     if (aMirrorObjectRefs->size() == 0) {
+      DocumentPtr aDoc = document();
       // Clear list of objects
       AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
           data()->attribute(SketchPlugin_Constraint::ENTITY_C()));
       std::list<ObjectPtr> aTargetList = aRefListOfMirrored->list();
       std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
       for (; aTargetIter != aTargetList.end(); aTargetIter++) {
-        aRefListOfMirrored->remove(*aTargetIter);
-        // remove the corresponding feature from the sketch
-        ResultConstructionPtr aRC =
-            std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aTargetIter);
-        DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
-        FeaturePtr aFeature =  aDoc ? aDoc->feature(aRC) : FeaturePtr();
+        FeaturePtr aFeature = ModelAPI_Feature::feature(*aTargetIter);
         if (aFeature)
           aDoc->removeFeature(aFeature);
       }
index 4e6cdfd62a6f7d5f0d5135cb61ba451ff4c9cb49..e53185f413b11ceb49bbbf5e3a36e75866733a02 100755 (executable)
@@ -6,16 +6,10 @@
 
 #include "SketchPlugin_ConstraintSplit.h"
 
-//#include <GeomAPI_Circ2d.h>
-//#include <GeomAPI_Dir2d.h>
-//#include <GeomAPI_Lin2d.h>
 #include <GeomAPI_Pnt2d.h>
-//#include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
-//#include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_AttributeString.h>
-//#include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_Tools.h>
 
index 5842df8a0968939413d98fd409be090d7e116fa9..436cc5e7b428110a780758741702818af822ec83 100644 (file)
@@ -5,7 +5,6 @@
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
-#include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_ResultConstruction.h>
 
 /// It is important.
index 2d2c6bc4a9880955de3c1f030c2b2d6cf231ed38..782f99a2472346eed9e2e785846da018e28853ca 100644 (file)
@@ -123,7 +123,13 @@ void SketchPlugin_Line::attributeChanged(const std::string& theID) {
   // to be removed after debug
   if ((theID == EXTERNAL_ID() || isFixed()) && !isCopy()) {
     std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-     // update arguments due to the selection value
+    if (!aSelection) {
+      // empty shape in selection shows that the shape is equal to context
+      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
+      if (anExtRes)
+        aSelection = anExtRes->shape();
+    }
+    // update arguments due to the selection value
     if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
       std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
       std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = 
index 0ef30f7a166309271f9a23516f049997c243bbea..6ae033dec67086f271731da7795cd6f4f3d1f044 100755 (executable)
@@ -332,8 +332,7 @@ void SketchPlugin_MultiRotation::attributeChanged(const std::string& theID)
         return;
 
       // Clear list of objects
-      AttributeRefListPtr aRefListOfRotated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
-          data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
+      AttributeRefListPtr aRefListOfRotated = reflist(SketchPlugin_Constraint::ENTITY_B());
       std::list<ObjectPtr> aTargetList = aRefListOfRotated->list();
       std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
       std::set<FeaturePtr> aFeaturesToBeRemoved;
@@ -342,10 +341,7 @@ void SketchPlugin_MultiRotation::attributeChanged(const std::string& theID)
         for (int i = 0; i < aNbCopies && aTargetIter != aTargetList.end(); i++, aTargetIter++) {
           aRefListOfRotated->remove(*aTargetIter);
           // remove the corresponding feature from the sketch
-          ResultConstructionPtr aRC =
-            std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aTargetIter);
-          DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
-          FeaturePtr aFeature =  aDoc ? aDoc->feature(aRC) : FeaturePtr();
+          FeaturePtr aFeature = ModelAPI_Feature::feature(*aTargetIter);
           if (aFeature)
             aFeaturesToBeRemoved.insert(aFeature);
         }
@@ -353,10 +349,7 @@ void SketchPlugin_MultiRotation::attributeChanged(const std::string& theID)
       ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
 
       aRefListOfRotated->clear();
-      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
-        data()->attribute(SketchPlugin_Constraint::ENTITY_A()))->clear();
-      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
-        data()->attribute(SketchPlugin_Constraint::ENTITY_B()))->clear();
+      reflist(SketchPlugin_Constraint::ENTITY_A())->clear();
     }
   }
 }
index d6e1d5dd22b50b5b679a11c9ca4ed4cdf4459d22..34e26377b424630c042a9c2233f207dfeced6d2b 100755 (executable)
@@ -274,29 +274,23 @@ void SketchPlugin_MultiTranslation::attributeChanged(const std::string& theID)
       int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value()-1;
       if (aNbCopies <= 0)
         return;
+
+      DocumentPtr aDoc = document();
       // Clear list of objects
-      AttributeRefListPtr aRefListOfTranslated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
-          data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
+      AttributeRefListPtr aRefListOfTranslated = reflist(SketchPlugin_Constraint::ENTITY_B());
       std::list<ObjectPtr> aTargetList = aRefListOfTranslated->list();
       std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
       while (aTargetIter != aTargetList.end()) {
         aTargetIter++;
         for (int i = 0; i < aNbCopies && aTargetIter != aTargetList.end(); i++, aTargetIter++) {
           aRefListOfTranslated->remove(*aTargetIter);
-          // remove the corresponding feature from the sketch
-          ResultConstructionPtr aRC =
-            std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aTargetIter);
-          DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
-          FeaturePtr aFeature =  aDoc ? aDoc->feature(aRC) : FeaturePtr();
+          FeaturePtr aFeature = ModelAPI_Feature::feature(*aTargetIter);
           if (aFeature)
             aDoc->removeFeature(aFeature);
         }
       }
       aRefListOfTranslated->clear();
-      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
-        data()->attribute(SketchPlugin_Constraint::ENTITY_A()))->clear();
-      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
-        data()->attribute(SketchPlugin_Constraint::ENTITY_B()))->clear();
+      reflist(SketchPlugin_Constraint::ENTITY_A())->clear();
     }
   }
 }
index afa84bf135efa5993c0762f1e1e3662640abf25c..4ee1f89845f46d680a5af1af57728b6f6d549557 100644 (file)
@@ -69,7 +69,13 @@ void SketchPlugin_Point::attributeChanged(const std::string& theID) {
   // the second condition for unability to move external point anywhere
   if (theID == EXTERNAL_ID() || isFixed()) {
     std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-     // update arguments due to the selection value
+    if (!aSelection) {
+      // empty shape in selection shows that the shape is equal to context
+      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
+      if (anExtRes)
+        aSelection = anExtRes->shape();
+    }
+    // update arguments due to the selection value
     if (aSelection && !aSelection->isNull() && aSelection->isVertex()) {
       std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aSelection));
       std::shared_ptr<GeomDataAPI_Point2D> aCoordAttr = 
index eaf073c8b7702a9caeda15e061116fb724df09ee..85dade4280451efbcb8cefba8724157a992674d5 100644 (file)
@@ -187,6 +187,7 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
     aCenterPnt->setValue(aCenterInSketch);
   }
 
+  aProjection->boolean(COPY_ID())->setValue(true);
   aProjection->execute();
   aRefAttr->setObject(aProjection);
 
index 5d1b9d3d23d7ef7b5924f25f818c7f28155f1660..3ce9adaa5fe63857959529cd8cfe7c9f2183b2bd 100755 (executable)
@@ -91,7 +91,7 @@ void SketchPlugin_Sketch::execute()
         aFeature->setSketch(this);
       // do not include the external edges into the result
       if (aFeature->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())) {
-        if (aFeature->data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->value())
+        if (aFeature->data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->context())
           continue;
       }
       // do not include the construction entities in the result
index 3e0cf8e207c26c3003b9f9d1da3bf8f5e6cc4c9a..3070252604dc486fe525174beb2565cb5dcd841a 100644 (file)
@@ -78,7 +78,7 @@ aEndPoint.setValue(100., 25.)
 aSketchLineB = aSketchFeature.addFeature("SketchLine")
 aStartPoint = geomDataAPI_Point2D(aSketchLineB.attribute("StartPoint"))
 aEndPoint = geomDataAPI_Point2D(aSketchLineB.attribute("EndPoint"))
-aStartPoint.setValue(-20., 15.)
+aStartPoint.setValue(-10., 15.)
 aEndPoint.setValue(80., 50.)
 aSession.finishOperation()
 #=========================================================================
@@ -97,10 +97,13 @@ assert (not refattrB.isInitialized())
 refattrA.setObject(aSketchLineA.firstResult())
 refattrB.setObject(aSketchLineB.firstResult())
 anAngleVal.setValue(ANGLE_DEGREE)
+aConstraint.execute()
+aSession.finishOperation()
+aSession.startOperation()
 aFlyoutPoint = geomDataAPI_Point2D(aConstraint.attribute("ConstraintFlyoutValuePnt"))
 aFlyoutPoint.setValue(50.0, 100.0)
-aConstraint.execute()
 aSession.finishOperation()
+aSession.abortOperation()
 assert (anAngleVal.isInitialized())
 assert (refattrA.isInitialized())
 assert (refattrB.isInitialized())
@@ -110,7 +113,7 @@ assert (angle(aSketchLineA, aSketchLineB) == ANGLE_DEGREE)
 #=========================================================================
 aSession.startOperation()
 aStartPoint = geomDataAPI_Point2D(aSketchLineA.attribute("StartPoint"))
-aStartPoint.setValue(0., 30.)
+aStartPoint.setValue(0., -30.)
 aConstraint.execute()
 aSession.finishOperation()
 assert (angle(aSketchLineA, aSketchLineB) == ANGLE_DEGREE)
@@ -145,3 +148,6 @@ assert (angle(aSketchLineA, aSketchLineB) == NEW_ANGLE_DEGREE)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index e37159af8b89bbb8683d0d2a8235e344206ecebb..a1697920ead11a9e49aa7a23cd9ee787a464ad77 100644 (file)
@@ -209,3 +209,6 @@ assert (aCircleCenter.x() == 0. and aCircleCenter.y() == 0.)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index dda5b8de16bebf0cd0ee03190de580a6d989ccd4..b5d898273aec132fa44c00bc2f962227a66c8bd9 100644 (file)
@@ -100,3 +100,6 @@ checkCollinear(aSketchLineA, aSketchLineB)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 75ea588541f45da65b254925605f4c1bafa91c90..75f4d3fbbbdf94a956e845f5b83a75898548a54b 100644 (file)
@@ -104,9 +104,13 @@ assert (aLineResult is not None)
 aConstraint.execute()
 refattrA.setAttr(aSketchPointCoords)
 refattrB.setAttr(aLineAStartPoint)
+aSession.finishOperation()
+# set flyout point then abort operation, after that check the Distance is correct
+aSession.startOperation()
 aFlyoutPoint = geomDataAPI_Point2D(aConstraint.attribute("ConstraintFlyoutValuePnt"))
 aFlyoutPoint.setValue(50.0, 100.0)
 aSession.finishOperation()
+aSession.abortOperation()
 assert (refattrA.isInitialized())
 assert (refattrB.isInitialized())
 assert (aDistance.isInitialized())
@@ -154,9 +158,13 @@ aLineResult = aSketchLine.firstResult()
 assert (aLineResult is not None)
 refattrA.setObject(aLineResult)
 refattrB.setAttr(aSketchPointCoords)
+aSession.finishOperation()
+# set flyout point then abort operation, after that check the Distance is correct
+aSession.startOperation()
 aFlyoutPoint = geomDataAPI_Point2D(aConstraint.attribute("ConstraintFlyoutValuePnt"))
 aFlyoutPoint.setValue(50.0, 100.0)
 aSession.finishOperation()
+aSession.abortOperation()
 assert (refattrA.isInitialized())
 assert (refattrB.isInitialized())
 assert (aDistance.isInitialized())
@@ -179,3 +187,6 @@ assert (math.fabs(distancePointPoint(aLineAStartPoint, aLineAEndPoint) - PT_LINE
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index d4176eebd4449fcbb7dd8496b5291832a5a5c8b8..2d38a28f858a4388a4503c62fe6d7c94a595153f 100644 (file)
@@ -117,16 +117,12 @@ assert (math.fabs(aCircRadius - anArcRadius) <= 1.e-10)
 # A constraint to make equal radii of arc and external circle
 #=========================================================================
 aSession.startOperation()
-anExtCircRes = modelAPI_Result(aDocument.objectByName("Construction", "SketchCircle_1"))
-assert(anExtCircRes)
-anExtCircShape = anExtCircRes.shape()
-assert(anExtCircShape)
 anExtCircle = aSketchFeature.addFeature("SketchCircle")
 anExtCircleCenter = geomDataAPI_Point2D(anExtCircle.attribute("CircleCenter"))
 anExtCircleRadius = anExtCircle.real("CircleRadius")
 anExtCircleCenter.setValue(-50., 50.)
 anExtCircleRadius.setValue(10.)
-anExtCircle.selection("External").setValue(anExtCircRes, anExtCircShape)
+anExtCircle.selection("External").selectSubShape("EDGE", "Sketch_1/Edge-SketchCircle_1_2")
 aSession.finishOperation()
 aSession.startOperation()
 aConstraintEqRad2 = aSketchFeature.addFeature("SketchConstraintEqual")
@@ -182,16 +178,12 @@ assert (math.fabs(aLine1Len - aLine2Len) < 1.e-10)
 # A constraint to make equal length of line with external line
 #=========================================================================
 aSession.startOperation()
-anExtLineRes = modelAPI_Result(aDocument.objectByName("Construction", "SketchLine_1"))
-assert(anExtLineRes)
-anExtLineShape = anExtLineRes.shape()
-assert(anExtLineShape)
 anExtLine = aSketchFeature.addFeature("SketchLine")
 anExtLineStart = geomDataAPI_Point2D(anExtLine.attribute("StartPoint"))
 anExtLineEnd = geomDataAPI_Point2D(anExtLine.attribute("EndPoint"))
 anExtLineStart.setValue(-40., 35.)
 anExtLineEnd.setValue(-60., 25.)
-anExtLine.selection("External").setValue(anExtLineRes, anExtLineShape)
+anExtLine.selection("External").selectSubShape("EDGE", "Sketch_1/Edge-SketchLine_1")
 anExtLineLen = lineLength(anExtLine)
 aSession.finishOperation()
 aSession.startOperation()
@@ -208,3 +200,6 @@ assert (math.fabs(aLine2Len - anExtLineLen) < 1.e-10)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 7a7a7d3faa92392503e7839b5b20bb2ad3717fdb..dc0b226d20b0d416ee5887f54e42c9eccd8ac875 100644 (file)
@@ -74,3 +74,6 @@ assert(aLineStartPoint.y() == aLineEndPoint.y())
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 88f9292b61e4f436799dae44bb3a415005a30abc..72db4d76f7d3b14f3778c3e5c585fbe252b89f54 100644 (file)
@@ -94,3 +94,6 @@ assert (math.fabs(aLineAEndPoint.x() - aLineAStartPoint.x() - 140) < 1.e-10)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 80ef018179857a148b2943eab474b3a24fc0567f..39db682204acc2f974bbd2faa3ce1afd90c97c50 100644 (file)
@@ -140,3 +140,6 @@ assert (anOriginCoord.x() == 0. and anOriginCoord.y() == 0.)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index bbf74982a86484fac94d9c9d0f80eca931c719e5..25b7eeecb6c7cf97def16038767e34f3df2827c7 100644 (file)
@@ -28,7 +28,7 @@ def normalize(theDir):
     return [theDir[0] / aLen, theDir[1] / aLen]
 
 def checkMirror(theListInit, theListMirr, theMirrorLine):
-    TOL = 5.e-5
+    TOL = 6.e-5
     aListSize = theListInit.size()
     
     aLineStartPoint = geomDataAPI_Point2D(theMirrorLine.attribute("StartPoint"))
@@ -201,3 +201,27 @@ checkMirror(aRefListB, aRefListC, aMirrorLine)
 #=========================================================================
 # End of test
 #=========================================================================
+
+
+# make second line fixed
+aSession.startOperation()
+aFixed = aSketchFeature.addFeature("SketchConstraintRigid")
+aRefObjectA = aFixed.refattr("ConstraintEntityA")
+anObjectA = modelAPI_ResultConstruction(aSketchLine2.lastResult())
+assert (anObjectA is not None)
+aRefObjectA.setObject(anObjectA)
+aFixed.execute()
+aSession.finishOperation()
+# set mirror for first line to check dumping
+aSession.startOperation()
+aRefListInitial.clear()
+assert (aRefListB.size() == 0)
+assert (aRefListC.size() == 0)
+aRefListInitial.append(aSketchLine1.lastResult())
+aSession.finishOperation()
+assert (aRefListB.size() == 1)
+assert (aRefListC.size() == 1)
+checkMirror(aRefListB, aRefListC, aMirrorLine)
+
+import model
+assert(model.checkPythonDump())
index 03eba23ccf379ae59722e2f90b440a10a59585ad..076b2fc6277986ba1e1340c3a28b4e5a29c6cdb0 100644 (file)
@@ -108,3 +108,6 @@ assert (aLineBEndPointPrev != aLineBEndPointNew)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 837eb262695ded641b8737836bf0a6c3b7706fbd..42c2c98574efa659af17689816aea709311a86ad 100644 (file)
@@ -121,3 +121,6 @@ assert (aLineBEndPointPrev   != (aLineBEndPoint.x(),   aLineBEndPoint.y()))
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index edc37350bb130c8c020e10802f4cdf37b6e15d61..acef6c2f03287e8b8d00c7d72215fd9a610d8d6b 100644 (file)
@@ -150,3 +150,6 @@ assert (aCircleRadius.value() == 25)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 2fe43e55756e8d6458fa82df145107020771f593..44f741503c445a26fd56fde77468a8af18133331 100644 (file)
@@ -135,3 +135,6 @@ assert ((aLineCStartPoint.x(), aLineCStartPoint.y()) == (aLineBEndPoint.x(), aLi
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index df3cd3115ac72f8c589ee84217a87d730eb9d098..24762159ff842198eddc5b244a3465dc5c5e6ac4 100644 (file)
@@ -246,7 +246,7 @@ assert(anArc2CenterNew == anArc2CenterPrev)
 assert(anArc2StartPointNew == anArc2StartPointPrev)
 assert(anArc2EndPointNew == anArc2EndPointPrev)
 aSession.startOperation()
-aSketchFeature.removeFeature(aTangency)
+aDocument.removeFeature(aTangency)
 aSession.finishOperation()
 
 #=========================================================================
@@ -305,3 +305,6 @@ assert(math.fabs(distancePointLine(aCircleCenter, aLine) - round(aCircleRadius.v
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 3a03d1d0e750dee73e0ce9be150f80cb50765145..f70040248ee769213a09ddc33f15de5c412f7f73 100644 (file)
@@ -74,3 +74,6 @@ assert(aLineStartPoint.x() == aLineEndPoint.x())
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index bb2735398b05f32698f21aa0e6c7b269f277f608..5b7bebb299b69bc36d8a83011de13677b8ff5ea1 100644 (file)
@@ -66,7 +66,7 @@ def createSketch2(theSketch):
     aStartPoint1 = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
     aEndPoint1   = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
     aStartPoint1.setValue(10., 10.)
-    aEndPoint1.setValue(30., 5.)
+    aEndPoint1.setValue(30., 15.)
     allFeatures.append(aSketchLine)
     # Arc
     aSketchArc = theSketch.addFeature("SketchArc")
@@ -103,13 +103,13 @@ def checkFillet(theObjects, theRadius):
 
     anArcPoints = []
     aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcStartPoint"))
-    print "ArcStartPoint " + repr(aPoint.x()) + " " + repr(aPoint.y())
+    #print "ArcStartPoint " + repr(aPoint.x()) + " " + repr(aPoint.y())
     anArcPoints.append((aPoint.x(), aPoint.y()))
     aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcEndPoint"))
-    print "ArcEndPoint " + repr(aPoint.x()) + " " + repr(aPoint.y())
+    #print "ArcEndPoint " + repr(aPoint.x()) + " " + repr(aPoint.y())
     anArcPoints.append((aPoint.x(), aPoint.y()))
     aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcCenter"))
-    print "ArcCenter " + repr(aPoint.x()) + " " + repr(aPoint.y())
+    #print "ArcCenter " + repr(aPoint.x()) + " " + repr(aPoint.y())
     aCenterX = aPoint.x()
     aCenterY = aPoint.y()
     aFilletRadius = math.hypot(anArcPoints[0][0]-aCenterX, anArcPoints[0][1]-aCenterY)
@@ -120,9 +120,9 @@ def checkFillet(theObjects, theRadius):
 
         aLinePoints = []
         aLinePoints.append((aStartPoint.x(), aStartPoint.y()))
-        print "aLineStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y())
+        #print "aLineStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y())
         aLinePoints.append((aEndPoint.x(), aEndPoint.y()))
-        print "aLineEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y())
+        #print "aLineEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y())
 
         aLineDirX = aEndPoint.x() - aStartPoint.x()
         aLineDirY = aEndPoint.y() - aStartPoint.y()
@@ -145,10 +145,10 @@ def checkFillet(theObjects, theRadius):
 
             aBaseArcPoints = []
             aBaseArcPoints.append((aStartPoint.x(), aStartPoint.y()))
-            print "anArcStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y())
+            #print "anArcStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y())
             aBaseArcPoints.append((aEndPoint.x(), aEndPoint.y()))
-            print "anArcEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y())
-            print "anArcCenter " + repr(aCenterPoint.x()) + " " + repr(aCenterPoint.y())
+            #print "anArcEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y())
+            #print "anArcCenter " + repr(aCenterPoint.x()) + " " + repr(aCenterPoint.y())
 
             aRadius = math.hypot(aStartPoint.x()-aCenterPoint.x(), aStartPoint.y()-aCenterPoint.y())
             aDist = math.hypot(aCenterPoint.x() - aCenterX, aCenterPoint.y() - aCenterY)
@@ -219,6 +219,7 @@ checkFillet(aResObjects, FILLET_RADIUS1)
 # Change Fillet radius
 #=========================================================================
 aRadius.setValue(FILLET_RADIUS2)
+aFillet.execute()
 aSession.finishOperation()
 checkFillet(aResObjects, FILLET_RADIUS2)
 
@@ -271,8 +272,12 @@ checkFillet(aResObjects, FILLET_RADIUS1)
 # Change Fillet radius
 #=========================================================================
 aRadius.setValue(FILLET_RADIUS2)
+aFillet.execute()
 aSession.finishOperation()
 checkFillet(aResObjects, FILLET_RADIUS2)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index f745cdfa56eb1d48da1d8f93b3922f57973c84f7..82075373941b56c8f5f03bbc14f4c920afbbd744 100644 (file)
@@ -41,6 +41,7 @@ def createNAngle(theSketch, theN, theRadius, theEdgeLength=0):
         anEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
         aStartPoint.setValue(begin[0], begin[1])
         anEndPoint.setValue(end[0], end[1])
+        aSketchLine.execute()
         allStartPoints.append(aStartPoint)
         allEndPoints.append(anEndPoint)
         allLines.append(aSketchLine)
@@ -119,3 +120,6 @@ aSession.finishOperation()
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 27b0aae2430b8fc0de718f988352bc18884a4e64..2afda371697834187d41e8c319458e9652672948 100644 (file)
@@ -219,3 +219,6 @@ checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 2c0a2b9373ed2c93a83e469f8345a0d7302517da..0d3971e27e640289d955646ce9a345c258086c79 100644 (file)
@@ -210,3 +210,6 @@ checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 909d079be762ff59f888b5b4f922e97b817c47a1..ee3151c430e805a7d029d7df1a85c1e3fcba54d6 100644 (file)
@@ -70,28 +70,16 @@ aSession.finishOperation()
 # Project all features onto the new sketch
 #=========================================================================
 aSession.startOperation()
-anExtLineRes = modelAPI_Result(aDocument.objectByName("Construction", "SketchLine_1"))
-assert(anExtLineRes)
-anExtLineShape = anExtLineRes.shape()
-assert(anExtLineShape)
 aLineProjector = aSketchFeature.addFeature("SketchProjection")
-aLineProjector.selection("ExternalFeature").setValue(anExtLineRes, anExtLineShape)
+aLineProjector.selection("ExternalFeature").selectSubShape("EDGE", "Sketch_1/Edge-SketchLine_1")
 aLineProjector.execute()
 
-anExtCircRes = modelAPI_Result(aDocument.objectByName("Construction", "SketchCircle_1_2"))
-assert(anExtCircRes)
-anExtCircShape = anExtCircRes.shape()
-assert(anExtCircShape)
 aCircleProjector = aSketchFeature.addFeature("SketchProjection")
-aCircleProjector.selection("ExternalFeature").setValue(anExtCircRes, anExtCircShape)
+aCircleProjector.selection("ExternalFeature").selectSubShape("EDGE", "Sketch_1/Edge-SketchCircle_1_2")
 aCircleProjector.execute()
 
-anExtArcRes = modelAPI_Result(aDocument.objectByName("Construction", "SketchArc_1_2"))
-assert(anExtArcRes)
-anExtArcShape = anExtArcRes.shape()
-assert(anExtArcShape)
 anArcProjector = aSketchFeature.addFeature("SketchProjection")
-anArcProjector.selection("ExternalFeature").setValue(anExtArcRes, anExtArcShape)
+anArcProjector.selection("ExternalFeature").selectSubShape("EDGE", "Sketch_1/Edge-SketchArc_1_2")
 anArcProjector.execute()
 aSession.finishOperation()
 #=========================================================================
@@ -137,3 +125,6 @@ assert(math.fabs(aProjLineEnd.y() - aLineEnd.y()) < 1.e-10)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index d4c7061a30833483398f702956aa9b554012deab..b822c58d3c1cbf655907601f3afea7a38cbbcbe9 100644 (file)
@@ -88,3 +88,6 @@ assert (aNbLines == 4)
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 8d8c4c82043cfe51a01da07904e9716b08986605..ed61f3fae28c84de90367df65fc08423bb4835f1 100644 (file)
@@ -96,19 +96,13 @@ assert (len(aSketchReflist.list()) == 0)
 aSketchArc = aSketchFeature.addFeature("SketchArc")
 assert (aSketchArc.getKind() == "SketchArc")
 anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
-assert (anArcCentr.x() == 0)
-assert (anArcCentr.y() == 0)
 assert (not anArcCentr.isInitialized())
 anArcCentr.setValue(10., 10.)
 anArcStartPoint = geomDataAPI_Point2D(
     aSketchArc.attribute("ArcStartPoint"))
-assert (anArcStartPoint.x() == 0)
-assert (anArcStartPoint.y() == 0)
 assert (not anArcStartPoint.isInitialized())
 anArcStartPoint.setValue(0., 50.)
 anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
-assert (anArcEndPoint.x() == 0)
-assert (anArcEndPoint.y() == 0)
 assert (not anArcEndPoint.isInitialized())
 anArcEndPoint.setValue(50., 0.)
 aSession.finishOperation()
@@ -177,14 +171,11 @@ assert (len(aSketchReflist.list()) == 1)
 aSketchCircle = aSketchFeature.addFeature("SketchCircle")
 assert (aSketchCircle.getKind() == "SketchCircle")
 anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-assert (anCircleCentr.x() == 0)
-assert (anCircleCentr.y() == 0)
 assert (not anCircleCentr.isInitialized())
 aCircleRadius = aSketchCircle.real("CircleRadius")
 assert (type(aCircleRadius) == ModelAPI_AttributeDouble)
 # ModelAPI_AttributeDouble.typeId() is checked in ModelAPI_TestConstants
 assert (aCircleRadius.attributeType() == ModelAPI_AttributeDouble.typeId())
-assert (aCircleRadius.value() == 0)
 anCircleCentr.setValue(-25., -25)
 aCircleRadius.setValue(25.)
 assert (anCircleCentr.x() == -25)
@@ -219,6 +210,12 @@ aLineStart.setValue(0., 0.)
 aLineEnd.setValue(50., 0.)
 aSession.finishOperation()
 aSession.startOperation()
+aFixed = aSketchFeature.addFeature("SketchConstraintRigid")
+aRefObjectA = aFixed.refattr("ConstraintEntityA")
+aRefObjectA.setObject(modelAPI_ResultConstruction(aSketchLine.lastResult()))
+aFixed.execute()
+aSession.finishOperation()
+aSession.startOperation()
 aSketchArcTangent = aSketchFeature.addFeature("SketchArc")
 aSketchArcTangent.string("ArcType").setValue("Tangent")
 anArcEndPoint = geomDataAPI_Point2D(aSketchArcTangent.attribute("ArcEndPoint"))
@@ -241,11 +238,11 @@ aSketchArcTangent2.string("ArcType").setValue("Tangent")
 anArcEndPoint2 = geomDataAPI_Point2D(aSketchArcTangent2.attribute("ArcEndPoint"))
 aTangent = aSketchArcTangent2.refattr("ArcTangentPoint")
 aTangent.setAttr(anArcEndPoint)
-anArcEndPoint2.setValue(anArcEndPoint.x() + 1, anArcEndPoint.y() + 1)
-aSession.finishOperation()
-aSession.startOperation()
-anArcEndPoint2.setValue(50., 50.)
+anArcEndPoint2.setValue(50., 150.)
 aSession.finishOperation()
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index b37b0f61dd8ed40904ef4567ce0cf431ce7b2909..f7880bf34108b227bbb1e2769fbe0956093f822e 100644 (file)
@@ -47,8 +47,6 @@ assert (len(aSketchReflist.list()) == 0)
 aSketchPoint = aSketchFeature.addFeature("SketchPoint")
 assert (aSketchPoint.getKind() == "SketchPoint")
 coords = geomDataAPI_Point2D(aSketchPoint.attribute("PointCoordindates"))
-assert (coords.x() == 0)
-assert (coords.y() == 0)
 assert (not coords.isInitialized())
 # Simulate SketchPlugin_Point::move(...)
 coords.setValue(10., 10.)
@@ -72,11 +70,7 @@ assert (aSketchReflist.size() == 2)
 assert (len(aSketchReflist.list()) == 2)
 aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
 aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
-assert (aLineStartPoint.x() == 0)
-assert (aLineStartPoint.y() == 0)
 assert (not aLineStartPoint.isInitialized())
-assert (aLineEndPoint.x() == 0)
-assert (aLineEndPoint.y() == 0)
 assert (not aLineEndPoint.isInitialized())
 # Simulate SketchPlugin_Line::move(...)
 aLineStartPoint.setValue(50., 50.)
@@ -100,3 +94,6 @@ aResultConstruction = modelAPI_ResultConstruction(aResult)
 aShape = aResultConstruction.shape()
 assert (aShape is not None)
 assert (not aShape.isNull())
+
+import model
+assert(model.checkPythonDump())
index e324fd2dab9d03fcfcca604eafa30a58b31f8974..3e8b9e0045c362cfb40271738b14698e9210aa29 100644 (file)
@@ -155,3 +155,6 @@ aSession.finishOperation()
 #=========================================================================
 # End of test
 #=========================================================================
+
+import model
+assert(model.checkPythonDump())
index 5e101d2401e376e45e682b762ee37f6cb7dff7cb..a7c348db78a0c00b73b3ee9be87ea8a550d2c90d 100644 (file)
@@ -856,7 +856,7 @@ ConstraintWrapperPtr createConstraintMiddlePoint(
   aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPointOnLine(*aPoint, *aLine)));
   double aDist = lineLength(*aLine);
   std::shared_ptr<PlaneGCSSolver_ParameterWrapper> aDistance =
-      std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(createParameter(theGroupID, aDist));
+      std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(createParameter(theGroupID, aDist * 0.5));
   aConstrList.push_back(GCSConstraintPtr(
       new GCS::ConstraintP2PDistance(*aPoint, aLine->p1, aDistance->parameter())));
   aConstrList.push_back(GCSConstraintPtr(
@@ -1204,5 +1204,12 @@ void adjustMirror(ConstraintWrapperPtr theConstraint)
 
   if (aPoints.size() == 2)
     makeMirrorPoints(aPoints[0], aPoints[1], aMirrorLine);
+
+  // update scales of constraints
+  std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aGCSConstraint = 
+      std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint);
+  std::list<GCSConstraintPtr>::const_iterator aCIt = aGCSConstraint->constraints().begin();
+  for (; aCIt != aGCSConstraint->constraints().end(); ++aCIt)
+    (*aCIt)->rescale();
 }
 
index b505b2f79fdc9bcf0b5bd21c3fb37c07a1df74d9..63867f1c3bd7c6c7eaf3171d301a650745dbaf81 100644 (file)
@@ -50,7 +50,7 @@ void SketchSolver_ConstraintMirror::getAttributes(
     }
   }
 
-  if (theBaseEntities.size() > theMirrorEntities.size())
+  if (theBaseEntities.size() > theMirrorEntities.size() || aMirroredList.empty())
     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
 }
 
@@ -79,18 +79,18 @@ void SketchSolver_ConstraintMirror::process()
   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
   std::list<ConstraintWrapperPtr> aMirConstrList;
 
-  std::vector<EntityWrapperPtr>::iterator aBIt = aBaseList.begin();
+  // update mirrored features to be in the current group
   std::vector<EntityWrapperPtr>::iterator aMIt = aMirrorList.begin();
-  for (; aBIt != aBaseList.end(); ++aBIt, ++aMIt) {
+  for (; aMIt != aMirrorList.end(); ++aMIt)
+    myStorage->update((*aMIt)->baseFeature(), myGroupID);
+
+  std::vector<EntityWrapperPtr>::iterator aBIt = aBaseList.begin();
+  for (aMIt = aMirrorList.begin(); aBIt != aBaseList.end(); ++aBIt, ++aMIt) {
     aNewConstraints = aBuilder->createConstraint(
         myBaseConstraint, myGroupID, mySketchID, aConstrType,
         0.0, *aBIt, *aMIt, aMirrorLine);
     aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end());
   }
-
-  // update mirrored features to be in the current group
-  for (aMIt = aMirrorList.begin(); aMIt != aMirrorList.end(); ++aMIt)
-    myStorage->update((*aMIt)->baseFeature(), myGroupID);
   myStorage->addConstraint(myBaseConstraint, aMirConstrList);
 
   adjustConstraint();
index 4748424f865e704108d37e2005a6dce2557fda3c..61c0547b08e6c46f2cef8a57854c8dae675cea41 100644 (file)
@@ -279,7 +279,7 @@ bool SketchSolver_Manager::changeWorkplane(CompositeFeaturePtr theSketch)
     }
     myGroups.push_back(aNewGroup);
   }
-  return aResult;
+  return aResult || isUpdated;
 }
 
 // ============================================================================
index 84d0878f66df2d68817c3f3f12620e322a5bd50b..b8e37cc53219fad4b3248a423e77942ea8077958 100644 (file)
@@ -246,7 +246,9 @@ double getFlyoutDistance(const ModelAPI_Feature* theConstraint)
   std::shared_ptr<GeomDataAPI_Point2D> aFlyoutPoint =
       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       const_cast<ModelAPI_Feature*>(theConstraint)->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
-
+  // for not initialized values return zero distance to avoid Presentation crash
+  if (!aFlyoutPoint->isInitialized())
+    return 0;
   return aFlyoutPoint->y();
 }