subDocument(*aSubIter)->close();
mySubs.clear();
// close this
- myDoc->Close();
+ if (myDoc->CanClose() == CDM_CCS_OK)
+ myDoc->Close();
Model_Application::getApplication()->deleteDocument(myID);
}
void Model_Document::addFeature(const boost::shared_ptr<ModelAPI_Feature> theFeature)
{
+ if (theFeature->isAction()) return; // do not add action to the data model
+
boost::shared_ptr<ModelAPI_Document> aThis =
Model_Application::getApplication()->getDocument(myID);
TDF_Label aFeaturesLab = groupLabel(FEATURES_GROUP);
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<ModelAPI_Feature> theFeature)
+{
+ boost::shared_ptr<Model_Data> aData = boost::static_pointer_cast<Model_Data>(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<boost::shared_ptr<ModelAPI_Feature> >::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<ModelAPI_Feature> Model_Document::feature(TDF_Label& theLabel)
{
// iterate all features, may be optimized later by keeping labels-map
aNumObjects++;
stringstream aNameStream;
aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
+ aName = aNameStream.str();
// reinitialize iterator to make sure a new name is unique
a = 0;
} else a++;
//! \param creates feature and puts it in the document
MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> addFeature(std::string theID);
+ //! Removes the feature from the document
+ MODEL_EXPORT virtual void removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
//! Returns the existing feature by the label
//! \param theLabel base label of the feature
MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> feature(TDF_Label& theLabel);
//! 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
#include <Model_Document.h>
#include <Model_Application.h>
#include <Events_Loop.h>
+#include <Events_Error.h>
#include <Config_FeatureMessage.h>
#include <Config_ModuleReader.h>
+#include <TDF_CopyTool.hxx>
+#include <TDF_DataSet.hxx>
+#include <TDF_RelocationTable.hxx>
+#include <TDF_ClosureTool.hxx>
+
+
using namespace std;
static Model_PluginManager* myImpl = new Model_PluginManager();
if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
boost::shared_ptr<ModelAPI_Feature> 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 + "'");
}
}
myCurrentDoc = theDoc;
}
+boost::shared_ptr<ModelAPI_Document> Model_PluginManager::copy(
+ boost::shared_ptr<ModelAPI_Document> theSource, std::string theID)
+{
+ // create a new document
+ boost::shared_ptr<Model_Document> aNew = boost::dynamic_pointer_cast<Model_Document>(
+ Model_Application::getApplication()->getDocument(theID));
+ // make a copy of all labels
+ TDF_Label aSourceRoot =
+ boost::dynamic_pointer_cast<Model_Document>(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;
/// 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<ModelAPI_Document> copy(
+ boost::shared_ptr<ModelAPI_Document> theSource, std::string theID);
+
/// Is called only once, on startup of the application
Model_PluginManager();
//! \param creates feature and puts it in the document
MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> addFeature(std::string theID) = 0;
+ //! Removes the feature from the document
+ MODELAPI_EXPORT virtual void removeFeature(boost::shared_ptr<ModelAPI_Feature> 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<ModelAPI_Document> subDocument(std::string theDocID) = 0;
+ MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Document>
+ subDocument(std::string theDocID) = 0;
///! Returns the id of hte document
MODELAPI_EXPORT virtual const std::string& id() const = 0;
/// 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<ModelAPI_Data> data() {return myData;}
/// Defines the current document that used for current work in the application
virtual void setCurrentDocument(boost::shared_ptr<ModelAPI_Document> theDoc) = 0;
+ /// Copies the document to the new one wit hthe given id
+ virtual boost::shared_ptr<ModelAPI_Document> copy(
+ boost::shared_ptr<ModelAPI_Document> theSource, std::string theID) = 0;
+
/// Is needed for python wrapping by swig, call Get to get an instance
ModelAPI_PluginManager();
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})
--- /dev/null
+// File: PartSetPlugin_Duplicate.cxx
+// Created: 20 May 2014
+// Author: Mikhail PONIKAROV
+
+#include "PartSetPlugin_Duplicate.h"
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+
+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<ModelAPI_AttributeRefAttr> aRef = data()->refattr(PART_DUPLICATE_ATTR_REF);
+ if (!aRef->attr()) { // create a copy: if not created yet attribute is not initialized
+ boost::shared_ptr<ModelAPI_PluginManager> aPManager = ModelAPI_PluginManager::get();
+ boost::shared_ptr<ModelAPI_Document> aRoot = aPManager->rootDocument();
+ boost::shared_ptr<PartSetPlugin_Part> aSource; // searching for source document attribute
+ for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) {
+ aSource = boost::dynamic_pointer_cast<PartSetPlugin_Part>(
+ aRoot->feature(getGroup(), a, true));
+ if (aSource->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument())
+ break;
+ aSource.reset();
+ }
+ if (aSource) {
+ boost::shared_ptr<ModelAPI_Document> aCopy =
+ aPManager->copy(aSource->data()->docRef(PART_ATTR_DOC_REF)->value(), data()->getName());
+ aRef->setFeature(aSource);
+ }
+ }
+}
--- /dev/null
+// 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
#include "PartSetPlugin_Plugin.h"
#include "PartSetPlugin_Part.h"
+#include "PartSetPlugin_Duplicate.h"
+#include "PartSetPlugin_Remove.h"
#include <ModelAPI_PluginManager.h>
#include <ModelAPI_Document.h>
if (theFeatureID == "Part") {
return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Part);
}
- // feature of such kind is not found
+ if (theFeatureID == "duplicate") {
+ return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Duplicate);
+ }
+ if (theFeatureID == "remove") {
+ return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Remove);
+ }
+ // feature of such kind is not found
return boost::shared_ptr<ModelAPI_Feature>();
}
--- /dev/null
+// File: PartSetPlugin_Remove.cxx
+// Created: 20 May 2014
+// Author: Mikhail PONIKAROV
+
+#include "PartSetPlugin_Remove.h"
+#include "PartSetPlugin_Part.h"
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_AttributeDocRef.h>
+
+void PartSetPlugin_Remove::execute()
+{
+ boost::shared_ptr<ModelAPI_PluginManager> aPManager = ModelAPI_PluginManager::get();
+ boost::shared_ptr<ModelAPI_Document> aRoot = aPManager->rootDocument();
+ boost::shared_ptr<ModelAPI_Document> aCurrent;
+ boost::shared_ptr<PartSetPlugin_Part> a;
+ for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) {
+ boost::shared_ptr<ModelAPI_Feature> aFeature = aRoot->feature(getGroup(), a, true);
+ if (aFeature->getKind() == "Part") {
+ boost::shared_ptr<PartSetPlugin_Part> aPart =
+ boost::static_pointer_cast<PartSetPlugin_Part>(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);
+ }
+ }
+ }
+}
--- /dev/null
+// File: PartSetPlugin_Remove.h
+// Created: 20 May 2014
+// Author: Mikhail PONIKAROV
+
+#ifndef PartSetPlugin_Remove_HeaderFile
+#define PartSetPlugin_Remove_HeaderFile
+
+#include "PartSetPlugin.h"
+#include <ModelAPI_Feature.h>
+
+/**\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