Salome HOME
Dump Python in the High Level Parameterized Geometry API (issue #1648)
authorazv <azv@opencascade.com>
Wed, 3 Aug 2016 06:43:53 +0000 (09:43 +0300)
committerazv <azv@opencascade.com>
Fri, 5 Aug 2016 07:14:55 +0000 (10:14 +0300)
1. Dumper base functionality.
2. Feature to dump model into Python script.
3. Dump parameters, parts, sketches and points on sketches.
4. Uncompleted dump for point from ConstructionPlugin.

26 files changed:
src/ConstructionAPI/ConstructionAPI_Point.cpp
src/ConstructionAPI/ConstructionAPI_Point.h
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/icons/dump.png [new file with mode: 0644]
src/ExchangePlugin/plugin-Exchange.xml
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_Interface.h
src/ModelHighAPI/ModelHighAPI_Services.cpp
src/ModelHighAPI/ModelHighAPI_Services.h
src/ModelHighAPI/ModelHighAPI_swig.h
src/ParametersAPI/ParametersAPI_Parameter.cpp
src/ParametersAPI/ParametersAPI_Parameter.h
src/PartSetAPI/PartSetAPI_Part.cpp
src/PartSetAPI/PartSetAPI_Part.h
src/PythonAPI/model/dump/DumpAssistant.py [new file with mode: 0644]
src/PythonAPI/model/dump/__init__.py [new file with mode: 0644]
src/SketchAPI/SketchAPI_Point.cpp
src/SketchAPI/SketchAPI_Point.h
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h

index c503c16fa9c0885473a0ee4c8a672a558cb832d5..76be0f73bb2e6fd569af7b999a0fdb50592aafa1 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <GeomAPI_Shape.h>
 
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 
@@ -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 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..d89f6d9
--- /dev/null
@@ -0,0 +1,52 @@
+// 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();
+  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();
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 dfd97daaf3479d08a7c7adc122a600755cd88bb6..d92154841749757bb82135c7e422a7aeee17581c 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
@@ -17,6 +18,7 @@ SET(PROJECT_HEADERS
 
 SET(PROJECT_SOURCES
   ModelHighAPI_Double.cpp
+  ModelHighAPI_Dumper.cpp
   ModelHighAPI_Integer.cpp
   ModelHighAPI_Interface.cpp
   ModelHighAPI_RefAttr.cpp
@@ -34,7 +36,7 @@ SET(PROJECT_LIBRARIES
   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)
@@ -57,6 +59,8 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/GeomAPI
   ${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..4f4312e23b6ed62d3cea28ce5b5ec28ac09578c1 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)
 
 
 // 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..5bff806
--- /dev/null
@@ -0,0 +1,368 @@
+// 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_AttributeInteger.h>
+#include <ModelAPI_AttributeSelection.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 <algorithm>
+#include <fstream>
+
+//#define DUMP_USER_DEFINED_NAMES
+
+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()
+{
+  myDumpBuffer = std::ostringstream();
+  myDumpBuffer << std::setprecision(16);
+}
+
+const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity)
+{
+  EntityNameMap::const_iterator aFound = myNames.find(theEntity);
+  if (aFound != myNames.end())
+    return aFound->second.first;
+
+  // entity is not found, store it
+  std::string aName;
+  bool isNameDefined = false;
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theEntity);
+  if (aFeature) {
+    aName = aFeature->name();
+    isNameDefined = !aName.empty();
+
+    if (!isNameDefined) {
+      static long anIndex = 0;
+      // set default name: feature ID + index
+      std::ostringstream aConverter;
+      aConverter << aFeature->getKind() << "_" << ++anIndex;
+      aName = aConverter.str();
+      std::transform(aName.begin(), aName.end(), aName.begin(), ::tolower);
+    }
+  }
+
+  myNames[theEntity] = std::pair<std::string, bool>(aName, isNameDefined);
+  return myNames[theEntity].first;
+}
+
+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;
+}
+
+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] = std::pair<std::string, bool>(aDocName, false);
+  *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;
+  // dump all features
+  std::list<FeaturePtr> aFeatures = theDoc->allFeatures();
+  std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
+  for (; aFeatIt != aFeatures.end(); ++aFeatIt) {
+    dumpFeature(*aFeatIt);
+    // iteratively process composite features
+    CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
+    if (!aCompFeat)
+      continue;
+
+    // sub-part is processed independently, because it provides separate document
+    if ((*aFeatIt)->getKind() == PartSetPlugin_Part::ID()) {
+      ResultPartPtr aPartResult =
+          std::dynamic_pointer_cast<ModelAPI_ResultPart>((*aFeatIt)->lastResult());
+      if (!aPartResult)
+        continue;
+      DocumentPtr aSubDoc = aPartResult->partDoc();
+      // set name of document equal to part name
+      myNames[aSubDoc] = myNames[*aFeatIt];
+
+      isOk = process(aSubDoc) && isOk;
+    } else 
+      isOk = process(aCompFeat) && isOk;
+  }
+  return isOk;
+}
+
+bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite)
+{
+  // dump all sub-features;
+  int aNbSubs = theComposite->numberOfSubs();
+  for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
+    FeaturePtr aFeature = theComposite->subFeature(anIndex);
+    dumpFeature(aFeature, true);
+  }
+  // dump command to update model
+  myDumpBuffer << "model.do()" << std::endl;
+  return true;
+}
+
+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 << 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()
+{
+  if (!myLastEntityWithName)
+    return;
+
+#ifdef DUMP_USER_DEFINED_NAMES
+  const std::string& aName = name(myLastEntityWithName);
+  myDumpBuffer << aName;
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myLastEntityWithName);
+  if (aFeature)
+    myDumpBuffer << ".feature()";
+  myDumpBuffer << ".data().setName(\"" << aName << "\")" << std::endl;
+#endif
+  myLastEntityWithName = EntityPtr();
+}
+
+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 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();
+  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 EntityPtr& theEntity)
+{
+  myDumpBuffer << name(theEntity);
+  if (myNames[theEntity].second)
+    myLastEntityWithName = theEntity;
+  return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+    const std::shared_ptr<ModelAPI_AttributeSelection>& theAttrSelect)
+{
+  myDumpBuffer << "\"" << theAttrSelect->namingName() << "\"";
+  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;
+  theDumper.dumpEntitySetName();
+  return theDumper;
+}
diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h
new file mode 100644 (file)
index 0000000..6752289
--- /dev/null
@@ -0,0 +1,179 @@
+// 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 <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <string>
+
+class GeomAPI_Pnt;
+class GeomAPI_Dir;
+
+class GeomDataAPI_Dir;
+class GeomDataAPI_Point;
+class GeomDataAPI_Point2D;
+
+class ModelAPI_AttributeBoolean;
+class ModelAPI_AttributeDouble;
+class ModelAPI_AttributeInteger;
+class ModelAPI_AttributeSelection;
+class ModelAPI_AttributeString;
+class ModelAPI_CompositeFeature;
+class ModelAPI_Document;
+class ModelAPI_Entity;
+class ModelAPI_Feature;
+
+typedef std::shared_ptr<ModelAPI_Entity>  EntityPtr;
+typedef std::shared_ptr<ModelAPI_Feature> FeaturePtr;
+
+/**\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
+  MODELHIGHAPI_EXPORT
+  const std::string& name(const EntityPtr& theEntity);
+
+  /// Returns name of parent composite feature for specified entity
+  MODELHIGHAPI_EXPORT
+  const std::string& parentName(const FeaturePtr& theFeature);
+
+  /// Dump given feature
+  virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 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 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 EntityPtr& theEntity);
+
+  /// Dump AttributeSelection
+  MODELHIGHAPI_EXPORT
+  ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeSelection>& theAttrSelect);
+
+protected:
+  /// Dump "setName" command if last entity had user-defined name
+  MODELHIGHAPI_EXPORT void dumpEntitySetName();
+
+  /// Clear dump buffer
+  void clear();
+
+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);
+
+  /// Iterate all features in composite feature and dump them into intermediate buffer
+  bool process(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite);
+
+private:
+  typedef std::map<EntityPtr, std::pair<std::string, bool> > EntityNameMap;
+  typedef std::map<std::string, std::set<std::string> >      ModulesMap;
+
+  static ModelHighAPI_Dumper* mySelf;
+
+  std::ostringstream  myDumpBuffer;         ///< intermediate buffer to store dumping data
+  ModulesMap          myModules;            ///< modules and entities to be imported
+  EntityNameMap       myNames;              ///< names of the entities
+  EntityPtr           myLastEntityWithName; ///< not null, if last dumped entity had user defined name
+};
+
+#endif
index 7d61ffbfb69ee940f6f987d0075f216881beb53a..143be4e53d12069a44b0bb98fedc6a9876f9ac9b 100644 (file)
@@ -18,6 +18,7 @@
 class ModelAPI_Feature;
 class ModelAPI_Result;
 class ModelHighAPI_Selection;
+class ModelHighAPI_Dumper;
 //--------------------------------------------------------------------------------------
 /**\class ModelHighAPI_Interface
  * \ingroup CPPHighAPI
@@ -58,6 +59,10 @@ public:
   MODELHIGHAPI_EXPORT
   void throwException(const std::string & theDescription);
 
+  /// Dump wrapped feature
+  MODELHIGHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const {}
+
 protected:
   std::shared_ptr<ModelAPI_Feature> myFeature;
 };
index 09be73726729380ce997b7d211ac4383deba5a6c..80f466e5e4568f11685293587b84eef39aed9382 100644 (file)
@@ -11,6 +11,8 @@
 #include <GeomAPI_Pnt.h>
 #include <ModelAPI_Session.h>
 
+#include <cmath>
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<ModelAPI_Document> moduleDocument()
 {
@@ -42,6 +44,32 @@ 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();
+}
+
 //--------------------------------------------------------------------------------------
 void begin()
 {
index 4d0578382469dcabd6218c6c5e7ee429e795f573..fa500e5de5bfede57dc724de4a8673c8d82d3e55 100644 (file)
@@ -14,6 +14,8 @@
 #include <string>
 //--------------------------------------------------------------------------------------
 class GeomAPI_Ax3;
+class GeomAPI_Dir;
+class GeomAPI_Pnt;
 class ModelAPI_Document;
 //--------------------------------------------------------------------------------------
 /// Return the main document (the Partset) created or open from the Modeler.
@@ -35,6 +37,12 @@ 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);
+
 /** Start a data structure transaction.
  *
  *  Make a control point for being able to discard or undo
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 0faa1346af1cc6a013a1499e88444aa5ea049016..8781004a0c711f49df97c355fab7c5c6359435a3 100644 (file)
@@ -7,6 +7,7 @@
 //--------------------------------------------------------------------------------------
 #include "ParametersAPI_Parameter.h"
 //--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 ParametersAPI_Parameter::ParametersAPI_Parameter(
@@ -36,6 +37,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);
+
+  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 e55cc920ff6d1a69e2de3e3e17a117fc039b082d..acda463d3a1651c918b17084eefd841d154474df 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 << ").document()" << 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
diff --git a/src/PythonAPI/model/dump/DumpAssistant.py b/src/PythonAPI/model/dump/DumpAssistant.py
new file mode 100644 (file)
index 0000000..457c711
--- /dev/null
@@ -0,0 +1,49 @@
+"""Package for dumping purposes.
+"""
+
+import ModelHighAPI
+
+import ModelAPI
+
+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 aFeatureKind == "Parameter" or theFeature.isInHistory():
+                self.myFeatures[aFeatureKind](theFeature).dump(self)
+            else:
+                self.name(theFeature)
+
+
+# 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 c133a74c08b8e51cad0f5c1293b758aeff1f591a..08df487e4af1bf2f4d13ed80a322a78d18d6ee2f 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,20 @@ void SketchAPI_Point::setByExternalName(const std::string & theExternalName)
 }
 
 //--------------------------------------------------------------------------------------
+
+void SketchAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->value()) {
+    // point is external
+    theDumper << aBase << " = " << aSketchName << ".addPoint(" << anExternal << ")" << std::endl;
+  } else {
+    // point given by coordinates
+    std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+        aBase->attribute(SketchPlugin_Point::COORD_ID()));
+    theDumper << aBase << " = " << aSketchName << ".addPoint(" << aPoint << ")" << std::endl;
+  }
+}
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 2a8e7e141f12046de459a3b6955c654cb3951079..32ed616d36adfb38692bb29fb3d75d88d0110a4a 100644 (file)
 //--------------------------------------------------------------------------------------
 #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"
@@ -572,3 +574,46 @@ 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()) {
+    FeaturePtr aPlnFeature = ModelAPI_Feature::feature(anExternal->context()->data()->owner());
+    const std::string& aPlaneName = theDumper.name(aPlnFeature);
+    theDumper << aBase << " = model.addSketch(" << aDocName << ", \"" << aPlaneName << "\")" << 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 (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";
+      theDumper << anOriginName << " = " << anOrigin << std::endl
+                << aNormalName  << " = " << aNormal  << std::endl
+                << aDirXName    << " = " << aDirX    << std::endl;
+      // 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;
+    }
+  }
+}
index e23f9dd905861f19220192606950b8ff975afeca..e74096348eeda06487d5b7981f90c05fc1b3a2cf 100644 (file)
@@ -333,6 +333,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;