Salome HOME
Task 5.1.7: To be able to export a part to a file and import it into an existing...
authorazv <azv@opencascade.com>
Tue, 12 Nov 2019 12:24:33 +0000 (15:24 +0300)
committerazv <azv@opencascade.com>
Tue, 12 Nov 2019 12:24:33 +0000 (15:24 +0300)
Exporting/importing references to external objects.

14 files changed:
src/ExchangeAPI/ExchangeAPI_Export.cpp
src/ExchangeAPI/ExchangeAPI_Import.cpp
src/ExchangePlugin/CMakeLists.txt
src/ExchangePlugin/ExchangePlugin_ExportPart.cpp
src/ExchangePlugin/ExchangePlugin_ImportPart.cpp
src/Model/CMakeLists.txt
src/Model/Model_AttributeReference.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_Data.h
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Tools.cpp
src/Model/Model_Tools.h
src/ModelAPI/ModelAPI_Document.h

index e9863969ca7195ea9a940f1819c23d1a1155bb01..2d764635a27b543c56fcc5f751cba48a17417922 100644 (file)
@@ -200,7 +200,7 @@ void exportPart(const std::shared_ptr<ModelAPI_Document> & thePart,
     fillAttribute(theSelected,
         aFeature->selectionList(ExchangePlugin_ExportPart::SELECTION_LIST_ID()));
   }
-  // restart transaction to execute and delete the marcro-feature
+  // restart transaction to execute and delete the macro-feature
   apply();
 }
 //--------------------------------------------------------------------------------------
