X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcreaVtk%2FMeshManagerModel.cpp;h=84713441479ad9dbe9fcfade3da2982d05596f8d;hb=8480ddec6027339a7b6ca2291390eb51b755858d;hp=677727c6057a054b06ecb097298ba36977c1f78a;hpb=4c66cb9b724ca030dfd569b546521f700baadacb;p=creaVtk.git diff --git a/lib/creaVtk/MeshManagerModel.cpp b/lib/creaVtk/MeshManagerModel.cpp index 677727c..8471344 100644 --- a/lib/creaVtk/MeshManagerModel.cpp +++ b/lib/creaVtk/MeshManagerModel.cpp @@ -27,6 +27,163 @@ #include "MeshManagerModel.h" +// +//HISTORY HANDLER +// +template +HistoryHandler::HistoryHandler(int maxElements) +{ + this->maxElements = maxElements; +} +template +HistoryHandler::~HistoryHandler() +{ + CleanHistory(); +} + +template +void HistoryHandler::CleanHistory() +{ + for (T* element : redoStack) + { + 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; + }else{ + delete state; + } + return NULL; +} + +template +T* HistoryHandler::Redo(T* state) +{ + if(state == NULL) + { + return NULL; + } + if(!redoStack.empty()) + { + auto lastElem = redoStack.back(); + redoStack.pop_back(); + undoStack.push_back(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; + } +} + +template +void HistoryHandler::Save(T* state) +{ + undoStack.push_back(state); + if(undoStack.size() > maxElements) + { + T* frontDel = undoStack.front(); + undoStack.pop_front(); + delete frontDel; + } + if(!redoStack.empty()) + { + for (T* element : redoStack) + { + delete element; + } + redoStack.clear(); + } +} + +template +T* HistoryHandler::GetPrevious() +{ + if(!undoStack.empty()) + { + return undoStack.back(); + } + return NULL; +} + +template +T* HistoryHandler::GetNext() +{ + if(!redoStack.empty()) + { + return redoStack.back(); + } + return NULL; +} + +template +int HistoryHandler::UndoSize() +{ + return undoStack.size(); +} + +template +int HistoryHandler::RedoSize() +{ + return redoStack.size(); +} + //////////////////// /////////////////////// MESH MODEL //////////////////// @@ -41,8 +198,10 @@ MeshModel::MeshModel(int id) MeshModel::MeshModel(vtkPolyData* mesh, int id) { - if(mesh != NULL){ - _meshBase = mesh; + if(mesh != NULL) + { + _meshBase = vtkPolyData::New(); + _meshBase->DeepCopy(mesh); _meshTemp = vtkPolyData::New(); _meshTemp->DeepCopy(_meshBase); _meshId = id; @@ -50,11 +209,28 @@ MeshModel::MeshModel(vtkPolyData* mesh, int id) } } -MeshModel::~MeshModel(){ - if(_meshBase != NULL){ +MeshModel::MeshModel(MeshModel* meshModel) +{ + _meshBase = NULL; + _meshTemp = NULL; + if(meshModel->GetMeshBase() != NULL) + { + _meshBase = vtkPolyData::New(); + _meshBase->DeepCopy(meshModel->GetMeshBase()); + ResetMeshTemp_(); + } + _meshId = meshModel->GetId(); + _name = "mesh-" + std::to_string(meshModel->GetId()); +} + +MeshModel::~MeshModel() +{ + if(_meshBase != NULL) + { _meshBase->Delete(); } - if(_meshTemp != NULL){ + if(_meshTemp != NULL) + { _meshTemp->Delete(); } } @@ -70,7 +246,11 @@ void MeshModel::ResetMeshTemp_() _meshTemp = vtkPolyData::New(); _meshTemp->DeepCopy(_meshBase); } else { - _meshTemp=NULL; + if (_meshTemp!=NULL) + { + _meshTemp->Delete(); + _meshTemp = NULL; + } } } @@ -78,14 +258,28 @@ void MeshModel::SetMeshBase(vtkPolyData* mesh) { if (mesh!=NULL) { - _meshBase = mesh; + if(_meshBase != NULL) + { + _meshBase->Delete(); + } + _meshBase = vtkPolyData::New(); + _meshBase->DeepCopy(mesh); ResetMeshTemp_(); } // if mesh } void MeshModel::SetMeshMemoryMode(vtkPolyData* mesh) { - _meshBase = mesh; + if(_meshBase != NULL) + { + _meshBase->Delete(); + _meshBase = NULL; + } + if(mesh != NULL) + { + _meshBase = vtkPolyData::New(); + _meshBase->DeepCopy(mesh); + } } void MeshModel::ResetMeshTemp() @@ -104,12 +298,12 @@ void MeshModel::CopySetMeshBase(vtkPolyData* mesh) } -vtkPolyData* MeshModel::GetMeshBase() +vtkPolyData* MeshModel::GetMeshBase() { return _meshBase; } -vtkPolyData* MeshModel::GetMeshTemp() +vtkPolyData* MeshModel::GetMeshTemp() { return _meshTemp; } @@ -130,48 +324,91 @@ std::string MeshModel::GetName() MeshManagerModel::MeshManagerModel() { - //MeshModel* firstMesh = new MeshModel(); - //_meshes.push_back(firstMesh); currentMesh = 0; meshId = 0; + history = new HistoryHandler(15); + lastModified = 0; + memoryMode = false; + referencePoint = {0, 0, 0}; + referenceNormal = {0, 0, 1}; } MeshManagerModel::~MeshManagerModel() { DeleteAll(); + history->CleanHistory(); + delete history; } void MeshManagerModel::RefreshOutputs(bool signalBox) // virtual { } -int MeshManagerModel::GetNumberOfMeshes(){ +void MeshManagerModel::SetHistory(int maxCapacity) +{ + if(history != NULL){ + ResetHistory(); + delete history; + } + history = new HistoryHandler(maxCapacity); +} + +void MeshManagerModel::ResetHistory() +{ + history->CleanHistory(); +} + +void MeshManagerModel::SetReferencePoint(std::vector point) +{ + referencePoint = point; +} + +std::vector MeshManagerModel::GetReferencePoint() +{ + return referencePoint; +} + +void MeshManagerModel::SetReferenceNormal(std::vector normal) +{ + referenceNormal = normal; +} + +std::vector MeshManagerModel::GetReferenceNormal() +{ + return referenceNormal; +} + +int MeshManagerModel::GetNumberOfMeshes() +{ return _meshes.size(); } -void MeshManagerModel::AddMesh_(vtkPolyData* mesh){ - if(mesh != NULL){ - MeshModel *meshModel = new MeshModel(mesh, meshId); - _meshes.push_back(meshModel); +void MeshManagerModel::AddMesh_(vtkPolyData* mesh) +{ + if(mesh != NULL) + { + _meshes.push_back(std::make_shared(mesh, meshId)); meshId++; - } - else{ + }else{ printf("PG MeshManagerModel::AddMesh Mesh is null \n"); } } -void MeshManagerModel::AddMesh(vtkPolyData* mesh){ +void MeshManagerModel::AddMesh(vtkPolyData* mesh) +{ + Save(); AddMesh_(mesh); + lastModified = currentMesh; RefreshOutputs(true); } -void MeshManagerModel::AddMeshes_(std::vector meshList){ +void MeshManagerModel::AddMeshes_(std::vector meshList) +{ if(!meshList.empty()) { MeshModel *meshModel; for(int i = 0; i < meshList.size(); i++){ - meshModel = new MeshModel(meshList[i], meshId); - _meshes.push_back(meshModel); + _meshes.push_back(std::make_shared(meshList[i], meshId)); meshId++; } }else{ @@ -179,19 +416,25 @@ void MeshManagerModel::AddMeshes_(std::vector meshList){ } } -void MeshManagerModel::AddMeshes(std::vector meshList){ +void MeshManagerModel::AddMeshes(std::vector meshList) +{ + Save(); AddMeshes_(meshList); + lastModified = currentMesh; RefreshOutputs(true); } -void MeshManagerModel::AddEmptyMesh_(){ - MeshModel *meshModel = new MeshModel(meshId); - _meshes.push_back(meshModel); +void MeshManagerModel::AddEmptyMesh_() +{ + _meshes.push_back(std::make_shared(meshId)); meshId++; } -void MeshManagerModel::AddEmptyMesh(){ +void MeshManagerModel::AddEmptyMesh() +{ + Save(); AddEmptyMesh_(); + lastModified = currentMesh; RefreshOutputs(true); } @@ -199,30 +442,34 @@ void MeshManagerModel::InsertMeshesAtCurrent_(std::vector meshList { if(!meshList.empty()) { - std::vector tmpVect; + std::vector> tmpVect; MeshModel *meshModel; for(int i = 0; i < meshList.size(); i++){ - meshModel = new MeshModel(meshList[i], meshId); - tmpVect.push_back(meshModel); + tmpVect.push_back(std::make_shared(meshList[i], meshId)); meshId++; } _meshes.insert(_meshes.begin() + currentMesh, tmpVect.begin(), tmpVect.end()); }else{ - printf("PG MeshManagerModel::AddMeshes Empty list of meshes \n"); + printf("PG MeshManagerModel::InsertMeshesAtCurrent Empty list of meshes \n"); } } void MeshManagerModel::InsertMeshesAtCurrent(std::vector meshList) { + Save(); InsertMeshesAtCurrent_(meshList); + lastModified = currentMesh; RefreshOutputs(true); } -void MeshManagerModel::SelectMesh(int i) { - if(i >= 0 && i < _meshes.size()){ +void MeshManagerModel::SelectMesh(int i) +{ + if(i >= 0 && i < _meshes.size()) + { int prevCurrent = currentMesh; currentMesh = i; - if(prevCurrent != i){ + if(prevCurrent != i) + { RefreshOutputs(true); } } @@ -231,11 +478,14 @@ void MeshManagerModel::SelectMesh(int i) { } } -void MeshManagerModel::SelectMeshByName(std::string meshName) { - if(!_meshes.empty()){ +void MeshManagerModel::SelectMeshByName(std::string meshName) +{ + if(!_meshes.empty()) + { bool found = false; for(int i = 0; i < _meshes.size() && !found; i++){ - if(_meshes.at(i)->GetName() == meshName){ + if(_meshes.at(i)->GetName() == meshName) + { found = true; SelectMesh(i); } @@ -243,82 +493,113 @@ void MeshManagerModel::SelectMeshByName(std::string meshName) { } } -void MeshManagerModel::DeleteMesh(int position){ - if(position >= 0 && position < _meshes.size()){ - delete _meshes.at(position); +void MeshManagerModel::DeleteMesh_(int position) +{ + if(position >= 0 && position < _meshes.size()) + { _meshes.erase(_meshes.begin() + position); currentMesh = currentMesh + (position <= currentMesh?-1:0); - if(currentMesh < 0){ + if(currentMesh < 0) + { currentMesh = 0; } - RefreshOutputs(true); } } -void MeshManagerModel::DeleteMeshByName(std::string meshName){ - if(!_meshes.empty()){ +void MeshManagerModel::DeleteMesh(int position) +{ + Save(); + DeleteMesh_(position); + lastModified = currentMesh; + RefreshOutputs(true); +} + +void MeshManagerModel::DeleteMeshByName(std::string meshName) +{ + if(!_meshes.empty()) + { bool found = false; for(int i = 0; i < _meshes.size() && !found; i++){ - if(_meshes.at(i)->GetName() == meshName){ + if(_meshes.at(i)->GetName() == meshName) + { found = true; - delete _meshes.at(i); - _meshes.erase(_meshes.begin() + i); - currentMesh = currentMesh + (i <= currentMesh?-1:0); - if(currentMesh < 0){ - currentMesh = 0; - } + DeleteMesh_(i); RefreshOutputs(true); } } } } -void MeshManagerModel::DeleteCurrentMesh(){ - if(!_meshes.empty()){ - delete _meshes.at(currentMesh); - _meshes.erase(_meshes.begin() + currentMesh); - currentMesh--; - if(currentMesh < 0){ - currentMesh = 0; - } +void MeshManagerModel::DeleteCurrentMesh() +{ + if(!_meshes.empty()) + { + Save(); + DeleteMesh_(currentMesh); + lastModified = currentMesh; RefreshOutputs(true); } } -void MeshManagerModel::DeleteAll(){ - if(!_meshes.empty()){ - for (MeshModel* element : _meshes) - { - delete element; - } +void MeshManagerModel::ReplaceMesh(std::vector meshList) +{ + Save(); + if(GetNumberOfMeshes() >= 1) + { + DeleteMesh_(currentMesh); + } + InsertMeshesAtCurrent_(meshList); + lastModified = currentMesh; + RefreshOutputs(true); +} + +void MeshManagerModel::DeleteAll_() +{ + if(!_meshes.empty()) + { + currentMesh = 0; _meshes.clear(); RefreshOutputs(true); } } -void MeshManagerModel::NextMesh(){ +void MeshManagerModel::DeleteAll() +{ + Save(); + DeleteAll_(); + lastModified = currentMesh; + RefreshOutputs(true); +} + +void MeshManagerModel::NextMesh() +{ currentMesh++; - if(currentMesh >= _meshes.size()){ + if(currentMesh >= _meshes.size()) + { currentMesh = _meshes.size()-1; } RefreshOutputs(true); } -void MeshManagerModel::PreviousMesh(){ +void MeshManagerModel::PreviousMesh() +{ currentMesh--; - if(currentMesh < 0){ + if(currentMesh < 0) + { currentMesh = 0; } RefreshOutputs(true); } -MeshModel* MeshManagerModel::GetMeshModel(){ +std::shared_ptr MeshManagerModel::GetMeshModel() +{ return _meshes.at(currentMesh); } vtkPolyData* MeshManagerModel::GetMeshBase() { - if(!_meshes.empty()){ + if(!_meshes.empty()) + { return _meshes.at(currentMesh)->GetMeshBase(); } else{ @@ -328,7 +609,8 @@ vtkPolyData* MeshManagerModel::GetMeshBase() vtkPolyData* MeshManagerModel::GetMeshTemp() { - if(!_meshes.empty()){ + if(!_meshes.empty()) + { return _meshes.at(currentMesh)->GetMeshTemp(); } else{ @@ -338,45 +620,63 @@ vtkPolyData* MeshManagerModel::GetMeshTemp() void MeshManagerModel::SetMeshBase(vtkPolyData* mesh) { - if(!_meshes.empty()){ + if(!_meshes.empty()) + { + Save(); + _meshes.at(currentMesh) = std::make_shared(_meshes.at(currentMesh).get()); _meshes.at(currentMesh)->SetMeshBase(mesh); + lastModified = currentMesh; RefreshOutputs(true); }else{ - printf("PG MeshManagerModel::SetMeshMemoryMode Mesh vector is empty \n"); + printf("PG MeshManagerModel::SetMeshBase Mesh vector is empty \n"); } } +void MeshManagerModel::MeshMemoryModeOn() +{ + memoryMode = true; +} + +void MeshManagerModel::MeshMemoryModeOff() +{ + memoryMode = false; +} + void MeshManagerModel::SetMeshMemoryMode(vtkPolyData* mesh) { - //if(!_meshes.empty()){ - if(_meshes.size() > 1){ - DeleteAll(); + if(_meshes.size() > 1) + { + DeleteAll_(); } - if(_meshes.size() == 0){ + if(_meshes.size() == 0) + { AddEmptyMesh_(); } _meshes.at(currentMesh)->SetMeshMemoryMode(mesh); + ResetHistory(); + SaveMemoryMode(); RefreshOutputs(true); - //}else{ - // printf("PG MeshManagerModel::SetMeshMemoryMode Mesh vector is empty \n"); - //} } void MeshManagerModel::ResetMeshTemp() { - if(!_meshes.empty()){ + if(!_meshes.empty()) + { _meshes.at(currentMesh)->ResetMeshTemp(); RefreshOutputs(true); }else{ printf("PG MeshManagerModel::ResetMeshTemp Mesh vector is empty \n"); } - } void MeshManagerModel::CopySetMeshBase(vtkPolyData* mesh) { - if(!_meshes.empty()){ + if(!_meshes.empty()) + { + Save(); + _meshes.at(currentMesh) = std::make_shared(_meshes.at(currentMesh).get()); _meshes.at(currentMesh)->CopySetMeshBase(mesh); + lastModified = currentMesh; RefreshOutputs(true); } else{ @@ -392,3 +692,136 @@ std::vector MeshManagerModel::GetMeshNames() } return names; } + +std::vector MeshManagerModel::GetAllPolyDatas() +{ + std::vector polydatas; + for(int i = 0; i < _meshes.size(); i++){ + polydatas.push_back(_meshes.at(i)->GetMeshBase()); + } + return polydatas; +} + +int MeshManagerModel::GetCurrentMesh() +{ + return currentMesh; +} + +void MeshManagerModel::Undo() +{ + if(history->UndoSize() > 0) + { + 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) + { + 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)); +} + +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, referencePoint, referenceNormal)); + } + else{ + printf("PG MeshManagerModel::SaveMemoryMode WARNING Mesh vector has invalid size or memoryMode is not set \n"); + } +} + +void MeshManagerModel::RestoreState(ManagerState* state) +{ + if(state != NULL) + { + _meshes = state->GetMeshes(); + 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(); + referencePoint = state->GetReferencePoint(); + referenceNormal = state->referenceNormal; + }else{ + printf("PG MeshManagerModel::RestoreStateMemoryMode WARNING Mesh vector has invalid size or state is NULL\n"); + } +} + +// +//Manager State +// +MeshManagerModel::ManagerState::ManagerState(std::vector> meshesToSave, int meshId, int modifiedPos) +{ + savedMeshes = meshesToSave; + savedId = meshId; + savedModifiedPos = modifiedPos; +} + +MeshManagerModel::ManagerState::ManagerState(std::vector> meshesToSave, int meshId, int modifiedPos, std::vector refPoint, std::vector refNormal) +{ + savedMeshes = meshesToSave; + savedId = meshId; + savedModifiedPos = modifiedPos; + referencePoint = refPoint; + referenceNormal = refNormal; +} + +MeshManagerModel::ManagerState::~ManagerState() +{ + savedMeshes.clear(); +} + +std::vector>& MeshManagerModel::ManagerState::GetMeshes() +{ + return savedMeshes; +} + +int MeshManagerModel::ManagerState::GetMeshId() +{ + return savedId; +} +int MeshManagerModel::ManagerState::GetModifiedPos() +{ + return savedModifiedPos; +} + +std::vector& MeshManagerModel::ManagerState::GetReferencePoint() +{ + return referencePoint; +}