From: mpv Date: Wed, 21 May 2014 08:44:36 +0000 (+0400) Subject: The duplicate and remove parts implementation. X-Git-Tag: V_0.2~26^2~4^2~1^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e69bac7a6862b4b4df111ad09e69e4ad330659d6;p=modules%2Fshaper.git The duplicate and remove parts implementation. --- diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 820846178..423de6a37 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -164,7 +164,8 @@ void Model_Document::close() subDocument(*aSubIter)->close(); mySubs.clear(); // close this - myDoc->Close(); + if (myDoc->CanClose() == CDM_CCS_OK) + myDoc->Close(); Model_Application::getApplication()->deleteDocument(myID); } @@ -296,6 +297,8 @@ static void AddToRefArray(TDF_Label& theArrayLab, TDF_Label& theReferenced) { void Model_Document::addFeature(const boost::shared_ptr theFeature) { + if (theFeature->isAction()) return; // do not add action to the data model + boost::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); TDF_Label aFeaturesLab = groupLabel(FEATURES_GROUP); @@ -333,6 +336,63 @@ void Model_Document::addFeature(const boost::shared_ptr theFea Events_Loop::loop()->send(aMsg); } +/// Appenad to the array of references a new referenced label. +/// If theIndex is not -1, removes element at thisindex, not theReferenced. +/// \returns the index of removed element +static int RemoveFromRefArray( + TDF_Label theArrayLab, TDF_Label theReferenced, const int theIndex = -1) { + int aResult = -1; // no returned + Handle(TDataStd_ReferenceArray) aRefs; + if (theArrayLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { + if (aRefs->Length() == 1) { // just erase an array + if ((theIndex == -1 && aRefs->Value(0) == theReferenced) || theIndex == 0) + theArrayLab.ForgetAttribute(TDataStd_ReferenceArray::GetID()); + aResult = 0; + } else { // reduce the array + Handle(TDataStd_HLabelArray1) aNewArray = + new TDataStd_HLabelArray1(aRefs->Lower(), aRefs->Upper() - 1); + int aCount = aRefs->Lower(); + for(int a = aCount; a <= aRefs->Upper(); a++, aCount++) { + if ((theIndex == -1 && aRefs->Value(a) == theReferenced) || theIndex == a) { + aCount--; + aResult = a; + } else { + aNewArray->SetValue(aCount, aRefs->Value(a)); + } + } + aRefs->SetInternalArray(aNewArray); + } + } + return aResult; +} + +void Model_Document::removeFeature(boost::shared_ptr theFeature) +{ + boost::shared_ptr aData = boost::static_pointer_cast(theFeature->data()); + TDF_Label aFeatureLabel = aData->label(); + // remove the object + TDF_Label aGroupLabel = groupLabel(theFeature->getGroup()); + int aRemovedIndex = RemoveFromRefArray(aGroupLabel, aFeatureLabel); + RemoveFromRefArray(aGroupLabel.FindChild(1), TDF_Label(), aRemovedIndex); + // remove feature from the myFeatures list + std::vector >::iterator aFIter = myFeatures.begin(); + while(aFIter != myFeatures.end()) { + if (*aFIter == theFeature) { + aFIter = myFeatures.erase(aFIter); + } else { + aFIter++; + } + } + // erase all attributes under the label of feature + aFeatureLabel.ForgetAllAttributes(); + // remove it from the references array + RemoveFromRefArray(groupLabel(FEATURES_GROUP), aData->label()); + + // event: feature is added + Model_FeatureDeletedMessage aMsg(theFeature->document(), theFeature->getGroup()); + Events_Loop::loop()->send(aMsg); +} + boost::shared_ptr Model_Document::feature(TDF_Label& theLabel) { // iterate all features, may be optimized later by keeping labels-map @@ -443,6 +503,7 @@ void Model_Document::setUniqueName(boost::shared_ptr theFeatur aNumObjects++; stringstream aNameStream; aNameStream<getKind()<<"_"< addFeature(std::string theID); + //! Removes the feature from the document + MODEL_EXPORT virtual void removeFeature(boost::shared_ptr theFeature); + //! Returns the existing feature by the label //! \param theLabel base label of the feature MODEL_EXPORT virtual boost::shared_ptr feature(TDF_Label& theLabel); @@ -105,7 +108,10 @@ protected: //! Creates new document with binary file format Model_Document(const std::string theID); + Handle_TDocStd_Document document() {return myDoc;} + friend class Model_Application; + friend class Model_PluginManager; private: std::string myID; ///< identifier of the document in the application diff --git a/src/Model/Model_PluginManager.cpp b/src/Model/Model_PluginManager.cpp index cbb917a76..d6fca2bf7 100644 --- a/src/Model/Model_PluginManager.cpp +++ b/src/Model/Model_PluginManager.cpp @@ -9,9 +9,16 @@ #include #include #include +#include #include #include +#include +#include +#include +#include + + using namespace std; static Model_PluginManager* myImpl = new Model_PluginManager(); @@ -30,7 +37,13 @@ boost::shared_ptr Model_PluginManager::createFeature(string th if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) { boost::shared_ptr aCreated = myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID); + if (!aCreated) { + Events_Error::send(string("Can not initialize feature '") + theFeatureID + + "' in plugin '" + myCurrentPluginName + "'"); + } return aCreated; + } else { + Events_Error::send(string("Can not load plugin '") + myCurrentPluginName + "'"); } } @@ -60,6 +73,27 @@ void Model_PluginManager::setCurrentDocument(boost::shared_ptr Model_PluginManager::copy( + boost::shared_ptr theSource, std::string theID) +{ + // create a new document + boost::shared_ptr aNew = boost::dynamic_pointer_cast( + Model_Application::getApplication()->getDocument(theID)); + // make a copy of all labels + TDF_Label aSourceRoot = + boost::dynamic_pointer_cast(theSource)->document()->Main().Father(); + TDF_Label aTargetRoot = aNew->document()->Main().Father(); + Handle(TDF_DataSet) aDS = new TDF_DataSet; + aDS->AddLabel(aSourceRoot); + TDF_ClosureTool::Closure(aDS); + Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable; + aRT->SetRelocation(aSourceRoot, aTargetRoot); + TDF_CopyTool::Copy(aDS, aRT); + + aNew->synchronizeFeatures(); + return aNew; +} + Model_PluginManager::Model_PluginManager() { myPluginsInfoLoaded = false; diff --git a/src/Model/Model_PluginManager.h b/src/Model/Model_PluginManager.h index 7f405573f..aa230700a 100644 --- a/src/Model/Model_PluginManager.h +++ b/src/Model/Model_PluginManager.h @@ -47,6 +47,10 @@ public: /// Processes the configuration file reading MODEL_EXPORT virtual void processEvent(const Events_Message* theMessage); + /// Copies the document to the new one wit hthe given id + MODEL_EXPORT virtual boost::shared_ptr copy( + boost::shared_ptr theSource, std::string theID); + /// Is called only once, on startup of the application Model_PluginManager(); diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index bed11f886..9070718b4 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -69,8 +69,12 @@ public: //! \param creates feature and puts it in the document MODELAPI_EXPORT virtual boost::shared_ptr addFeature(std::string theID) = 0; + //! Removes the feature from the document + MODELAPI_EXPORT virtual void removeFeature(boost::shared_ptr theFeature) = 0; + ///! Adds a new sub-document by the identifier, or returns existing one if it is already exist - MODELAPI_EXPORT virtual boost::shared_ptr subDocument(std::string theDocID) = 0; + MODELAPI_EXPORT virtual boost::shared_ptr + subDocument(std::string theDocID) = 0; ///! Returns the id of hte document MODELAPI_EXPORT virtual const std::string& id() const = 0; diff --git a/src/ModelAPI/ModelAPI_Feature.h b/src/ModelAPI/ModelAPI_Feature.h index eb4ba54f9..dd98c597a 100644 --- a/src/ModelAPI/ModelAPI_Feature.h +++ b/src/ModelAPI/ModelAPI_Feature.h @@ -40,6 +40,10 @@ public: /// Returns true if this feature must be displayed in the history (top level of Part tree) MODELAPI_EXPORT virtual bool isInHistory() {return true;} + /// Returns true if this feature must not be created: this is just an action + /// that is not stored in the features history (like delete part). + MODELAPI_EXPORT virtual bool isAction() {return false;} + /// Returns the data manager of this feature MODELAPI_EXPORT virtual boost::shared_ptr data() {return myData;} diff --git a/src/ModelAPI/ModelAPI_PluginManager.h b/src/ModelAPI/ModelAPI_PluginManager.h index 47c42562f..6b25bf4a3 100644 --- a/src/ModelAPI/ModelAPI_PluginManager.h +++ b/src/ModelAPI/ModelAPI_PluginManager.h @@ -43,6 +43,10 @@ public: /// Defines the current document that used for current work in the application virtual void setCurrentDocument(boost::shared_ptr theDoc) = 0; + /// Copies the document to the new one wit hthe given id + virtual boost::shared_ptr copy( + boost::shared_ptr theSource, std::string theID) = 0; + /// Is needed for python wrapping by swig, call Get to get an instance ModelAPI_PluginManager(); diff --git a/src/PartSetPlugin/CMakeLists.txt b/src/PartSetPlugin/CMakeLists.txt index d9715d590..119d74843 100644 --- a/src/PartSetPlugin/CMakeLists.txt +++ b/src/PartSetPlugin/CMakeLists.txt @@ -4,11 +4,15 @@ SET(PROJECT_HEADERS PartSetPlugin.h PartSetPlugin_Plugin.h PartSetPlugin_Part.h + PartSetPlugin_Duplicate.h + PartSetPlugin_Remove.h ) SET(PROJECT_SOURCES PartSetPlugin_Plugin.cpp PartSetPlugin_Part.cpp + PartSetPlugin_Duplicate.cpp + PartSetPlugin_Remove.cpp ) ADD_DEFINITIONS(-DPARTSETPLUGIN_EXPORTS ${BOOST_DEFINITIONS}) diff --git a/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp b/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp new file mode 100644 index 000000000..9b6a47e16 --- /dev/null +++ b/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp @@ -0,0 +1,40 @@ +// File: PartSetPlugin_Duplicate.cxx +// Created: 20 May 2014 +// Author: Mikhail PONIKAROV + +#include "PartSetPlugin_Duplicate.h" +#include +#include +#include +#include + +using namespace std; + +PartSetPlugin_Duplicate::PartSetPlugin_Duplicate() +{ +} + +void PartSetPlugin_Duplicate::initAttributes() +{ + PartSetPlugin_Part::initAttributes(); + data()->addAttribute(PART_DUPLICATE_ATTR_REF, ModelAPI_AttributeRefAttr::type()); + + boost::shared_ptr aRef = data()->refattr(PART_DUPLICATE_ATTR_REF); + if (!aRef->attr()) { // create a copy: if not created yet attribute is not initialized + boost::shared_ptr aPManager = ModelAPI_PluginManager::get(); + boost::shared_ptr aRoot = aPManager->rootDocument(); + boost::shared_ptr aSource; // searching for source document attribute + for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) { + aSource = boost::dynamic_pointer_cast( + aRoot->feature(getGroup(), a, true)); + if (aSource->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument()) + break; + aSource.reset(); + } + if (aSource) { + boost::shared_ptr aCopy = + aPManager->copy(aSource->data()->docRef(PART_ATTR_DOC_REF)->value(), data()->getName()); + aRef->setFeature(aSource); + } + } +} diff --git a/src/PartSetPlugin/PartSetPlugin_Duplicate.h b/src/PartSetPlugin/PartSetPlugin_Duplicate.h new file mode 100644 index 000000000..9bab4d63e --- /dev/null +++ b/src/PartSetPlugin/PartSetPlugin_Duplicate.h @@ -0,0 +1,27 @@ +// File: PartSetPlugin_Duplicate.h +// Created: 20 May 2014 +// Author: Mikhail PONIKAROV + +#ifndef PartSetPlugin_Duplicate_HeaderFile +#define PartSetPlugin_Duplicate_HeaderFile + +#include "PartSetPlugin_Part.h" + +/// the reference to copy: reference to the attribute +const std::string PART_DUPLICATE_ATTR_REF = "Origin"; + +/**\class PartSetPlugin_Duplicate + * \ingroup DataModel + * \brief Duplicates the active part (not root). Creates a new "part" feature. + */ +class PartSetPlugin_Duplicate: public PartSetPlugin_Part +{ +public: + /// Makes a new part, copy of active + PartSetPlugin_Duplicate(); + + /// Request for initialization of data model of the feature: adding all attributes + PARTSETPLUGIN_EXPORT virtual void initAttributes(); +}; + +#endif diff --git a/src/PartSetPlugin/PartSetPlugin_Plugin.cpp b/src/PartSetPlugin/PartSetPlugin_Plugin.cpp index 85ea1c37e..76ea7b441 100644 --- a/src/PartSetPlugin/PartSetPlugin_Plugin.cpp +++ b/src/PartSetPlugin/PartSetPlugin_Plugin.cpp @@ -1,5 +1,7 @@ #include "PartSetPlugin_Plugin.h" #include "PartSetPlugin_Part.h" +#include "PartSetPlugin_Duplicate.h" +#include "PartSetPlugin_Remove.h" #include #include @@ -19,6 +21,12 @@ boost::shared_ptr PartSetPlugin_Plugin::createFeature(string t if (theFeatureID == "Part") { return boost::shared_ptr(new PartSetPlugin_Part); } - // feature of such kind is not found + if (theFeatureID == "duplicate") { + return boost::shared_ptr(new PartSetPlugin_Duplicate); + } + if (theFeatureID == "remove") { + return boost::shared_ptr(new PartSetPlugin_Remove); + } + // feature of such kind is not found return boost::shared_ptr(); } diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.cpp b/src/PartSetPlugin/PartSetPlugin_Remove.cpp new file mode 100644 index 000000000..5e99cb1f9 --- /dev/null +++ b/src/PartSetPlugin/PartSetPlugin_Remove.cpp @@ -0,0 +1,29 @@ +// File: PartSetPlugin_Remove.cxx +// Created: 20 May 2014 +// Author: Mikhail PONIKAROV + +#include "PartSetPlugin_Remove.h" +#include "PartSetPlugin_Part.h" +#include +#include +#include + +void PartSetPlugin_Remove::execute() +{ + boost::shared_ptr aPManager = ModelAPI_PluginManager::get(); + boost::shared_ptr aRoot = aPManager->rootDocument(); + boost::shared_ptr aCurrent; + boost::shared_ptr a; + for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) { + boost::shared_ptr aFeature = aRoot->feature(getGroup(), a, true); + if (aFeature->getKind() == "Part") { + boost::shared_ptr aPart = + boost::static_pointer_cast(aFeature); + if (aPart->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument()) { + // do remove + aPart->data()->docRef(PART_ATTR_DOC_REF)->value()->close(); + aRoot->removeFeature(aPart); + } + } + } +} diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.h b/src/PartSetPlugin/PartSetPlugin_Remove.h new file mode 100644 index 000000000..f12066c3e --- /dev/null +++ b/src/PartSetPlugin/PartSetPlugin_Remove.h @@ -0,0 +1,39 @@ +// File: PartSetPlugin_Remove.h +// Created: 20 May 2014 +// Author: Mikhail PONIKAROV + +#ifndef PartSetPlugin_Remove_HeaderFile +#define PartSetPlugin_Remove_HeaderFile + +#include "PartSetPlugin.h" +#include + +/**\class PartSetPlugin_Remove + * \ingroup DataModel + * \brief Feature for creation of the new part in PartSet. + */ +class PartSetPlugin_Remove: public ModelAPI_Feature +{ +public: + /// Returns the kind of a feature + PARTSETPLUGIN_EXPORT virtual const std::string& getKind() + {static std::string MY_KIND = "Remove"; return MY_KIND;} + + /// Returns to which group in the document must be added feature + PARTSETPLUGIN_EXPORT virtual const std::string& getGroup() + {static std::string MY_GROUP = "Parts"; return MY_GROUP;} + + /// Request for initialization of data model of the feature: adding all attributes + PARTSETPLUGIN_EXPORT virtual void initAttributes() {} + + /// Not normal feature that stored in the tree + PARTSETPLUGIN_EXPORT virtual bool isAction() {return true;} + + /// Performs the "remove" + PARTSETPLUGIN_EXPORT virtual void execute(); + + /// Use plugin manager for features creation + PartSetPlugin_Remove() {} +}; + +#endif