index 81b34ac03e66d53ddfbf1a6f921d0c6833c51327..e585f971e036d7b379c9f96b1eaf44f916556329 100644 (file)
@@ -111,7 +111,7 @@ void importPart(const std::shared_ptr<ModelAPI_Document> & thePart,
 
   FeaturePtr aFeature = thePart->addFeature(ExchangePlugin_ImportPart::ID());
   aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(theFilePath);
-  // restart transaction to execute and delete the marcro-feature
+  // restart transaction to execute and delete the macro-feature
   apply();
 
   // restore current feature
index 4094385a5519021c968b78e5fa2b139892de4c14..875a0a917ff51830924a5f030007ec7ba34b5501 100644 (file)
@@ -27,6 +27,8 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/GeomAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
                     ${PROJECT_SOURCE_DIR}/src/XAO
+                    ${PROJECT_SOURCE_DIR}/src/ConstructionPlugin
+                    ${PROJECT_SOURCE_DIR}/src/PartSetPlugin
 )
 
 SET(PROJECT_HEADERS
index 79de399f8e69c93eb2d4b93be3c5ce25733c72c0..626f835e823da6abdf80df2da9ee313d1f868e77 100644 (file)
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 
+#include <ConstructionPlugin_Axis.h>
+#include <ConstructionPlugin_Plane.h>
+#include <ConstructionPlugin_Point.h>
+
 // Obtain all features to be exported to get the list of selected results.
 static void collectFeatures(AttributeSelectionListPtr theSelected,
                             std::list<FeaturePtr>& theExport);
@@ -145,7 +149,19 @@ void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExp
   // keep constructions only
   std::list<FeaturePtr>::iterator anIt = theExport.begin();
   while (anIt != theExport.end()) {
-    if ((*anIt)->lastResult()->groupName() == ModelAPI_ResultConstruction::group())
+    FeaturePtr aCurFeature = *anIt;
+    ResultPtr aCurResult = aCurFeature->lastResult();
+
+    bool isApplicable =
+        (!aCurResult || aCurResult->groupName() == ModelAPI_ResultConstruction::group());
+
+    if (isApplicable && !aCurFeature->isInHistory()) {
+      isApplicable = aCurFeature->getKind() != ConstructionPlugin_Point::ID() &&
+                     aCurFeature->getKind() != ConstructionPlugin_Axis::ID() &&
+                     aCurFeature->getKind() != ConstructionPlugin_Plane::ID();
+    }
+
+    if (isApplicable)
       ++anIt;
     else {
       std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
index ed0c456b75c903f7ee08c9e9f4de0ca8936366f6..11eae6c0d742c8420780de2e9bf1297a797bf0c2 100644 (file)
 #include <ExchangePlugin_ImportPart.h>
 
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Session.h>
 
+#include <PartSetPlugin_Part.h>
+
 ExchangePlugin_ImportPart::ExchangePlugin_ImportPart()
 {
 }
@@ -42,6 +45,20 @@ void ExchangePlugin_ImportPart::execute()
 
   // load the file into the active document
   SessionPtr aSession = ModelAPI_Session::get();
-  if (!aSession->activeDocument()->import(aFilename.c_str()))
+  DocumentPtr aDoc = aSession->activeDocument();
+  bool isPartSet = aDoc == aSession->moduleDocument();
+  bool isOk = aDoc->import(aFilename.c_str(), isPartSet);
+  if (!isOk && isPartSet) {
+    // there are features not appropriate for PartSet,
+    // create new part and load there
+    FeaturePtr aPartFeature = aDoc->addFeature(PartSetPlugin_Part::ID());
+    ResultPartPtr aPartResult;
+    if (aPartFeature) {
+      aPartFeature->execute();
+      aPartResult = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aPartFeature->lastResult());
+    }
+    isOk = aPartResult && aPartResult->partDoc()->import(aFilename.c_str());
+  }
+  if (!isOk)
     setError("Cannot import the document.");
 }
index 348761424e3bcb49e95e9bfc0c87dab64cd36e07..eaac6b906a332e4eddcde3e7621f0c4de4a8d630 100644 (file)
@@ -117,6 +117,7 @@ SET(PROJECT_INCLUDES
   ../GeomAlgoAPI
   ../GeomAPI
   ../ModelGeomAlgo
+  ../ConstructionPlugin
   ${OpenCASCADE_INCLUDE_DIR}
 )
 
index 2a2f5fa6791fee09f7b3762587f1663bb988d611..0b2d2869a3ed7f120f5f1449c405a21d598d94d9 100644 (file)
@@ -125,6 +125,7 @@ void Model_AttributeReference::reinit()
   myIsInitialized = myLab.FindAttribute(TDF_Reference::GetID(), myRef) == Standard_True;
   if (!myIsInitialized) {
     myRef = TDF_Reference::Set(myLab, myLab);  // not initialized references to itself
+    myIsInitialized = true;
   } else {
     if (owner()) {
       std::shared_ptr<Model_Document> aDoc =
index d636a3804608ac6af36832320f5e6dab92f3bbdc..c37149ede2ad5603bf6b3e4b8746adc28b4d759c 100644 (file)
@@ -421,32 +421,29 @@ bool Model_AttributeSelection::isInvalid()
 
 bool Model_AttributeSelection::isInitialized()
 {
-  if (ModelAPI_AttributeSelection::isInitialized()) { // additional checks if it is initialized
-    std::shared_ptr<GeomAPI_Shape> aResult;
-    if (myRef.isInitialized()) {
-      TDF_Label aSelLab = selectionLabel();
-      // it is just reference to shape, not sub-shape
-      if (aSelLab.IsAttribute(kSIMPLE_REF_ID) || aSelLab.IsAttribute(kPART_REF_ID)) {
-        ResultPtr aContext = context();
-        return aContext.get() != NULL;
-      }
-      Handle(TNaming_NamedShape) aSelection;
-      if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
-        return !aSelection->Get().IsNull();
-      } else { // for simple construction element: just shape of this construction element
-        if (myRef.value().get())
-          return true;
-        // check that this is on open of document, so, results are not initialized yet
-        TDF_Label aRefLab = myRef.myRef->Get();
-        if (aRefLab.IsNull() || !owner().get())
-          return false;
-        std::shared_ptr<Model_Document> aMyDoc =
-          std::dynamic_pointer_cast<Model_Document>(owner()->document());
-        if (!aMyDoc.get())
-          return false;
-        // check at least the feature exists
-        return aMyDoc->featureByLab(aRefLab).get() != NULL;
-      }
+  if (myRef.isInitialized()) {
+    TDF_Label aSelLab = selectionLabel();
+    // it is just reference to shape, not sub-shape
+    if (aSelLab.IsAttribute(kSIMPLE_REF_ID) || aSelLab.IsAttribute(kPART_REF_ID)) {
+      ResultPtr aContext = context();
+      return aContext.get() != NULL;
+    }
+    Handle(TNaming_NamedShape) aSelection;
+    if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
+      return !aSelection->Get().IsNull();
+    } else { // for simple construction element: just shape of this construction element
+      if (myRef.value().get())
+        return true;
+      // check that this is on open of document, so, results are not initialized yet
+      TDF_Label aRefLab = myRef.myRef->Get();
+      if (aRefLab.IsNull() || !owner().get())
+        return false;
+      std::shared_ptr<Model_Document> aMyDoc =
+        std::dynamic_pointer_cast<Model_Document>(owner()->document());
+      if (!aMyDoc.get())
+        return false;
+      // check at least the feature exists
+      return aMyDoc->featureByLab(aRefLab).get() != NULL;
     }
   }
   return false;
@@ -476,7 +473,7 @@ void Model_AttributeSelection::setID(const std::string theID)
 
 ResultPtr Model_AttributeSelection::context()
 {
-  if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
+  if (!myRef.isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
     return ResultPtr();
 
   if (myTmpContext.get() || myTmpSubShape.get()) {
index 9f26d8de1050bd4a25b85f481e00f243534c7906..7f9fa9b01584f120771ad4405ceaa1dfe24022bd 100644 (file)
@@ -96,6 +96,7 @@ class Model_Data : public ModelAPI_Data
   friend class Model_SelectionNaming;
   friend class Model_ResultConstruction;
   friend class Model_ResultBody;
+  friend class Model_Tools;
 
  public:
   /// The simplest constructor. "setLabel" must be called just after to initialize correctly.
index c69e0c5cb0abe63fab1ab559f5353c295d74eb28..c2323e13b55dc8b7994adb1d7a6fca2f100423d4 100644 (file)
@@ -349,7 +349,7 @@ bool Model_Document::load(const char* theDirName, const char* theFileName, Docum
   return isOk;
 }
 
-bool Model_Document::import(const char* theFileName)
+bool Model_Document::import(const char* theFileName, bool theCheckBefore)
 {
   Handle(Model_Application) anApp = Model_Application::getApplication();
   TCollection_ExtendedString aFormat;
@@ -359,43 +359,67 @@ bool Model_Document::import(const char* theFileName)
   Handle(TDocStd_Document) aTempDoc;
   bool isOk = loadDocument(anApp, aTempDoc, theFileName);
 
-  // copy features from the temporary document to the current
-  Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
-  TDF_LabelList anAllNewFeatures;
-  // Perform the copying twice for correct references:
-  // 1. copy labels hierarchy and fill the relocation table
-  TDF_Label aMain = myDoc->Main();
-  for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More(); anIt.Next()) {
-    TDF_Label aCurrentLab = anIt.Value();
-    Handle(TDataStd_Comment) aFeatureID;
-    TDF_Label aNewFeatuerLab;
-    if (aCurrentLab.FindAttribute(TDataStd_Comment::GetID(), aFeatureID)) {
-      TCollection_AsciiString anID(aFeatureID->Get());
-      FeaturePtr aNewFeature = addFeature(anID.ToCString());
-      std::shared_ptr<Model_Data> aData =
-          std::dynamic_pointer_cast<Model_Data>(aNewFeature->data());
-      aNewFeatuerLab = aData->label().Father();
-      Model_Tools::copyLabels(aCurrentLab, aNewFeatuerLab, aRelocTable);
-    }
-    anAllNewFeatures.Append(aNewFeatuerLab);
-  }
-  // 2. copy attributes
-  TDF_ListIteratorOfLabelList aNewIt(anAllNewFeatures);
-  for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More(); anIt.Next()) {
-    TDF_Label aCurrentLab = anIt.Value();
-    TDF_Label aFeatureLab = aNewIt.Value();
-    if (aFeatureLab.IsNull())
-      anAllNewFeatures.Remove(aNewIt);
-    else {
-      Model_Tools::copyAttrs(aCurrentLab, aFeatureLab, aRelocTable);
-      aNewIt.Next();
+  if (isOk && theCheckBefore) {
+    // verify all features are applicable for the current document type (e.g. PartSet)
+    std::shared_ptr<Model_Session> aSession =
+        std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get());
+    for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More() && isOk; anIt.Next()) {
+      TDF_Label aCurrentLab = anIt.Value();
+      Handle(TDataStd_Comment) aFeatureID;
+      TDF_Label aNewFeatuerLab;
+      if (aCurrentLab.FindAttribute(TDataStd_Comment::GetID(), aFeatureID)) {
+        TCollection_AsciiString anID(aFeatureID->Get());
+        std::string aFeatureKind(anID.ToCString());
+        if (aSession->myPlugins.find(aFeatureKind) != aSession->myPlugins.end()) {
+          std::string& aDocKind = aSession->myPlugins[aFeatureKind].second;
+          isOk = aDocKind.empty() || aDocKind == kind();
+        }
+      }
     }
   }
 
-  myObjs->synchronizeFeatures(anAllNewFeatures, true, false, false, true);
+  if (isOk) {
+    // copy features from the temporary document to the current
+    Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable();
+    TDF_LabelList anAllNewFeatures;
+    // Perform the copying twice for correct references:
+    // 1. copy labels hierarchy and fill the relocation table
+    TDF_Label aMain = myDoc->Main();
+    for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More(); anIt.Next()) {
+      TDF_Label aCurrentLab = anIt.Value();
+      Handle(TDataStd_Comment) aFeatureID;
+      TDF_Label aNewFeatuerLab;
+      if (aCurrentLab.FindAttribute(TDataStd_Comment::GetID(), aFeatureID)) {
+        TCollection_AsciiString anID(aFeatureID->Get());
+        FeaturePtr aNewFeature = addFeature(anID.ToCString());
+        std::shared_ptr<Model_Data> aData =
+            std::dynamic_pointer_cast<Model_Data>(aNewFeature->data());
+        aNewFeatuerLab = aData->label().Father();
+        Model_Tools::copyLabels(aCurrentLab, aNewFeatuerLab, aRelocTable);
+      }
+      anAllNewFeatures.Append(aNewFeatuerLab);
+    }
+    // 2. copy attributes
+    std::set<TCollection_AsciiString> aCoordinateLabels;
+    Model_Tools::labelsOfCoordinates(aCoordinateLabels, aRelocTable);
+    TDF_ListIteratorOfLabelList aNewIt(anAllNewFeatures);
+    for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More(); anIt.Next()) {
+      TDF_Label aCurrentLab = anIt.Value();
+      TDF_Label aFeatureLab = aNewIt.Value();
+      if (aFeatureLab.IsNull())
+        anAllNewFeatures.Remove(aNewIt);
+      else {
+        Model_Tools::copyAttrsAndKeepRefsToCoordinates(
+            aCurrentLab, aFeatureLab, aCoordinateLabels, aRelocTable);
+        aNewIt.Next();
+      }
+    }
 
-  if (aTempDoc->CanClose() == CDM_CCS_OK)
-    aTempDoc->Close();
+    myObjs->synchronizeFeatures(anAllNewFeatures, true, false, false, true);
+  }
+
+  if (anApp->CanClose(aTempDoc) == CDM_CCS_OK)
+    anApp->Close(aTempDoc);
   return isOk;
 }
 
@@ -531,7 +555,7 @@ bool Model_Document::save(const char* theFilename,
   Handle(TDocStd_Document) aTempDoc = new TDocStd_Document(aFormat);
   TDF_Label aMain = aTempDoc->Main();
 
-  Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
+  Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable();
   std::list<FeaturePtr>::const_iterator anIt = theExportFeatures.begin();
   // Perform the copying twice for correct references:
   // 1. copy labels hierarchy and fill the relocation table
@@ -541,11 +565,14 @@ bool Model_Document::save(const char* theFilename,
     Model_Tools::copyLabels(aData->label().Father(), aFeatureLab, aRelocTable);
   }
   // 2. copy attributes
+  std::set<TCollection_AsciiString> aCoordinateLabels;
+  Model_Tools::labelsOfCoordinates(aCoordinateLabels, aRelocTable);
   TDF_ChildIterator aChildIt(aMain);
   for (anIt = theExportFeatures.begin(); anIt != theExportFeatures.end(); ++anIt) {
     TDF_Label aFeatureLab = aChildIt.Value();
     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>((*anIt)->data());
-    Model_Tools::copyAttrs(aData->label().Father(), aFeatureLab, aRelocTable);
+    Model_Tools::copyAttrsAndKeepRefsToCoordinates(
+        aData->label().Father(), aFeatureLab, aCoordinateLabels, aRelocTable);
     aChildIt.Next();
   }
 
index 2cf44cbd0bcdb7b1d6eadf65e7036cf8d7977138..f7246758f6a2cae082b0ce3a1a04ebfc9e913545 100644 (file)
@@ -59,8 +59,10 @@ class Model_Document : public ModelAPI_Document
   //! Loads the OCAF document from the file into the current document.
   //! All the features are added after the active feature.
   //! \param theFileName name of the file to import
+  //! \param theCheckBefore verify the document does not contain unappropriate features
+  //!                       (useful for import to PartSet)
   //! \returns true if file was loaded successfully
-  MODEL_EXPORT virtual bool import(const char* theFileName);
+  MODEL_EXPORT virtual bool import(const char* theFileName, bool theCheckBefore = false);
 
   //! Saves the OCAF document to the file.
   //! \param theDirName directory where the document will be saved
index 33bafd04d21fb4c6f46219fd2824848349d39b77..48831807a3496897672b5b6809845bf6b5bc8fd3 100644 (file)
 //
 
 #include <Model_Tools.h>
+#include <Model_Data.h>
+
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Result.h>
+#include <ModelAPI_Session.h>
+
+#include <ConstructionPlugin_Axis.h>
+#include <ConstructionPlugin_Plane.h>
+#include <ConstructionPlugin_Point.h>
 
 #include <Standard_GUID.hxx>
 
+#include <TDataStd_Comment.hxx>
+#include <TDataStd_AsciiString.hxx>
+
 #include <TDF_AttributeIterator.hxx>
 #include <TDF_ChildIterator.hxx>
 #include <TDF_Reference.hxx>
 #include <TDF_RelocationTable.hxx>
+#include <TDF_Tool.hxx>
 
 void Model_Tools::copyLabels(TDF_Label theSource, TDF_Label theDestination,
                              Handle(TDF_RelocationTable) theRelocTable)
@@ -69,3 +83,99 @@ void Model_Tools::copyAttrs(TDF_Label theSource, TDF_Label theDestination,
               theRelocTable);
   }
 }
+
+static TCollection_AsciiString labelToString(TDF_Label theLabel)
+{
+  TCollection_AsciiString aLabString;
+  TDF_Tool::Entry(theLabel, aLabString);
+  return aLabString;
+}
+
+static void makeExternalReference(TDF_Label theDestination, TDF_Label theReferred)
+{
+  Handle(TDF_Attribute) aReference, aComment, aString;
+  theDestination.FindAttribute(TDF_Reference::GetID(), aReference);
+  // create new attributes if not yet exists in the destination
+  if (!theDestination.FindAttribute(TDataStd_Comment::GetID(), aComment)) {
+    aComment = new TDataStd_Comment;
+    theDestination.AddAttribute(aComment);
+  }
+  if (!theDestination.FindAttribute(TDataStd_AsciiString::GetID(), aString)) {
+    aString = new TDataStd_AsciiString;
+    theDestination.AddAttribute(aString);
+  }
+  // reference to itself
+  Handle(TDF_Reference)::DownCast(aReference)->Set(theDestination, theDestination);
+  // ID of the document
+  std::ostringstream aDocIdStr;
+  aDocIdStr << ModelAPI_Session::get()->moduleDocument()->id();
+  Handle(TDataStd_Comment)::DownCast(aComment)->Set(aDocIdStr.str().c_str());
+  // value of referred label
+  Handle(TDataStd_AsciiString)::DownCast(aString)->Set(labelToString(theReferred));
+}
+
+void Model_Tools::copyAttrsAndKeepRefsToCoordinates(
+    TDF_Label theSource,
+    TDF_Label theDestination,
+    const std::set<TCollection_AsciiString>& theCoordinateLabels,
+    Handle(TDF_RelocationTable) theRelocTable)
+{
+  TDF_AttributeIterator anAttrIter(theSource);
+  for(; anAttrIter.More(); anAttrIter.Next()) {
+    Handle(TDF_Attribute) aTargetAttr;
+    if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
+      // create a new attribute if not yet exists in the destination
+           aTargetAttr = anAttrIter.Value()->NewEmpty();
+      theDestination.AddAttribute(aTargetAttr);
+    }
+    anAttrIter.Value()->Paste(aTargetAttr, theRelocTable);
+    if (aTargetAttr->ID() == TDF_Reference::GetID()) {
+      Handle(TDF_Reference) aTargetRef = Handle(TDF_Reference)::DownCast(aTargetAttr);
+      if (aTargetRef->Get().IsNull()) {
+        // may be refer to a cartesian coordinate entity
+        Handle(TDF_Reference) aSourceRef = Handle(TDF_Reference)::DownCast(anAttrIter.Value());
+        if (!aSourceRef.IsNull() && !aSourceRef->Get().IsNull()) {
+          std::set<TCollection_AsciiString>::const_iterator aFound =
+              theCoordinateLabels.find(labelToString(aSourceRef->Get()));
+          if (aFound != theCoordinateLabels.end())
+            makeExternalReference(theDestination, aSourceRef->Get());
+        }
+      }
+      else if (aTargetRef->Get().IsEqual(anAttrIter.Value()->Label())) {
+        // a source reference refers itself, a copy must also refer itself
+        aTargetRef->Set(aTargetRef->Label());
+      }
+    }
+  }
+  // copy the sub-labels content
+  TDF_ChildIterator aSubLabsIter(theSource);
+  for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+    copyAttrsAndKeepRefsToCoordinates(
+        aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()),
+        theCoordinateLabels, theRelocTable);
+  }
+}
+
+void Model_Tools::labelsOfCoordinates(std::set<TCollection_AsciiString>& theCoordinateLabels,
+                                      Handle(TDF_RelocationTable) theRelocTable)
+{
+  DocumentPtr aPartSet = ModelAPI_Session::get()->moduleDocument();
+  std::list<FeaturePtr> aFeatures = aPartSet->allFeatures();
+  for (std::list<FeaturePtr>::iterator aFIt = aFeatures.begin(); aFIt != aFeatures.end(); ++aFIt) {
+    FeaturePtr aCurFeat = *aFIt;
+    if (!aCurFeat->isInHistory() &&
+        (aCurFeat->getKind() == ConstructionPlugin_Point::ID() ||
+         aCurFeat->getKind() == ConstructionPlugin_Axis::ID() ||
+         aCurFeat->getKind() == ConstructionPlugin_Plane::ID())) {
+      ResultPtr aResult = aCurFeat->lastResult();
+      if (aResult) {
+        std::shared_ptr<Model_Data> aResData =
+            std::dynamic_pointer_cast<Model_Data>(aResult->data());
+        TDF_Label aLab = aResData->label().Father();
+        theCoordinateLabels.insert(labelToString(aLab));
+        // set relocation to empty, references will be set correctly while copying attributes
+        theRelocTable->SetRelocation(aLab, TDF_Label());
+      }
+    }
+  }
+}
index b1d79a50c199649d373719195203bbc22fb0c69f..b7ec96c12c73e2441027900c0c7256e941448f20 100644 (file)
 #include <TDF_Label.hxx>
 #include <TDF_RelocationTable.hxx>
 
