From 527985a2c4e7eac7e4187a35004763bc130abd3e Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 12 Nov 2019 15:24:33 +0300 Subject: [PATCH] Task 5.1.7: To be able to export a part to a file and import it into an existing part (issue #3065) Exporting/importing references to external objects. --- src/ExchangeAPI/ExchangeAPI_Export.cpp | 2 +- src/ExchangeAPI/ExchangeAPI_Import.cpp | 2 +- src/ExchangePlugin/CMakeLists.txt | 2 + .../ExchangePlugin_ExportPart.cpp | 18 ++- .../ExchangePlugin_ImportPart.cpp | 19 ++- src/Model/CMakeLists.txt | 1 + src/Model/Model_AttributeReference.cpp | 1 + src/Model/Model_AttributeSelection.cpp | 51 ++++---- src/Model/Model_Data.h | 1 + src/Model/Model_Document.cpp | 99 ++++++++++------ src/Model/Model_Document.h | 4 +- src/Model/Model_Tools.cpp | 110 ++++++++++++++++++ src/Model/Model_Tools.h | 25 +++- src/ModelAPI/ModelAPI_Document.h | 4 +- 14 files changed, 265 insertions(+), 74 deletions(-) diff --git a/src/ExchangeAPI/ExchangeAPI_Export.cpp b/src/ExchangeAPI/ExchangeAPI_Export.cpp index e9863969c..2d764635a 100644 --- a/src/ExchangeAPI/ExchangeAPI_Export.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Export.cpp @@ -200,7 +200,7 @@ void exportPart(const std::shared_ptr & 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(); } //-------------------------------------------------------------------------------------- diff --git a/src/ExchangeAPI/ExchangeAPI_Import.cpp b/src/ExchangeAPI/ExchangeAPI_Import.cpp index 81b34ac03..e585f971e 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Import.cpp @@ -111,7 +111,7 @@ void importPart(const std::shared_ptr & 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 diff --git a/src/ExchangePlugin/CMakeLists.txt b/src/ExchangePlugin/CMakeLists.txt index 4094385a5..875a0a917 100644 --- a/src/ExchangePlugin/CMakeLists.txt +++ b/src/ExchangePlugin/CMakeLists.txt @@ -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 diff --git a/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp index 79de399f8..626f835e8 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp @@ -25,6 +25,10 @@ #include #include +#include +#include +#include + // Obtain all features to be exported to get the list of selected results. static void collectFeatures(AttributeSelectionListPtr theSelected, std::list& theExport); @@ -145,7 +149,19 @@ void collectConstructions(DocumentPtr theDocument, std::list& theExp // keep constructions only std::list::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::iterator aRemoveIt = anIt++; diff --git a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp index ed0c456b7..11eae6c0d 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp @@ -20,8 +20,11 @@ #include #include +#include #include +#include + 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(aPartFeature->lastResult()); + } + isOk = aPartResult && aPartResult->partDoc()->import(aFilename.c_str()); + } + if (!isOk) setError("Cannot import the document."); } diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 348761424..eaac6b906 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -117,6 +117,7 @@ SET(PROJECT_INCLUDES ../GeomAlgoAPI ../GeomAPI ../ModelGeomAlgo + ../ConstructionPlugin ${OpenCASCADE_INCLUDE_DIR} ) diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index 2a2f5fa67..0b2d2869a 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -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 aDoc = diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index d636a3804..c37149ede 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -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 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 aMyDoc = - std::dynamic_pointer_cast(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 aMyDoc = + std::dynamic_pointer_cast(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()) { diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 9f26d8de1..7f9fa9b01 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -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. diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index c69e0c5cb..c2323e13b 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -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 aData = - std::dynamic_pointer_cast(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 aSession = + std::dynamic_pointer_cast(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 aData = + std::dynamic_pointer_cast(aNewFeature->data()); + aNewFeatuerLab = aData->label().Father(); + Model_Tools::copyLabels(aCurrentLab, aNewFeatuerLab, aRelocTable); + } + anAllNewFeatures.Append(aNewFeatuerLab); + } + // 2. copy attributes + std::set 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::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 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 aData = std::dynamic_pointer_cast((*anIt)->data()); - Model_Tools::copyAttrs(aData->label().Father(), aFeatureLab, aRelocTable); + Model_Tools::copyAttrsAndKeepRefsToCoordinates( + aData->label().Father(), aFeatureLab, aCoordinateLabels, aRelocTable); aChildIt.Next(); } diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 2cf44cbd0..f7246758f 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -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 diff --git a/src/Model/Model_Tools.cpp b/src/Model/Model_Tools.cpp index 33bafd04d..48831807a 100644 --- a/src/Model/Model_Tools.cpp +++ b/src/Model/Model_Tools.cpp @@ -18,13 +18,27 @@ // #include +#include + +#include +#include +#include +#include + +#include +#include +#include #include +#include +#include + #include #include #include #include +#include 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& 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::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& theCoordinateLabels, + Handle(TDF_RelocationTable) theRelocTable) +{ + DocumentPtr aPartSet = ModelAPI_Session::get()->moduleDocument(); + std::list aFeatures = aPartSet->allFeatures(); + for (std::list::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 aResData = + std::dynamic_pointer_cast(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()); + } + } + } +} diff --git a/src/Model/Model_Tools.h b/src/Model/Model_Tools.h index b1d79a50c..b7ec96c12 100644 --- a/src/Model/Model_Tools.h +++ b/src/Model/Model_Tools.h @@ -25,17 +25,32 @@ #include #include +#include +#include + /// 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& theCoordinateLabels, + Handle(TDF_RelocationTable) theRelocTable); + + /// collect labels of coordinate planes, axes, and origin + static void labelsOfCoordinates( + std::set& theCoordinateLabels, + Handle(TDF_RelocationTable) theRelocTable); }; #endif diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 101910fc6..071d2284c 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -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 -- 2.30.2