Implement exporting/importing of the part to binary file.
ExchangePlugin_Validators.h
ExchangePlugin_Tools.h
ExchangePlugin_Dump.h
+ ExchangePlugin_ImportPart.h
+ ExchangePlugin_ExportPart.h
)
SET(PROJECT_SOURCES
ExchangePlugin_Validators.cpp
ExchangePlugin_Tools.cpp
ExchangePlugin_Dump.cpp
+ ExchangePlugin_ImportPart.cpp
+ ExchangePlugin_ExportPart.cpp
)
SET(XML_RESOURCES
--- /dev/null
+// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <ExchangePlugin_ExportPart.h>
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+// Obtain all features to be exported to get the list of selected results.
+static void collectFeatures(AttributeSelectionListPtr theSelected,
+ std::list<FeaturePtr>& theExport);
+// Obtain all constuction elements of the document.
+static void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport);
+
+
+ExchangePlugin_ExportPart::ExchangePlugin_ExportPart()
+{
+}
+
+void ExchangePlugin_ExportPart::initAttributes()
+{
+ data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(FILE_FORMAT_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(SELECTION_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SELECTION_LIST_ID());
+}
+
+void ExchangePlugin_ExportPart::execute()
+{
+ AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
+ std::string aFilename = aFilePathAttr->value();
+ if (aFilename.empty()) {
+ setError("File path is empty.");
+ return;
+ }
+
+ std::list<FeaturePtr> aFeaturesToExport;
+
+ SessionPtr aSession = ModelAPI_Session::get();
+ AttributeSelectionListPtr aSelected = selectionList(SELECTION_LIST_ID());
+ DocumentPtr anExportDoc;
+ if (aSelected && aSelected->size() == 0 &&
+ aSession->activeDocument() == aSession->moduleDocument()) {
+ // no result is selected, thus have to export all features of the current document,
+ // but the document is a PartSet; and it is forbidden to copy results of Parts,
+ // thus copy construction elements only
+ collectConstructions(aSession->moduleDocument(), aFeaturesToExport);
+ }
+ else
+ collectFeatures(aSelected, aFeaturesToExport);
+
+ if (!aFeaturesToExport.empty()) {
+ // remove 'ExportPart' feature is any
+ if (aFeaturesToExport.back()->getKind() == ExchangePlugin_ExportPart::ID())
+ aFeaturesToExport.pop_back();
+ // save the document
+ if (!aSession->activeDocument()->save(aFilename.c_str(), aFeaturesToExport))
+ setError("Cannot save the document.");
+ }
+}
+
+
+// ================================ Auxiliary functions ===================================
+
+static void allReferencedFeatures(std::set<FeaturePtr>& theFeatures)
+{
+ std::set<FeaturePtr> aReferences;
+ for (std::set<FeaturePtr>::iterator anIt = theFeatures.begin();
+ anIt != theFeatures.end(); ++anIt) {
+ std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+ (*anIt)->data()->referencesToObjects(aRefs);
+
+ for (std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRIt = aRefs.begin();
+ aRIt != aRefs.end(); ++aRIt) {
+ for (std::list<ObjectPtr>::iterator anObjIt = aRIt->second.begin();
+ anObjIt != aRIt->second.end(); ++anObjIt) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
+ if (aFeature)
+ aReferences.insert(aFeature);
+ }
+ }
+ }
+
+ if (!aReferences.empty()) {
+ allReferencedFeatures(aReferences);
+ theFeatures.insert(aReferences.begin(), aReferences.end());
+ }
+}
+
+void collectFeatures(AttributeSelectionListPtr theSelected, std::list<FeaturePtr>& theExport)
+{
+ theExport = ModelAPI_Session::get()->activeDocument()->allFeatures();
+
+ if (!theSelected || theSelected->size() == 0) {
+ // nothing is selected, return all features of the document
+ return;
+ }
+
+ // collect initial list of features basing on the selected results
+ std::set<FeaturePtr> aFeaturesToExport;
+ for (int anIndex = 0, aSize = theSelected->size(); anIndex < aSize; ++anIndex) {
+ AttributeSelectionPtr aCurrent = theSelected->value(anIndex);
+ FeaturePtr aCurrentFeature = ModelAPI_Feature::feature(aCurrent->context());
+ if (aCurrentFeature)
+ aFeaturesToExport.insert(aCurrentFeature);
+ }
+ // recursively collect all features used for the selected results
+ allReferencedFeatures(aFeaturesToExport);
+
+ // remove the features which are not affect the selected results
+ std::list<FeaturePtr>::iterator anIt = theExport.begin();
+ while (anIt != theExport.end()) {
+ if (aFeaturesToExport.find(*anIt) == aFeaturesToExport.end()) {
+ std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
+ theExport.erase(aRemoveIt);
+ }
+ else
+ ++anIt;
+ }
+}
+
+void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport)
+{
+ theExport = theDocument->allFeatures();
+ // keep constructions only
+ std::list<FeaturePtr>::iterator anIt = theExport.begin();
+ while (anIt != theExport.end()) {
+ if ((*anIt)->lastResult()->groupName() == ModelAPI_ResultConstruction::group())
+ ++anIt;
+ else {
+ std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
+ theExport.erase(aRemoveIt);
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef EXCHANGEPLUGIN_EXPORTPART_H_
+#define EXCHANGEPLUGIN_EXPORTPART_H_
+
+#include <ExchangePlugin.h>
+#include <ModelAPI_Feature.h>
+
+/**
+ * \class ExchangePlugin_ExportPart
+ * \ingroup Plugins
+ * \brief Feature for export some results of a Part to the binary format for the further import.
+ */
+class ExchangePlugin_ExportPart : public ModelAPI_Feature
+{
+public:
+ /// Feature kind
+ inline static const std::string& ID()
+ {
+ static const std::string MY_EXPORT_ID("ExportPart");
+ return MY_EXPORT_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;
+ }
+ /// attribute name of selection list
+ inline static const std::string& SELECTION_LIST_ID()
+ {
+ static const std::string MY_SELECTION_LIST_ID("selection_list");
+ return MY_SELECTION_LIST_ID;
+ }
+ /// Default constructor
+ ExchangePlugin_ExportPart();
+
+ /// Returns the unique kind of a feature
+ EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ return ExchangePlugin_ExportPart::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();
+
+ /// Returns true if this feature is used as macro: creates other features and then removed.
+ EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+ /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
+ EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+
+ /// Do not put in history.
+ /// Since it is not a macro, it is not deleted, but we don't want to see it.
+ bool isInHistory() { return false; }
+};
+
+#endif /* EXCHANGEPLUGIN_EXPORTPART_H_ */
--- /dev/null
+// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <ExchangePlugin_ImportPart.h>
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Session.h>
+
+ExchangePlugin_ImportPart::ExchangePlugin_ImportPart()
+{
+}
+
+void ExchangePlugin_ImportPart::initAttributes()
+{
+ data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+}
+
+void ExchangePlugin_ImportPart::execute()
+{
+ AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
+ std::string aFilename = aFilePathAttr->value();
+ if (aFilename.empty()) {
+ setError("File path is empty.");
+ return;
+ }
+
+ // load the file into the active document
+ SessionPtr aSession = ModelAPI_Session::get();
+ if (!aSession->activeDocument()->import(aFilename.c_str()))
+ setError("Cannot import the document.");
+}
--- /dev/null
+// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef EXCHANGEPLUGIN_IMPORTPART_H_
+#define EXCHANGEPLUGIN_IMPORTPART_H_
+
+#include <ExchangePlugin.h>
+#include <ModelAPI_Feature.h>
+
+/**
+ * \class ExchangePlugin_ImportPart
+ * \ingroup Plugins
+ * \brief Feature for import the structure of Part into the current document.
+ */
+class ExchangePlugin_ImportPart : public ModelAPI_Feature
+{
+public:
+ /// Feature kind
+ inline static const std::string& ID()
+ {
+ static const std::string MY_IMPORT_ID("ImportPart");
+ return MY_IMPORT_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;
+ }
+ /// Default constructor
+ ExchangePlugin_ImportPart();
+
+ /// Returns the unique kind of a feature
+ EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ return ExchangePlugin_ImportPart::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();
+
+ /// Returns true if this feature is used as macro: creates other features and then removed.
+ EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+ /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
+ EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+};
+
+#endif /* EXCHANGEPLUGIN_IMPORTPART_H_ */
#include <ExchangePlugin_Dump.h>
#include <ExchangePlugin_ImportFeature.h>
#include <ExchangePlugin_ExportFeature.h>
+#include <ExchangePlugin_ImportPart.h>
+#include <ExchangePlugin_ExportPart.h>
#include <ExchangePlugin_Validators.h>
#include <Config_PropManager.h>
if (theFeatureID == ExchangePlugin_ExportFeature::ID()) {
return FeaturePtr(new ExchangePlugin_ExportFeature);
} else
+ if (theFeatureID == ExchangePlugin_ImportPart::ID()) {
+ return FeaturePtr(new ExchangePlugin_ImportPart);
+ } else
+ if (theFeatureID == ExchangePlugin_ExportPart::ID()) {
+ return FeaturePtr(new ExchangePlugin_ExportPart);
+ } else
if (theFeatureID == ExchangePlugin_Dump::ID()) {
return FeaturePtr(new ExchangePlugin_Dump);
}
tooltip="To use geometrical order for identification of selected shapes"
default="false"/> -->
</feature>
+
+ <feature id="ImportPart" title="Import part" tooltip="Import features from file" icon="icons/Exchange/import_part.png"
+ helpfile="importPart.html"
+ internal="1">
+ <file_selector id="file_path" title="Import file" path="">
+ <validator id="ExchangePlugin_ImportFormat" parameters="shaperpart:Part" />
+ </file_selector>
+ </feature>
+ <feature id="ExportPart" title="Export part" tooltip="Export structure of the Part to file" icon="icons/Exchange/export_part.png"
+ helpfile="exportPart.html"
+ internal="1">
+ <export_file_selector id="file_path"
+ type="save"
+ title="Export file"
+ path="">
+ <validator id="ExchangePlugin_ExportFormat"
+ parameters="shaperpart:Part" />
+ </export_file_selector>
+ <multi_selector id="selection_list"
+ tooltip="Select features or results"
+ shape_types="Vertices Edges Faces Solids Compsolids Objects">
+ </multi_selector>
+ </feature>
</group>
</workbench>
</plugin>
\ No newline at end of file
Model_ResultField.h
Model_ResultGroup.h
Model_ResultParameter.h
+ Model_Tools.h
Model_Update.h
Model_Validator.h
)
Model_ResultField.cpp
Model_ResultGroup.cpp
Model_ResultParameter.cpp
+ Model_Tools.cpp
Model_Update.cpp
Model_Validator.cpp
)
#include <ModelAPI_Events.h>
+#include <PCDM_RetrievalDriver.hxx>
+
IMPLEMENT_STANDARD_RTTIEXT(Model_Application, TDocStd_Application)
static Handle_Model_Application TheApplication = new Model_Application;
// store handle to the application to avoid nullification
static Handle(Model_Application) TheKeepHandle;
TheKeepHandle = this;
+ // additional file format supported
+ static TCollection_ExtendedString THE_DOC_FORMAT("BinOcaf"/*"BinShaperPart"*/);
+ static TCollection_ExtendedString THE_FILE_EXT("shaperpart");
+ Handle(PCDM_RetrievalDriver) aReader =
+ Handle(PCDM_RetrievalDriver)::DownCast(TheKeepHandle->ReaderFromFormat("BinOcaf"));
+ Handle(PCDM_StorageDriver) aWriter = TheKeepHandle->WriterFromFormat("BinOcaf");
+ TheKeepHandle->DefineFormat(THE_DOC_FORMAT, "Shaper Part document", THE_FILE_EXT,
+ aReader, aWriter);
}
//=======================================================================
#include <Model_AttributeTables.h>
#include <Model_Events.h>
#include <Model_Expression.h>
+#include <Model_Tools.h>
+#include <Model_Validator.h>
+
#include <ModelAPI_Feature.h>
#include <ModelAPI_Result.h>
#include <ModelAPI_ResultParameter.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_Tools.h>
-#include <Model_Validator.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Point2D.h>
#include <TDataStd_Name.hxx>
#include <TDataStd_AsciiString.hxx>
-#include <TDataStd_IntegerArray.hxx>
#include <TDataStd_UAttribute.hxx>
-#include <TDF_AttributeIterator.hxx>
-#include <TDF_ChildIterator.hxx>
-#include <TDF_RelocationTable.hxx>
#include <TDF_ChildIDIterator.hxx>
-#include <TColStd_HArray1OfByte.hxx>
#include <string>
}
}
-/// makes copy of all attributes on the given label and all sub-labels
-static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
- 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);
- }
- // no special relocation, empty map, but self-relocation is on: copy references w/o changes
- Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
- anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
- // an exception: if a source reference refers itself, a copy must also refer itself
- if (aTargetAttr->ID() == TDF_Reference::GetID()) {
- Handle(TDF_Reference) aTargetRef = Handle(TDF_Reference)::DownCast(aTargetAttr);
- if (aTargetRef->Get().IsEqual(anAttrIter.Value()->Label()))
- aTargetRef->Set(aTargetRef->Label());
- }
- }
- // copy the sub-labels content
- TDF_ChildIterator aSubLabsIter(theSource);
- for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
- copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
- }
-}
-
void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
{
TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
- copyAttrs(myLab, aTargetRoot);
+ Model_Tools::copyAttrs(myLab, aTargetRoot);
// reinitialize Model_Attributes by TDF_Attributes set
std::shared_ptr<Model_Data> aTData = std::dynamic_pointer_cast<Model_Data>(theTarget);
aTData->myAttrs.clear();
#include <Model_Application.h>
#include <Model_Session.h>
#include <Model_Events.h>
+#include <Model_Tools.h>
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_Validator.h>
#include <ModelAPI_CompositeFeature.h>
#include <TNaming_Iterator.hxx>
#include <TNaming_NamedShape.hxx>
#include <TNaming_Tool.hxx>
-#include<TNaming_OldShapeIterator.hxx>
+#include <TNaming_OldShapeIterator.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_ListOfShape.hxx>
}
// LCOV_EXCL_STOP
-bool Model_Document::load(const char* theDirName, const char* theFileName, DocumentPtr theThis)
+static bool loadDocument(Handle(Model_Application) theApp,
+ Handle(TDocStd_Document)& theDoc,
+ const TCollection_ExtendedString& theFilename)
{
- Handle(Model_Application) anApp = Model_Application::getApplication();
- if (isRoot()) {
- anApp->setLoadPath(theDirName);
- }
- TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
- PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
- Handle(TDocStd_Document) aLoaded;
+ PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus)-1;
try {
- aStatus = anApp->Open(aPath, aLoaded);
+ aStatus = theApp->Open(theFilename, theDoc);
} catch (Standard_Failure const& anException) {
Events_InfoMessage("Model_Document",
"Exception in opening of document: %1").arg(anException.GetMessageString()).send();
return false;
}
- bool isError = aStatus != PCDM_RS_OK;
- if (isError) {
+ bool isOk = aStatus == PCDM_RS_OK;
+ if (!isOk) {
// LCOV_EXCL_START
switch (aStatus) {
case PCDM_RS_UnknownDocument:
}
// LCOV_EXCL_STOP
}
+ return isOk;
+}
+
+bool Model_Document::load(const char* theDirName, const char* theFileName, DocumentPtr theThis)
+{
+ Handle(Model_Application) anApp = Model_Application::getApplication();
+ if (isRoot()) {
+ anApp->setLoadPath(theDirName);
+ }
+ TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
+ Handle(TDocStd_Document) aLoaded;
+ bool isOk = loadDocument(anApp, aLoaded, aPath);
+
std::shared_ptr<Model_Session> aSession =
std::dynamic_pointer_cast<Model_Session>(Model_Session::get());
- if (!isError) {
+ if (isOk) {
myDoc = aLoaded;
myDoc->SetUndoLimit(UNDO_LIMIT);
} else { // open failed, but new document was created to work with it: inform the model
aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
}
- return !isError;
+ return isOk;
+}
+
+bool Model_Document::import(const char* theFileName)
+{
+ Handle(Model_Application) anApp = Model_Application::getApplication();
+ TCollection_ExtendedString aFormat;
+ if (!anApp->Format(theFileName, aFormat))
+ return false;
+
+ 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();
+ }
+ }
+
+ myObjs->synchronizeFeatures(anAllNewFeatures, true, false, false, true);
+
+ if (aTempDoc->CanClose() == CDM_CCS_OK)
+ aTempDoc->Close();
+ return isOk;
+}
+
+static bool saveDocument(Handle(Model_Application) theApp,
+ Handle(TDocStd_Document) theDoc,
+ const TCollection_ExtendedString& theFilename)
+{
+ PCDM_StoreStatus aStatus;
+ try {
+ aStatus = theApp->SaveAs(theDoc, theFilename);
+ }
+ catch (Standard_Failure const& anException) {
+ Events_InfoMessage("Model_Document",
+ "Exception in saving of document: %1").arg(anException.GetMessageString()).send();
+ return false;
+ }
+ bool isDone = aStatus == PCDM_SS_OK || aStatus == PCDM_SS_No_Obj;
+ if (!isDone) {
+ switch (aStatus) {
+ case PCDM_SS_DriverFailure:
+ Events_InfoMessage("Model_Document",
+ "Can not save document: save driver-library failure").send();
+ break;
+ case PCDM_SS_WriteFailure:
+ Events_InfoMessage("Model_Document", "Can not save document: file writing failure").send();
+ break;
+ case PCDM_SS_Failure:
+ default:
+ Events_InfoMessage("Model_Document", "Can not save document").send();
+ break;
+ }
+ }
+ return isDone;
}
bool Model_Document::save(
}
// filename in the dir is id of document inside of the given directory
TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
- PCDM_StoreStatus aStatus;
- try {
- aStatus = anApp->SaveAs(myDoc, aPath);
- } catch (Standard_Failure const& anException) {
- Events_InfoMessage("Model_Document",
- "Exception in saving of document: %1").arg(anException.GetMessageString()).send();
- if (aWasCurrent.get()) { // return the current feature to the initial position
- setCurrentFeature(aWasCurrent, false);
- aSession->setCheckTransactions(true);
- }
- return false;
- }
- bool isDone = aStatus == PCDM_SS_OK || aStatus == PCDM_SS_No_Obj;
- if (!isDone) {
- switch (aStatus) {
- case PCDM_SS_DriverFailure:
- Events_InfoMessage("Model_Document",
- "Can not save document: save driver-library failure").send();
- break;
- case PCDM_SS_WriteFailure:
- Events_InfoMessage("Model_Document", "Can not save document: file writing failure").send();
- break;
- case PCDM_SS_Failure:
- default:
- Events_InfoMessage("Model_Document", "Can not save document").send();
- break;
- }
- }
+ bool isDone = saveDocument(anApp, myDoc, aPath);
if (aWasCurrent.get()) { // return the current feature to the initial position
setCurrentFeature(aWasCurrent, false);
return isDone;
}
+bool Model_Document::save(const char* theFilename,
+ const std::list<FeaturePtr>& theExportFeatures) const
+{
+ Handle(Model_Application) anApp = Model_Application::getApplication();
+ TCollection_ExtendedString aFormat;
+ if (!anApp->Format(theFilename, aFormat))
+ return false;
+
+ Handle(TDocStd_Document) aTempDoc = new TDocStd_Document(aFormat);
+ TDF_Label aMain = aTempDoc->Main();
+
+ Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
+ std::list<FeaturePtr>::const_iterator anIt = theExportFeatures.begin();
+ // Perform the copying twice for correct references:
+ // 1. copy labels hierarchy and fill the relocation table
+ for (; anIt != theExportFeatures.end(); ++anIt) {
+ TDF_Label aFeatureLab = aMain.NewChild();
+ std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>((*anIt)->data());
+ Model_Tools::copyLabels(aData->label().Father(), aFeatureLab, aRelocTable);
+ }
+ // 2. copy attributes
+ 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);
+ aChildIt.Next();
+ }
+
+ bool isDone = saveDocument(anApp, aTempDoc, theFilename);
+ if (aTempDoc->CanClose() == CDM_CCS_OK)
+ aTempDoc->Close();
+ return isDone;
+}
+
void Model_Document::close(const bool theForever)
{
std::shared_ptr<ModelAPI_Session> aPM = Model_Session::get();
MODEL_EXPORT virtual bool load(
const char* theDirName, const char* theFileName, DocumentPtr theThis);
+ //! 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
+ //! \returns true if file was loaded successfully
+ MODEL_EXPORT virtual bool import(const char* theFileName);
+
//! Saves the OCAF document to the file.
//! \param theDirName directory where the document will be saved
//! \param theFileName a name of the document file to store
MODEL_EXPORT virtual bool save(
const char* theDirName, const char* theFileName, std::list<std::string>& theResults);
+ //! Export the list of features to the file
+ //! \param theFilename path to save the file
+ //! \param theExportFeatures list of features to export
+ MODEL_EXPORT virtual bool save(const char* theFilename,
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theExportFeatures) const;
+
//! Removes document data
//! \param theForever if it is false, document is just hidden
//! (to keep possibility make it back on Undo/Redo)
--- /dev/null
+// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <Model_Tools.h>
+
+#include <Standard_GUID.hxx>
+
+#include <TDF_AttributeIterator.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_Reference.hxx>
+#include <TDF_RelocationTable.hxx>
+
+void Model_Tools::copyLabels(TDF_Label theSource, TDF_Label theDestination,
+ Handle(TDF_RelocationTable) theRelocTable)
+{
+ theRelocTable->SetRelocation(theSource, theDestination);
+ // copy the sub-labels hierarchy
+ TDF_ChildIterator aSubLabsIter(theSource);
+ for (; aSubLabsIter.More(); aSubLabsIter.Next()) {
+ copyLabels(aSubLabsIter.Value(),
+ theDestination.FindChild(aSubLabsIter.Value().Tag()),
+ theRelocTable);
+ }
+}
+
+void Model_Tools::copyAttrs(TDF_Label theSource, TDF_Label theDestination,
+ 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);
+ }
+ // no special relocation, empty map, but self-relocation is on: copy references w/o changes
+ Handle(TDF_RelocationTable) aRelocTable =
+ theRelocTable.IsNull() ? new TDF_RelocationTable(Standard_True) : theRelocTable;
+ anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
+ // an exception: if a source reference refers itself, a copy must also refer itself
+ if (aTargetAttr->ID() == TDF_Reference::GetID()) {
+ Handle(TDF_Reference) aTargetRef = Handle(TDF_Reference)::DownCast(aTargetAttr);
+ if (aTargetRef->Get().IsEqual(anAttrIter.Value()->Label()))
+ aTargetRef->Set(aTargetRef->Label());
+ }
+ }
+ // copy the sub-labels content
+ TDF_ChildIterator aSubLabsIter(theSource);
+ for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+ copyAttrs(aSubLabsIter.Value(),
+ theDestination.FindChild(aSubLabsIter.Value().Tag()),
+ theRelocTable);
+ }
+}
--- /dev/null
+// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef Model_Tools_H_
+#define Model_Tools_H_
+
+#include <Model.h>
+
+#include <TDF_Label.hxx>
+#include <TDF_RelocationTable.hxx>
+
+/// A collection of methods useful for different parts of data model.
+namespace Model_Tools
+{
+ /// 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);
+
+ /// 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)());
+};
+
+#endif
MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Feature> nextFeature(
std::shared_ptr<ModelAPI_Feature> theCurrent, const bool theReverse = false) const = 0;
+ /// 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
+ /// \returns true if file was loaded successfully
+ MODELAPI_EXPORT virtual bool import(const char* theFileName) = 0;
+
+ /// Export the list of features to the file
+ /// \param theFilename path to save the file
+ /// \param theExportFeatures list of features to export
+ MODELAPI_EXPORT virtual bool save(const char* theFilename,
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theExportFeatures) const = 0;
+
protected:
//! Only for SWIG wrapping it is here
MODELAPI_EXPORT ModelAPI_Document();
SET(PROJECT_INCLUDES
${PROJECT_SOURCE_DIR}/src/Events
${PROJECT_SOURCE_DIR}/src/Config
+ ${PROJECT_SOURCE_DIR}/src/ExchangePlugin
${PROJECT_SOURCE_DIR}/src/ModelAPI
${PROJECT_SOURCE_DIR}/src/GeomAPI
${PROJECT_SOURCE_DIR}/src/ModuleBase
#include <ModelAPI_AttributeDocRef.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_Feature.h>
#include <Events_InfoMessage.h>
#include <Events_LongOp.h>
+#include <ExchangePlugin_ExportPart.h>
+#include <ExchangePlugin_ImportPart.h>
+
#include <GeomAPI_Pnt.h>
#include <ModuleBase_IModule.h>
static QString MyExtension(".cadbld");
#endif
+static QString MyImportPartFilter(QObject::tr("Part files (*.shaperpart);;All files (*.*)"));
+
//******************************************************
XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen()));
salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
+ aAction = salomeConnector()->addDesktopCommand("EXPORT_PART_CMD", tr("Export part..."),
+ tr("Export a part of the current document into a file"),
+ QIcon(), QKeySequence(),
+ false, "MEN_DESK_FILE");
+ connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onExportPart()));
+
+ aAction = salomeConnector()->addDesktopCommand("IMPORT_PART_CMD", tr("Import part..."),
+ tr("Import structure of a part"),
+ QIcon(), QKeySequence(),
+ false, "MEN_DESK_FILE");
+ connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportPart()));
+ salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
+
#else
// File commands group
AppElements_MenuGroupPanel* aGroup = myMainWindow->menuObject()->generalPage();
myDisplayer->updateViewer();
}
+//******************************************************
+void XGUI_Workshop::onImportPart()
+{
+ if (!abortAllOperations())
+ return;
+
+ //show file dialog, check if readable and open
+ qreal aRatio = ModuleBase_Tools::currentPixelRatio();
+ // If the ratio is > 1 (HD screen) then QT has a bug in
+ // displaying of system open file dialog (too small)
+ QString aFile = QFileDialog::getOpenFileName(desktop(), tr("Import part"), QString(),
+ MyImportPartFilter, Q_NULLPTR,
+ ((aRatio > 1) ? QFileDialog::DontUseNativeDialog : QFileDialog::Options()));
+ if (!aFile.isNull()) {
+ ModuleBase_OperationFeature* anImportPartOp = dynamic_cast<ModuleBase_OperationFeature*>(
+ module()->createOperation(ExchangePlugin_ImportPart::ID()));
+ if (operationMgr()->startOperation(anImportPartOp)) {
+ // initialize the filename to be imported
+ FeaturePtr aFeature = anImportPartOp->feature();
+ aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(aFile.toStdString());
+ ModuleBase_Tools::flushUpdated(aFeature);
+ operationMgr()->commitOperation();
+ }
+ }
+}
+
+//******************************************************
+void XGUI_Workshop::onExportPart()
+{
+ if (abortAllOperations()) {
+ ModuleBase_OperationFeature* anExportPartOp = dynamic_cast<ModuleBase_OperationFeature*>(
+ module()->createOperation(ExchangePlugin_ExportPart::ID()));
+ operationMgr()->startOperation(anExportPartOp);
+ }
+}
+
//******************************************************
ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule)
{
/// Create a new document
void onNew();
+ /// Import part structure from a file
+ void onImportPart();
+
+ /// Export features to a file
+ void onExportPart();
+
#ifndef HAVE_SALOME
/// Exit application
void onExit();