+#include <memory>
+#include <set>
+
 /// A collection of methods useful for different parts of data model.
-namespace Model_Tools
+class Model_Tools
 {
+public:
   /// makes copy of label and all its sub-labels without copying the attributes;
   /// and feel the relocation table
-  void copyLabels(TDF_Label theSource, TDF_Label theDestination,
-                  Handle(TDF_RelocationTable) theRelocTable);
+  static void copyLabels(TDF_Label theSource, TDF_Label theDestination,
+                         Handle(TDF_RelocationTable) theRelocTable);
 
   /// makes copy of all attributes on the given label and all sub-labels
-  void copyAttrs(TDF_Label theSource, TDF_Label theDestination,
-                 Handle(TDF_RelocationTable) theRelocTable = Handle(TDF_RelocationTable)());
+  static void copyAttrs(TDF_Label theSource, TDF_Label theDestination,
+                        Handle(TDF_RelocationTable) theRelocTable = Handle(TDF_RelocationTable)());
+
+  /// makes copy of all attributes on the given label and all sub-labels,
+  /// but keep references to the Origin, coordinate axes and coordinate planes
+  static void copyAttrsAndKeepRefsToCoordinates(TDF_Label theSource, TDF_Label theDestination,
+      const std::set<TCollection_AsciiString>& theCoordinateLabels,
+      Handle(TDF_RelocationTable) theRelocTable);
+
+  /// collect labels of coordinate planes, axes, and origin
+  static void labelsOfCoordinates(
+      std::set<TCollection_AsciiString>& theCoordinateLabels,
+      Handle(TDF_RelocationTable) theRelocTable);
 };
 
 #endif
index 101910fc62aeb06dbfb2dcb5a79363409624c75f..071d2284ce67fdd9b48d8bfab0dc93d787501ea6 100644 (file)
@@ -262,8 +262,10 @@ public:
   /// Loads the OCAF document from the file into the current document.
   /// All the features are added after the active feature.
   /// \param theFileName name of the file to import
+  /// \param theCheckBefore verify the document does not contain unappropriate features
+  ///                       (useful for import to PartSet)
   /// \returns true if file was loaded successfully
-  MODELAPI_EXPORT virtual bool import(const char* theFileName) = 0;
+  MODELAPI_EXPORT virtual bool import(const char* theFileName, bool theCheckBefore = false) = 0;
 
   /// Export the list of features to the file
   /// \param theFilename path to save the file