From: Pablo Garzon Date: Tue, 18 Jul 2023 11:28:17 +0000 (+0200) Subject: #3507 Undo and Redo Meshes X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=0105528a5e3a8a9bb4f1e7b313e6a4e437ddb5e6;p=creaVtk.git #3507 Undo and Redo Meshes --- diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx index e8ed045..b4190a2 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx @@ -53,11 +53,19 @@ void MeshManager::Process() { meshManagerModel_Box = new MeshManagerModel_Box(this); - meshManagerModel_Box->AddMeshes_( bbGetInputMeshVector() ); - - meshManagerModel_Box->AddMesh_( bbGetInputMesh() ); + if(bbGetInputMemoryMode() == false){ + meshManagerModel_Box->MeshMemoryModeOff(); + meshManagerModel_Box->AddMeshes_( bbGetInputMeshVector() ); + meshManagerModel_Box->AddMesh_( bbGetInputMesh() ); + meshManagerModel_Box->ResetHistory(); + } + else{ + meshManagerModel_Box->MeshMemoryModeOn(); + meshManagerModel_Box->SetHistory(50); + meshManagerModel_Box->AddMesh_( bbGetInputMesh() ); + meshManagerModel_Box->SaveMemoryMode(); + } - meshManagerModel_Box->ResetHistory(); //meshManagerModel_Box->SetMeshBase( bbGetInputMesh() ); meshManagerModel_Box->RefreshOutputs(false); bbSetOutputMeshManagerModel( meshManagerModel_Box ); diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.h b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.h index 02dc689..39d1566 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.h +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.h @@ -25,6 +25,7 @@ class bbcreaVtk_EXPORT MeshManager //===== BBTK_DECLARE_INPUT(Mesh,vtkPolyData*); BBTK_DECLARE_INPUT(MeshVector, std::vector); + BBTK_DECLARE_INPUT(MemoryMode, bool); BBTK_DECLARE_OUTPUT(MeshBase,vtkPolyData*); BBTK_DECLARE_OUTPUT(MeshTemp,vtkPolyData*); BBTK_DECLARE_OUTPUT(MeshNames,std::vector); @@ -61,6 +62,7 @@ BBTK_BEGIN_DESCRIBE_BLACK_BOX(MeshManager,bbtk::AtomicBlackBox); BBTK_INPUT(MeshManager,Mesh,"Mesh",vtkPolyData*,""); BBTK_INPUT(MeshManager,MeshVector,"Vector of Meshes",std::vector,""); + BBTK_INPUT(MeshManager,MemoryMode,"Memory Mode, default false", bool,""); BBTK_OUTPUT(MeshManager,MeshBase,"Mesh Base",vtkPolyData*,""); BBTK_OUTPUT(MeshManager,MeshTemp,"Mesh Temp",vtkPolyData*,""); BBTK_OUTPUT(MeshManager,MeshNames,"Mesh Names",std::vector,""); diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx index cf99baf..1be40ff 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx @@ -56,7 +56,14 @@ void MeshManager_tool::Process() { bbGetInputMeshManagerModel()->SetMeshMemoryMode( bbGetInputMesh() ); } // if Tool 35 Set memory mode - + if(bbGetInputTool() == 37) // Save State Memory Mode + { + if(bbGetInputStringParam().length() > 0){ + cout << " MeshManager_tool : MeshManagerModel Executed tool 37" << endl;//bGetInputMeshManagerModel()->Save(); + bbGetInputMeshManagerModel()->SaveMemoryMode(); + // cout << bbGetInputStringParam() << endl; + } + } if (bbGetInputTool()==32) // Copy and Set { bbGetInputMeshManagerModel()->CopySetMeshBase( bbGetInputMesh() ); diff --git a/lib/creaVtk/MeshManagerModel.cpp b/lib/creaVtk/MeshManagerModel.cpp index 41b9770..ddf2558 100644 --- a/lib/creaVtk/MeshManagerModel.cpp +++ b/lib/creaVtk/MeshManagerModel.cpp @@ -48,21 +48,27 @@ void HistoryHandler::CleanHistory() { delete element; } + redoStack.clear(); for (T* element : undoStack) { delete element; } + undoStack.clear(); } template T* HistoryHandler::Undo(T* state) { + if(state == NULL) + { + return NULL; + } if(!undoStack.empty()) { auto lastElem = undoStack.back(); undoStack.pop_back(); redoStack.push_back(state); - return lastElem;//undoStack.back(); + return lastElem; }else{ delete state; } @@ -72,6 +78,10 @@ T* HistoryHandler::Undo(T* state) template T* HistoryHandler::Redo(T* state) { + if(state == NULL) + { + return NULL; + } if(!redoStack.empty()) { auto lastElem = redoStack.back(); @@ -80,8 +90,46 @@ T* HistoryHandler::Redo(T* state) return lastElem; }else{ delete state; + return NULL; + } +} + +/** +* To be used with RedoKeepCurrent +* Will always maintain the current state in the undo stack as the first element +* Useful when states are saved after actions and the initial state is saved. +*/ +template +T* HistoryHandler::UndoKeepCurrent() +{ + if(undoStack.size() > 1) + { + auto lastElem = undoStack.back(); + undoStack.pop_back(); + redoStack.push_back(lastElem); + return undoStack.back(); + }else{ + return NULL; + } +} + +/** +* To be used with UndoKeepCurrent +* Will always maintain the current state in the undo stack as the first element +* Useful when states are saved after actions and the initial state is saved. +*/ +template +T* HistoryHandler::RedoKeepCurrent() +{ + if(!redoStack.empty()) + { + auto lastElem = redoStack.back(); + redoStack.pop_back(); + undoStack.push_back(lastElem); + return undoStack.back(); + }else{ + return NULL; } - return NULL; } template @@ -90,8 +138,9 @@ void HistoryHandler::Save(T* state) undoStack.push_back(state); if(undoStack.size() > maxElements) { - delete undoStack.front(); + T* frontDel = undoStack.front(); undoStack.pop_front(); + delete frontDel; } if(!redoStack.empty()) { @@ -279,21 +328,32 @@ MeshManagerModel::MeshManagerModel() meshId = 0; history = new HistoryHandler(15); lastModified = 0; + memoryMode = false; } MeshManagerModel::~MeshManagerModel() { DeleteAll(); + history->CleanHistory(); + delete history; } void MeshManagerModel::RefreshOutputs(bool signalBox) // virtual { } +void MeshManagerModel::SetHistory(int maxCapacity) +{ + if(history != NULL){ + ResetHistory(); + delete history; + } + history = new HistoryHandler(maxCapacity); +} + void MeshManagerModel::ResetHistory() { history->CleanHistory(); - //Save(); } int MeshManagerModel::GetNumberOfMeshes() @@ -550,6 +610,16 @@ void MeshManagerModel::SetMeshBase(vtkPolyData* mesh) } } +void MeshManagerModel::MeshMemoryModeOn() +{ + memoryMode = true; +} + +void MeshManagerModel::MeshMemoryModeOff() +{ + memoryMode = false; +} + void MeshManagerModel::SetMeshMemoryMode(vtkPolyData* mesh) { if(_meshes.size() > 1) @@ -561,6 +631,8 @@ void MeshManagerModel::SetMeshMemoryMode(vtkPolyData* mesh) AddEmptyMesh_(); } _meshes.at(currentMesh)->SetMeshMemoryMode(mesh); + ResetHistory(); + SaveMemoryMode(); RefreshOutputs(true); } @@ -616,25 +688,47 @@ int MeshManagerModel::GetCurrentMesh() void MeshManagerModel::Undo() { if(history->UndoSize() > 0) - { - RestoreState(history->Undo(new ManagerState(_meshes, meshId, lastModified))); - RefreshOutputs(true); + { + if(memoryMode == false){ + RestoreState(history->Undo(new ManagerState(_meshes, meshId, lastModified))); + RefreshOutputs(true); + } + else if(history->UndoSize() > 1){ + RestoreStateMemoryMode(history->UndoKeepCurrent()); + } } } void MeshManagerModel::Redo() { if(history->RedoSize() > 0) - { - RestoreState(history->Redo(new ManagerState(_meshes, meshId, lastModified))); - RefreshOutputs(true); + { + if(memoryMode == false){ + RestoreState(history->Redo(new ManagerState(_meshes, meshId, lastModified))); + RefreshOutputs(true); + } + else{ + RestoreStateMemoryMode(history->RedoKeepCurrent()); + } } } void MeshManagerModel::Save() { history->Save(new ManagerState(_meshes, meshId, currentMesh)); - //lastModified = currentMesh; +} + +void MeshManagerModel::SaveMemoryMode() +{ + if(_meshes.size() == 1 && memoryMode) + { + std::vector> savedMesh; + savedMesh.push_back(std::make_shared(_meshes.at(0).get())); + history->Save(new ManagerState(savedMesh, meshId, 0)); + } + else{ + printf("PG MeshManagerModel::SaveMemoryMode WARNING Mesh vector has invalid size or memoryMode is not set \n"); + } } void MeshManagerModel::RestoreState(ManagerState* state) @@ -645,6 +739,23 @@ void MeshManagerModel::RestoreState(ManagerState* state) meshId = state->GetMeshId(); currentMesh = state->GetModifiedPos(); lastModified = state->GetModifiedPos(); + delete state; + } + else{ + printf("PG MeshManagerModel::RestoreState WARNING State is NULL \n"); + } +} + +void MeshManagerModel::RestoreStateMemoryMode(ManagerState* state){ + if(_meshes.size() == 1 && state != NULL) + { + vtkPoints* statePoints = vtkPoints::New(); + statePoints->DeepCopy(state->GetMeshes().at(0)->GetMeshBase()->GetPoints()); + _meshes.at(0)->GetMeshBase()->SetPoints(statePoints); + _meshes.at(0)->GetMeshBase()->GetPoints()->Modified(); + _meshes.at(0)->GetMeshBase()->Modified(); + }else{ + printf("PG MeshManagerModel::RestoreStateMemoryMode WARNING Mesh vector has invalid size or state is NULL\n"); } } diff --git a/lib/creaVtk/MeshManagerModel.h b/lib/creaVtk/MeshManagerModel.h index f981c87..b74204c 100644 --- a/lib/creaVtk/MeshManagerModel.h +++ b/lib/creaVtk/MeshManagerModel.h @@ -35,7 +35,9 @@ public: ~HistoryHandler(); void CleanHistory(); StateType* Undo(StateType* State); + StateType* UndoKeepCurrent(); StateType* Redo(StateType* State); + StateType* RedoKeepCurrent(); void Save(StateType* State); StateType* GetPrevious(); StateType* GetNext(); @@ -95,11 +97,14 @@ public : MeshManagerModel(std::vector meshList); ~MeshManagerModel(); + void SetHistory(int maxCapacity); void ResetHistory(); void ResetAll(); void SetMeshBase(vtkPolyData* mesh); void SetMeshMemoryMode(vtkPolyData* mesh); + void MeshMemoryModeOn(); + void MeshMemoryModeOff(); void CopySetMeshBase(vtkPolyData* mesh); void ResetMeshTemp(); //void ResetMeshTemp_(); @@ -142,6 +147,7 @@ public : void NextMesh(); void PreviousMesh(); + void SaveMemoryMode(); void Undo(); void Redo(); @@ -167,6 +173,7 @@ private: int currentMesh; int meshId; int lastModified; + bool memoryMode; class ManagerState{ public: @@ -183,6 +190,7 @@ private: void Save(); void RestoreState(ManagerState* state); + void RestoreStateMemoryMode(ManagerState* state); HistoryHandler *history;