}
//=======================================================================
-const std::shared_ptr<Model_Document>& Model_Application::getDocument(string theDocID)
+std::shared_ptr<Model_Document> Model_Application::document(const int theDocID)
{
if (myDocs.find(theDocID) != myDocs.end())
return myDocs[theDocID];
+ return std::shared_ptr<Model_Document>(); // not loaded, so return null
+}
+//=======================================================================
+void Model_Application::createDocument(const int theDocID)
+{
static const std::string thePartSetKind("PartSet");
static const std::string thePartKind("Part");
- bool isRoot = theDocID == "root"; // the document is root
std::shared_ptr<Model_Document> aNew(
- new Model_Document(theDocID, isRoot ? thePartSetKind : thePartKind));
+ new Model_Document(theDocID, theDocID == 0 ? thePartSetKind : thePartKind));
myDocs[theDocID] = aNew;
+ aNew->setThis(aNew);
+ static Events_ID anId = ModelAPI_DocumentCreatedMessage::eventId();
+ std::shared_ptr<ModelAPI_DocumentCreatedMessage> aMessage = std::shared_ptr
+ <ModelAPI_DocumentCreatedMessage>(new ModelAPI_DocumentCreatedMessage(anId, this));
+ aMessage->setDocument(aNew);
+ Events_Loop::loop()->send(aMessage);
+}
+
+//=======================================================================
+bool Model_Application::loadDocument(const std::string theDocName, const int theDocID)
+{
+ static const std::string thePartKind("Part"); // root document is never loaded here
+ std::shared_ptr<Model_Document> aNew(new Model_Document(theDocID, thePartKind));
+ myDocs[theDocID] = aNew;
+
+ bool aRes = true;
// load it if it must be loaded by demand
- if (myLoadedByDemand.find(theDocID) != myLoadedByDemand.end() && !myPath.empty()) {
- aNew->load(myPath.c_str(), aNew);
- myLoadedByDemand.erase(theDocID); // done, don't do it anymore
- } else {
- aNew->setThis(aNew);
- static Events_ID anId = ModelAPI_DocumentCreatedMessage::eventId();
- std::shared_ptr<ModelAPI_DocumentCreatedMessage> aMessage = std::shared_ptr
- <ModelAPI_DocumentCreatedMessage>(new ModelAPI_DocumentCreatedMessage(anId, this));
- aMessage->setDocument(aNew);
- Events_Loop::loop()->send(aMessage);
+ if (myLoadedByDemand.find(theDocName) != myLoadedByDemand.end() && !myPath.empty()) {
+ aRes = aNew->load(myPath.c_str(), theDocName.c_str(), aNew);
+ myLoadedByDemand.erase(theDocName); // done, don't do it anymore
+ } else { // error
+ aRes = false;
}
- return myDocs[theDocID];
+ return aRes;
}
-void Model_Application::deleteDocument(string theDocID)
+//=======================================================================
+void Model_Application::deleteDocument(const int theDocID)
{
if (myDocs.find(theDocID) != myDocs.end()) {
myDocs[theDocID]->close(true);
myLoadedByDemand.clear();
}
+//=======================================================================
void Model_Application::deleteAllDocuments()
{
- std::map<std::string, std::shared_ptr<Model_Document> >::iterator aDoc = myDocs.begin();
+ std::map<int, std::shared_ptr<Model_Document> >::iterator aDoc = myDocs.begin();
for(; aDoc != myDocs.end(); aDoc++) {
- aDoc->second->close(true);
+ if (!aDoc->second->isOpened()) // here is main document was closed before subs and closed subs
+ aDoc->second->close(true);
}
myDocs.clear();
myLoadedByDemand.clear();
}
//=======================================================================
-bool Model_Application::hasDocument(std::string theDocID)
+bool Model_Application::hasDocument(const int theDocID)
{
return myDocs.find(theDocID) != myDocs.end();
}
+//=======================================================================
+bool Model_Application::hasRoot()
+{
+ return !myDocs.empty();
+}
+
+//=======================================================================
+std::shared_ptr<Model_Document> Model_Application::rootDocument()
+{
+ return myDocs[0];
+}
+
//=======================================================================
void Model_Application::setLoadPath(std::string thePath)
{
void Model_Application::removeUselessDocuments(
std::list<std::shared_ptr<ModelAPI_Document> > theUsedDocs)
{
- std::map<std::string, std::shared_ptr<Model_Document> >::iterator aDoc = myDocs.begin();
+ std::map<int, std::shared_ptr<Model_Document> >::iterator aDoc = myDocs.begin();
while(aDoc != myDocs.end()) {
bool aFound = false;
std::list<std::shared_ptr<ModelAPI_Document> >::iterator aUsed = theUsedDocs.begin();
}
}
+int Model_Application::generateDocumentId()
+{
+ int aResult = myDocs.size();
+ for(; myDocs.find(aResult) != myDocs.end(); aResult++); // count until the result id is unique
+ return aResult;
+}
+
//=======================================================================
Model_Application::Model_Application()
{
//! Retuns the application: one per process
MODEL_EXPORT static Handle_Model_Application getApplication();
- //! Returns the main document (on first call creates it) by the string identifier
- MODEL_EXPORT const std::shared_ptr<Model_Document>& getDocument(std::string theDocID);
+ //! Returns the document by the identifier
+ //! \returns false of document is not yet created/not loaded
+ MODEL_EXPORT std::shared_ptr<Model_Document> document(const int theDocID);
//! Returns true if document has been created
- MODEL_EXPORT bool hasDocument(std::string theDocID);
+ MODEL_EXPORT bool hasDocument(const int theDocID);
+ //! Returns true if root document has been created
+ MODEL_EXPORT bool hasRoot();
+ //! Returns root document, if created (or null otherwise)
+ MODEL_EXPORT std::shared_ptr<Model_Document> rootDocument();
//! Deletes the document from the application
- MODEL_EXPORT void deleteDocument(std::string theDocID);
+ MODEL_EXPORT void deleteDocument(const int theDocID);
//! Deletes all documents existing in the application
MODEL_EXPORT void deleteAllDocuments();
+ //! Creates a new document an returns an id of this document
+ //! \param theDocID if it is zero, the root document is created
+ MODEL_EXPORT void createDocument(const int theDocID);
+ //! Loads document by the file name (if it is registered as load by demand)
+ //! \param theDocName name of the document file
+ //! \param theDocID the identifier of the loaded document (to be created)
+ //! \returns true if load is ok
+ MODEL_EXPORT bool loadDocument(const std::string theDocName, const int theDocID);
//! Set path for the loaded by demand documents
void setLoadPath(std::string thePath);
//! not in the given list
void removeUselessDocuments(std::list<std::shared_ptr<ModelAPI_Document> > theUsedDocs);
+ //! produces new unique identifier of the document
+ int generateDocumentId();
+
public:
// Redefined OCAF methods
//! Return name of resource (i.e. "Standard")
Model_Application();
private:
- /// Map from string identifiers to created documents of an application
- std::map<std::string, std::shared_ptr<Model_Document> > myDocs;
+ /// Map from identifiers to created documents of an application
+ std::map<int, std::shared_ptr<Model_Document> > myDocs;
/// Path for the loaded by demand documents
std::string myPath;
/// Path for the loaded by demand documents
void Model_AttributeDocRef::setValue(std::shared_ptr<ModelAPI_Document> theDoc)
{
- myDoc = theDoc;
- TCollection_ExtendedString aNewID(theDoc->id().c_str());
- if (!myIsInitialized || myComment->Get() != aNewID) {
- myComment->Set(TCollection_ExtendedString(theDoc->id().c_str()));
+ if (myID->Get() != theDoc->id()) {
+ myID->Set(theDoc->id());
owner()->data()->sendAttributeUpdated(this);
}
}
std::shared_ptr<ModelAPI_Document> Model_AttributeDocRef::value()
{
- return myDoc;
+ return Model_Application::getApplication()->document(myID->Get());
+}
+
+int Model_AttributeDocRef::docId()
+{
+ return myID->Get();
}
Model_AttributeDocRef::Model_AttributeDocRef(TDF_Label& theLabel)
{
- myIsInitialized = theLabel.FindAttribute(TDataStd_Comment::GetID(), myComment) == Standard_True;
+ myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), myID) == Standard_True;
if (!myIsInitialized) {
- // create attribute: not initialized by value yet, just empty string
- myComment = TDataStd_Comment::Set(theLabel, "");
- } else { // document was already referenced: try to set it as loaded by demand
- Handle(Model_Application) anApp = Model_Application::getApplication();
- string anID(TCollection_AsciiString(myComment->Get()).ToCString());
- if (!anApp->hasDocument(anID)) {
- anApp->setLoadByDemand(anID);
- }
+ int aNewID = Model_Application::getApplication()->generateDocumentId();
+ myID = TDataStd_Integer::Set(theLabel, aNewID);
}
}
#include "Model.h"
#include "ModelAPI_AttributeDocRef.h"
-#include <TDataStd_Comment.hxx>
+#include <TDataStd_Integer.hxx>
#include <TDF_Label.hxx>
/**\class Model_AttributeDocRef
class Model_AttributeDocRef : public ModelAPI_AttributeDocRef
{
- Handle_TDataStd_Comment myComment; ///< reference to document is identified as string-id
- std::shared_ptr<ModelAPI_Document> myDoc; ///< document referenced by this attribute (if already loaded)
+ Handle(TDataStd_Integer) myID; ///< persistent and unique identifier of the document in the application
public:
+
/// Defines the document referenced from this attribute
MODEL_EXPORT virtual void setValue(std::shared_ptr<ModelAPI_Document> theDoc);
/// Returns document referenced from this attribute
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> value();
+ /// Returns the persisten ID of the document
+ MODEL_EXPORT virtual int docId();
+
protected:
/// Initializes attibutes
Model_AttributeDocRef(TDF_Label& theLabel);
myRef->Label().ForgetAttribute(TDataStd_AsciiString::GetID());
} else { // different document: store the document name (comment) and entry (string): external
// if these attributes exist, the link is external: keep reference to access the label
- TDataStd_Comment::Set(myRef->Label(), theObject->document()->id().c_str());
+ std::ostringstream anIdString; // string with document Id
+ anIdString<<theObject->document()->id();
+ TDataStd_Comment::Set(myRef->Label(), anIdString.str().c_str());
TCollection_AsciiString anEntry;
TDF_Tool::Entry(anObjLab, anEntry);
TDataStd_AsciiString::Set(myRef->Label(), anEntry);
if (isInitialized()) {
Handle(TDataStd_Comment) aDocID;
if (myRef->Label().FindAttribute(TDataStd_Comment::GetID(), aDocID)) { // external ref
- DocumentPtr aRefDoc =
- ModelAPI_Session::get()->document(TCollection_AsciiString(aDocID->Get()).ToCString());
- if (aRefDoc) {
+ int anID = atoi(TCollection_AsciiString(aDocID->Get()).ToCString());
+ DocumentPtr aRefDoc = Model_Application::getApplication()->document(anID);
+ if (aRefDoc.get()) {
Handle(TDataStd_AsciiString) anEntry;
if (myRef->Label().FindAttribute(TDataStd_AsciiString::GetID(), anEntry)) {
std::shared_ptr<Model_Document> aDR = std::dynamic_pointer_cast<Model_Document>(aRefDoc);
static const int TAG_CURRENT_TRANSACTION = 2; ///< integer, index of the transaction
static const int TAG_SELECTION_FEATURE = 3; ///< integer, tag of the selection feature label
-Model_Document::Model_Document(const std::string theID, const std::string theKind)
+Model_Document::Model_Document(const int theID, const std::string theKind)
: myID(theID), myKind(theKind), myIsActive(false),
myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format
{
myObjs->setOwner(theDoc);
}
-/// Returns the file name of this document by the nameof directory and identifuer of a document
-static TCollection_ExtendedString DocFileName(const char* theFileName, const std::string& theID)
+/// Returns the file name of this document by the name of directory and identifier of a document
+static TCollection_ExtendedString DocFileName(const char* theDirName, const std::string& theID)
{
- TCollection_ExtendedString aPath((const Standard_CString) theFileName);
+ TCollection_ExtendedString aPath((const Standard_CString) theDirName);
// remove end-separators
while(aPath.Length() &&
(aPath.Value(aPath.Length()) == '\\' || aPath.Value(aPath.Length()) == '/'))
return this == Model_Session::get()->moduleDocument().get();
}
-bool Model_Document::load(const char* theFileName, DocumentPtr theThis)
+bool Model_Document::load(const char* theDirName, const char* theFileName, DocumentPtr theThis)
{
Handle(Model_Application) anApp = Model_Application::getApplication();
if (isRoot()) {
- anApp->setLoadPath(theFileName);
+ anApp->setLoadPath(theDirName);
}
- TCollection_ExtendedString aPath(DocFileName(theFileName, myID));
+ TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
Handle(TDocStd_Document) aLoaded;
try {
myDoc = aLoaded;
myDoc->SetUndoLimit(UNDO_LIMIT);
// to avoid the problem that feature is created in the current, not this, document
- aSession->setActiveDocument(anApp->getDocument(myID), false);
+ aSession->setActiveDocument(anApp->document(myID), false);
aSession->setCheckTransactions(false);
if (myObjs)
delete myObjs;
aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
// this is done in Part result "activate", so no needed here. Causes not-blue active part.
// aSession->setActiveDocument(anApp->getDocument(myID), true);
+
+ // make sub-parts as loaded by demand
+ std::list<ResultPtr> aPartResults;
+ myObjs->allResults(ModelAPI_ResultPart::group(), aPartResults);
+ std::list<ResultPtr>::iterator aPartRes = aPartResults.begin();
+ for(; aPartRes != aPartResults.end(); aPartRes++) {
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aPartRes);
+ if (aPart.get())
+ anApp->setLoadByDemand(aPart->data()->name());
+ }
+
} else { // open failed, but new documnet was created to work with it: inform the model
aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
}
return !isError;
}
-bool Model_Document::save(const char* theFileName, std::list<std::string>& theResults)
+bool Model_Document::save(
+ const char* theDirName, const char* theFileName, std::list<std::string>& theResults)
{
// create a directory in the root document if it is not yet exist
Handle(Model_Application) anApp = Model_Application::getApplication();
#endif
}
// filename in the dir is id of document inside of the given directory
- TCollection_ExtendedString aPath(DocFileName(theFileName, myID));
+ TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
PCDM_StoreStatus aStatus;
try {
aStatus = anApp->SaveAs(myDoc, aPath);
}
myTransactionSave = myTransactions.size();
if (isDone) { // save also sub-documents if any
- theResults.push_back(TCollection_AsciiString(aPath).ToCString());
- const std::set<std::string> aSubs = subDocuments(false);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
- for (; aSubIter != aSubs.end() && isDone; aSubIter++) {
- if (anApp->isLoadByDemand(*aSubIter)) {
+ // iterate all result parts to find all loaded or not yet loaded documents
+ std::list<ResultPtr> aPartResults;
+ myObjs->allResults(ModelAPI_ResultPart::group(), aPartResults);
+ std::list<ResultPtr>::iterator aPartRes = aPartResults.begin();
+ for(; aPartRes != aPartResults.end(); aPartRes++) {
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aPartRes);
+ if (!aPart->isActivated()) {
// copy not-activated document that is not in the memory
- std::string aDocName = *aSubIter;
+ std::string aDocName = aPart->data()->name();
if (!aDocName.empty()) {
// just copy file
TCollection_AsciiString aSubPath(DocFileName(anApp->loadPath().c_str(), aDocName));
OSD_Path aPath(aSubPath);
OSD_File aFile(aPath);
if (aFile.Exists()) {
- TCollection_AsciiString aDestinationDir(DocFileName(theFileName, aDocName));
+ TCollection_AsciiString aDestinationDir(DocFileName(theDirName, aDocName));
OSD_Path aDestination(aDestinationDir);
aFile.Copy(aDestination);
theResults.push_back(aDestinationDir.ToCString());
}
}
} else { // simply save opened document
- isDone = subDoc(*aSubIter)->save(theFileName, theResults);
+ isDone = std::dynamic_pointer_cast<Model_Document>(aPart->partDoc())->
+ save(theDirName, aPart->data()->name().c_str(), theResults);
}
}
}
aPM->setActiveDocument(DocumentPtr());
}
// close all subs
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++) {
std::shared_ptr<Model_Document> aSub = subDoc(*aSubIter);
if (aSub->myObjs) // if it was not closed before
(*myNestedNum.rbegin())++;
myRedos.clear();
// new command for all subs
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++)
subDoc(*aSubIter)->startOperation();
}
// finish for all subs first: to avoid nested finishing and "isOperation" calls problems inside
bool aResult = false;
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++)
if (subDoc(*aSubIter)->finishOperation())
aResult = true;
myDoc->ClearRedos();
}
// abort for all subs, flushes will be later, in the end of root abort
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++)
subDoc(*aSubIter)->abortOperation();
// references may be changed because they are set in attributes on the fly
myTransactions.size() - aCurrentNum > 0 /* for omitting the first useless transaction */)
return true;
// check other subs contains operation that can be undoed
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++) {
std::shared_ptr<Model_Document> aSub = subDoc(*aSubIter);
if (aSub->myObjs) {// if it was not closed before
if (theWithSubs) {
// undo for all subs
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++) {
if (!subDoc(*aSubIter)->myObjs)
continue;
if (!myRedos.empty())
return true;
// check other subs contains operation that can be redoed
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++) {
if (!subDoc(*aSubIter)->myObjs)
continue;
}
// redo for all subs
- const std::set<std::string> aSubs = subDocuments(true);
- std::set<std::string>::iterator aSubIter = aSubs.begin();
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::iterator aSubIter = aSubs.begin();
for (; aSubIter != aSubs.end(); aSubIter++)
subDoc(*aSubIter)->redo();
myObjs->updateHistory(theGroup);
}
-std::shared_ptr<ModelAPI_Document> Model_Document::subDocument(std::string theDocID)
+const std::set<int> Model_Document::subDocuments() const
{
- return Model_Application::getApplication()->getDocument(theDocID);
-}
-
-const std::set<std::string> Model_Document::subDocuments(const bool theActivatedOnly) const
-{
- std::set<std::string> aResult;
+ std::set<int> aResult;
std::list<ResultPtr> aPartResults;
myObjs->allResults(ModelAPI_ResultPart::group(), aPartResults);
std::list<ResultPtr>::iterator aPartRes = aPartResults.begin();
for(; aPartRes != aPartResults.end(); aPartRes++) {
ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aPartRes);
- if (aPart && (!theActivatedOnly || aPart->isActivated())) {
- aResult.insert(aPart->original()->data()->name());
+ if (aPart && aPart->isActivated()) {
+ aResult.insert(aPart->original()->partDoc()->id());
}
}
return aResult;
}
-std::shared_ptr<Model_Document> Model_Document::subDoc(std::string theDocID)
+std::shared_ptr<Model_Document> Model_Document::subDoc(int theDocID)
{
// just store sub-document identifier here to manage it later
return std::dynamic_pointer_cast<Model_Document>(
- Model_Application::getApplication()->getDocument(theDocID));
+ Model_Application::getApplication()->document(theDocID));
}
ObjectPtr Model_Document::object(const std::string& theGroupID, const int theIndex)
return myObjs->internalFeature(theIndex);
}
+std::shared_ptr<ModelAPI_Feature> Model_Document::featureById(const int theId)
+{
+ return myObjs->featureById(theId);
+}
+
void Model_Document::synchronizeTransactions()
{
Model_Document* aRoot =
MODEL_EXPORT virtual const std::string& kind() const {return myKind;}
//! Loads the OCAF document from the file.
- //! \param theFileName full name of the file to load
+ //! \param theDirName directory of the loaded file
+ //! \param theFileName a name of the file to load
//! \param theThis the common shared pointer to the document to manage with it later
//! \returns true if file was loaded successfully
- MODEL_EXPORT virtual bool load(const char* theFileName, DocumentPtr theThis);
+ MODEL_EXPORT virtual bool load(
+ const char* theDirName, const char* theFileName, DocumentPtr theThis);
//! Saves the OCAF document to the file.
- //! \param theFileName full name of the file to store
+ //! \param theDirName directory where the document will be saved
+ //! \param theFileName a name of the document file to store
//! \param theResults the result full file names that were stored by "save"
//! \returns true if file was stored successfully
- MODEL_EXPORT virtual bool save(const char* theFileName, std::list<std::string>& theResults);
+ MODEL_EXPORT virtual bool save(
+ const char* theDirName, const char* theFileName, std::list<std::string>& theResults);
//! Removes document data
//! \param theForever if it is false, document is just hiden (to keep possibility make it back on Undo/Redo)
//! \returns index started from zero, or -1 if object is invisible or belongs to another document
MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Object> theObject);
- //! Adds a new sub-document by the identifier, or returns existing one if it is already exist
- MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> subDocument(std::string theDocID);
-
//! Internal sub-document by ID
- MODEL_EXPORT virtual std::shared_ptr<Model_Document> subDoc(std::string theDocID);
+ MODEL_EXPORT virtual std::shared_ptr<Model_Document> subDoc(int theDocID);
///! Returns the id of the document
- MODEL_EXPORT virtual const std::string& id() const
+ MODEL_EXPORT virtual const int id() const
{
return myID;
}
//! wihtout this participation
MODEL_EXPORT virtual void synchronizeTransactions();
+ //! Returns feature by the id of the feature (produced by the Data "featureId" method)
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Feature> featureById(const int theId);
+
/// Creates a construction cresults
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultConstruction> createConstruction(
TDF_Label generalLabel() const;
//! Creates new document with binary file format
- Model_Document(const std::string theID, const std::string theKind);
+ Model_Document(const int theID, const std::string theKind);
//! Returns the internal OCCT document of this interface
Handle_TDocStd_Document document()
//! \returns true if resulting transaction is not empty and can be undoed
void compactNested();
- //! Returns all sub documents
- const std::set<std::string> subDocuments(const bool theActivatedOnly) const;
+ //! Returns all loaded sub documents
+ const std::set<int> subDocuments() const;
//! The implementation of undo: with or without recoursive calls in the sub-documents
void undoInternal(const bool theWithSubs, const bool theSynchronize);
friend class DFBrowser;
private:
- std::string myID; ///< identifier of the document in the application
+ int myID; ///< identifier of the document in the application
std::string myKind; ///< kind of the document in the application
Handle_TDocStd_Document myDoc; ///< OCAF document
isSameName = (*aRIter)->data()->name() == aName;
}
}
- // for new Parts create names that are not in the Postponed list
- if (!isSameName && (theFeature->getKind() == "Part" || theFeature->getKind() == "Duplicate")) {
- std::shared_ptr<Model_Session> aSession =
- std::dynamic_pointer_cast<Model_Session>(Model_Session::get());
- isSameName = aSession->isLoadByDemand(aName) || aSession->hasDocument(aName);
- }
if (isSameName) {
aNumObjects++;
theObj->initAttributes();
}
+std::shared_ptr<ModelAPI_Feature> Model_Objects::featureById(const int theId)
+{
+ if (theId > 0) {
+ TDF_Label aLab = featuresLabel().FindChild(theId, Standard_False);
+ return feature(aLab);
+ }
+ return std::shared_ptr<ModelAPI_Feature>(); // not found
+}
+
void Model_Objects::synchronizeFeatures(
const TDF_LabelList& theUpdated, const bool theUpdateReferences, const bool theFlush)
{
//! Returns the feature by zero-based index: features in the history or not
std::shared_ptr<ModelAPI_Feature> internalFeature(const int theIndex);
+ //! Returns feature by the id of the feature (produced by the Data "featureId" method)
+ std::shared_ptr<ModelAPI_Feature> featureById(const int theId);
+
+
/// Creates a construction result
std::shared_ptr<ModelAPI_ResultConstruction> createConstruction(
const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeReference.h>
#include <Model_Document.h>
+#include <Model_Application.h>
#include <Events_Loop.h>
#include <ModelAPI_Events.h>
void Model_ResultPart::initAttributes()
{
// append the color attribute. It is empty, the attribute will be filled by a request
- data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId());
+ AttributeDocRefPtr aDocRef = std::dynamic_pointer_cast<ModelAPI_AttributeDocRef>(
+ data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()));
data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
data()->addAttribute(BASE_REF_ID(), ModelAPI_AttributeReference::typeId());
+
+ if (aDocRef->isInitialized() && // initialized immideately means already exist and will be loaded
+ !Model_Application::getApplication()->hasDocument(aDocRef->docId()))
+ Model_Application::getApplication()->setLoadByDemand(data()->name());
}
std::shared_ptr<ModelAPI_Document> Model_ResultPart::partDoc()
return baseRef()->partDoc();
}
DocumentPtr aRes = data()->document(DOC_REF())->value();
- if (!aRes.get() && myIsInLoad) { // trying to get this document from the session
- aRes = document()->subDocument(data()->name());
- }
return aRes;
}
Model_ResultPart::Model_ResultPart()
{
- myIsInLoad = false;
}
void Model_ResultPart::activate()
bool isNewTransaction = false;
SessionPtr aMgr = ModelAPI_Session::get();
if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created
- myIsInLoad = true;
+ Handle(Model_Application) anApp = Model_Application::getApplication();
if (!aMgr->isOperation()) {
aMgr->startOperation("Activation");
isNewTransaction = true;
}
- std::shared_ptr<ModelAPI_Document> aDoc = document()->subDocument(data()->name());
- myIsInLoad = false;
- if (aDoc) {
+ if (anApp->isLoadByDemand(data()->name())) {
+ anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just ne part, load may fail
+ } else {
+ anApp->createDocument(aDocRef->docId());
+ }
+ std::shared_ptr<ModelAPI_Document> aDoc = aDocRef->value();
+ if (aDoc.get()) {
aDoc->synchronizeTransactions();
aDocRef->setValue(aDoc);
}
{
TopoDS_Shape myShape; ///< shape of this part created from bodies (updated only of Part deactivation)
std::shared_ptr<gp_Trsf> myTrsf; ///< if it is just copy of original shape, keep just transformation
- bool myIsInLoad; ///< true if document of this part is in the loading process, so, it may be already received
public:
/// the reference to the base result document, may be null if this is the root, others make sequence of references
bool Model_Session::load(const char* theFileName)
{
- bool aRes = ROOT_DOC->load(theFileName, ROOT_DOC);
+ bool aRes = ROOT_DOC->load(theFileName, "root", ROOT_DOC);
return aRes;
}
bool Model_Session::save(const char* theFileName, std::list<std::string>& theResults)
{
- return ROOT_DOC->save(theFileName, theResults);
+ return ROOT_DOC->save(theFileName, "root", theResults);
}
void Model_Session::closeAll()
std::shared_ptr<ModelAPI_Document> Model_Session::moduleDocument()
{
- bool aFirstCall = !Model_Application::getApplication()->hasDocument("root");
+ Handle(Model_Application) anApp = Model_Application::getApplication();
+ bool aFirstCall = !anApp->hasRoot();
if (aFirstCall) {
// creation of the root document is always outside of the transaction, so, avoid checking it
setCheckTransactions(false);
- }
- std::shared_ptr<ModelAPI_Document> aDoc = std::shared_ptr<ModelAPI_Document>(
- Model_Application::getApplication()->getDocument("root"));
- if (aFirstCall) {
+ anApp->createDocument(0); // 0 is a root ID
// creation of the root document is always outside of the transaction, so, avoid checking it
setCheckTransactions(true);
}
- return aDoc;
+ return anApp->rootDocument();
}
-std::shared_ptr<ModelAPI_Document> Model_Session::document(std::string theDocID)
+std::shared_ptr<ModelAPI_Document> Model_Session::document(int theDocID)
{
return std::shared_ptr<ModelAPI_Document>(
- Model_Application::getApplication()->getDocument(theDocID));
+ Model_Application::getApplication()->document(theDocID));
}
bool Model_Session::hasModuleDocument()
{
- return Model_Application::getApplication()->hasDocument("root");
-}
-
-bool Model_Session::hasDocument(std::string theDocID)
-{
- return Model_Application::getApplication()->hasDocument(theDocID);
+ return Model_Application::getApplication()->hasRoot();
}
std::shared_ptr<ModelAPI_Document> Model_Session::activeDocument()
DocumentPtr anAPIDoc = *aDoc;
std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(anAPIDoc);
if (aDoc) {
- const std::set<std::string> aSubs = aDoc->subDocuments(true);
- std::set<std::string>::const_iterator aSubIter = aSubs.cbegin();
+ const std::set<int> aSubs = aDoc->subDocuments();
+ std::set<int>::const_iterator aSubIter = aSubs.cbegin();
for(; aSubIter != aSubs.cend(); aSubIter++) {
- if (!Model_Application::getApplication()->isLoadByDemand(*aSubIter)) {
- aResult.push_back(Model_Application::getApplication()->getDocument(*aSubIter));
- }
+ aResult.push_back(Model_Application::getApplication()->document(*aSubIter));
}
}
}
}
std::shared_ptr<ModelAPI_Document> Model_Session::copy(
- std::shared_ptr<ModelAPI_Document> theSource, std::string theID)
+ std::shared_ptr<ModelAPI_Document> theSource, const int theDestID)
{
- // create a new document
- std::shared_ptr<Model_Document> aNew = std::dynamic_pointer_cast<Model_Document>(
- Model_Application::getApplication()->getDocument(theID));
+ std::shared_ptr<Model_Document> aNew = Model_Application::getApplication()->document(theDestID);
// make a copy of all labels
TDF_Label aSourceRoot = std::dynamic_pointer_cast<Model_Document>(theSource)->document()->Main()
.Father();
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> moduleDocument();
/// Returns the document by ID, loads if not loaded yet. Returns null if no such document.
- MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> document(std::string theDocID);
- /// Return true if document with such ID has been already created
- MODEL_EXPORT virtual bool hasDocument(std::string theDocID);
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> document(int theDocID);
/// Return true if root document has been already created
MODEL_EXPORT virtual bool hasModuleDocument();
/// Processes the configuration file reading
MODEL_EXPORT virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
- /// Copies the document to the new one with the given id
+ /// Copies the document to the new one
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> copy(
- std::shared_ptr<ModelAPI_Document> theSource, std::string theID);
+ std::shared_ptr<ModelAPI_Document> theSource, const int theDestID);
/// Returns the validators factory: the only one instance per application
MODEL_EXPORT virtual ModelAPI_ValidatorsFactory* validators();
/// Returns document referenced from this attribute
MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Document> value() = 0;
+ /// Returns the persisten ID of the document
+ MODELAPI_EXPORT virtual int docId() = 0;
+
/// Returns the type of this class of attributes
MODELAPI_EXPORT static std::string typeId()
{
virtual void moveFeature(std::shared_ptr<ModelAPI_Feature> theMoved,
std::shared_ptr<ModelAPI_Feature> theAfterThis) = 0;
- ///! Adds a new sub-document by the identifier, or returns existing one if it is already exist
- virtual std::shared_ptr<ModelAPI_Document> subDocument(std::string theDocID) = 0;
-
///! Returns the id of the document
- virtual const std::string& id() const = 0;
+ virtual const int id() const = 0;
//! Returns the object in the group by the index (started from zero)
//! \param theGroupID group that contains an object
//! wihtout this participation
virtual void synchronizeTransactions() = 0;
+ //! Returns feature by the id of the feature (produced by the Data "featureId" method)
+ virtual std::shared_ptr<ModelAPI_Feature> featureById(const int theId) = 0;
//! To virtually destroy the fields of successors
MODELAPI_EXPORT virtual ~ModelAPI_Document();
/// Returns the root document of the application (that may contains sub-documents)
virtual std::shared_ptr<ModelAPI_Document> moduleDocument() = 0;
- /// Returns the document by ID, loads if not loaded yet. Returns null if no such document.
- virtual std::shared_ptr<ModelAPI_Document> document(std::string theDocID) = 0;
+ /// Returns the document by ID. Returns null if no such document.
+ virtual std::shared_ptr<ModelAPI_Document> document(int theDocID) = 0;
/// Return true if root document has been already created
virtual bool hasModuleDocument() = 0;
virtual bool isLoadByDemand(const std::string theDocID) = 0;
/// Copies the document to the new one with the given id
- virtual std::shared_ptr<ModelAPI_Document> copy(std::shared_ptr<ModelAPI_Document> theSource,
- std::string theID) = 0;
+ virtual std::shared_ptr<ModelAPI_Document> copy(
+ std::shared_ptr<ModelAPI_Document> theSource, const int theDestID) =0;
/// Returns the validators factory: the only one instance per application
virtual ModelAPI_ValidatorsFactory* validators() = 0;
aSession = ModelAPI_Session.get()
# TODO: enable this assertion:
assert(aSession.moduleDocument())
-assert(aSession.moduleDocument().id() == "root")
+assert(aSession.moduleDocument().id() == 0)
assert(aSession.moduleDocument().kind() == "PartSet")
assert(aSession.hasModuleDocument())
# Create a new document
aSession.finishOperation()
assert(aSession.activeDocument())
-assert(aSession.activeDocument().id() == "Part_1")
+assert(aSession.activeDocument().id() == 1)
assert(aSession.activeDocument().kind() == "Part")
# Activate root doc
-aRootDoc = aSession.document("root")
+aRootDoc = aSession.document(0)
assert(aRootDoc)
aSession.startOperation()
aSession.setActiveDocument(aRootDoc, False)
aSession.finishOperation()
assert(aSession.activeDocument())
-assert(aSession.activeDocument().id() == "root")
+assert(aSession.activeDocument().id() == 0)
# check all opened docs
allDocsList = aSession.allOpenedDocuments()
assert(len(allDocsList) != 0)
# Activate Part_1 doc back for further testing
aSession.startOperation()
-aSession.setActiveDocument(aSession.document("Part_1"), False)
+aSession.setActiveDocument(aSession.document(1), False)
aSession.finishOperation()
#=========================================================================
# Duplication of a document
aSession.finishOperation()
assert(aSession.moduleDocument().size("Parts") == 2)
aCopyOfPart = aSession.activeDocument()
-assert(aCopyOfPart.id() == "Part_2")
+assert(aCopyOfPart.id() == 2)
assert(aCopyOfPart.kind() == "Part")
assert(aCopyOfPart.size("Features") == 1)
assert(aCopyOfPart != aPart)
assert(aSession.activeDocument().id() == aCopyOfPart.id())
# Remove another one document
aSession.startOperation()
-aDoc2 = aSession.document("Part_2")
+aDoc2 = aSession.document(2)
aSession.setActiveDocument(aDoc2, False)
aDoc2.addFeature("Remove")
aSession.finishOperation()
// Author: Mikhail PONIKAROV
#include "PartSetPlugin_Duplicate.h"
+#include "PartSetPlugin_Part.h"
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_AttributeDocRef.h>
#include <ModelAPI_Data.h>
using namespace std;
-PartSetPlugin_Duplicate::PartSetPlugin_Duplicate()
-{
-}
-
-void PartSetPlugin_Duplicate::initAttributes()
+void PartSetPlugin_Duplicate::execute()
{
- PartSetPlugin_Part::initAttributes();
-
std::shared_ptr<ModelAPI_Session> aPManager = ModelAPI_Session::get();
std::shared_ptr<ModelAPI_Document> aRoot = aPManager->moduleDocument();
std::shared_ptr<ModelAPI_ResultPart> aSource; // searching for source document attribute
aSource.reset();
}
if (aSource) {
+ // create a new Part feature
+ FeaturePtr aNewPart = aRoot->addFeature(PartSetPlugin_Part::ID(), false);
+ aNewPart->execute(); // to make result and generate a unique name
+
std::shared_ptr<ModelAPI_Document> aCopy = aPManager->copy(
- aSource->data()->document(ModelAPI_ResultPart::DOC_REF())->value(), data()->name());
- } else { // invalid part copy: do nothing, keep this in empty name
- data()->setName("");
+ aSource->data()->document(ModelAPI_ResultPart::DOC_REF())->value(),
+ std::dynamic_pointer_cast<ModelAPI_ResultPart>(aNewPart->firstResult())->partDoc()->id());
}
}
-
-void PartSetPlugin_Duplicate::execute()
-{
- if (!data()->name().empty())
- PartSetPlugin_Part::execute();
-}
-
-const std::string& PartSetPlugin_Duplicate::documentToAdd()
-{
- // part must be added only to the module document
- return ModelAPI_Session::get()->moduleDocument()->kind();
-}
#ifndef PartSetPlugin_Duplicate_H_
#define PartSetPlugin_Duplicate_H_
-#include "PartSetPlugin_Part.h"
+#include "PartSetPlugin.h"
+#include <ModelAPI_Feature.h>
/**\class PartSetPlugin_Duplicate
* \ingroup Plugins
* \brief Duplicates the active part (not root). Creates a new "part" feature.
*/
-class PartSetPlugin_Duplicate : public PartSetPlugin_Part
+class PartSetPlugin_Duplicate : public ModelAPI_Feature
{
public:
- /// Duplicate kind
+
+ /// Duplicate kind
inline static const std::string& ID()
{
- static const std::string MY_DUPLICATE_KIND("Duplicate");
- return MY_DUPLICATE_KIND;
+ static const std::string MY_REMOVE_KIND("Duplicate");
+ return MY_REMOVE_KIND;
+ }
+ /// Returns the kind of a feature
+ PARTSETPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = PartSetPlugin_Duplicate::ID();
+ return MY_KIND;
}
- /// Makes a new part, copy of active
- PartSetPlugin_Duplicate();
-
- /// Part must be added only to PartSet
- PARTSETPLUGIN_EXPORT virtual const std::string& documentToAdd();
+ /// 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();
+ PARTSETPLUGIN_EXPORT virtual void initAttributes()
+ {
+ }
- /// doesn't call creation of new document, just does nothing if document was not copied
+ /// Not normal feature that stored in the tree
+ PARTSETPLUGIN_EXPORT virtual bool isAction()
+ {
+ return true;
+ }
+
+ /// Performs the "duplicate"
PARTSETPLUGIN_EXPORT virtual void execute();
+
+ /// Use plugin manager for features creation
+ PartSetPlugin_Duplicate()
+ {
+ }
+
};
#endif