]> Creatis software - creaVtk.git/blobdiff - lib/creaVtk/MeshManagerModel.cpp
#3522 AddImageTo vector from creaRigidRegistration::PackRecalage to bbtk::vtk
[creaVtk.git] / lib / creaVtk / MeshManagerModel.cpp
index 6af6e932b42bbd438df149c21b3ff977ebb7a03b..84713441479ad9dbe9fcfade3da2982d05596f8d 100644 (file)
@@ -48,21 +48,27 @@ void HistoryHandler<T>::CleanHistory()
        {
                delete element;
        }
+       redoStack.clear();
        for (T* element : undoStack)
        {
                delete element;
        }
+       undoStack.clear();
 }
 
 template <class T>
 T* HistoryHandler<T>::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<T>::Undo(T* state)
 template <class T>
 T* HistoryHandler<T>::Redo(T* state)
 {
+       if(state == NULL)
+       {
+               return NULL;
+       }
        if(!redoStack.empty())
        {
                auto lastElem = redoStack.back();
@@ -80,14 +90,58 @@ T* HistoryHandler<T>::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 <class T>
+T* HistoryHandler<T>::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 <class T>
+T* HistoryHandler<T>::RedoKeepCurrent()
+{
+       if(!redoStack.empty())
+       {
+               auto lastElem = redoStack.back();
+               redoStack.pop_back();
+               undoStack.push_back(lastElem);
+               return undoStack.back();
+       }else{
+               return NULL;
        }
-       return NULL;
 }
 
 template <class T>
 void HistoryHandler<T>::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)
@@ -101,7 +155,8 @@ void HistoryHandler<T>::Save(T* state)
 template <class T>
 T* HistoryHandler<T>::GetPrevious()
 {
-       if(!undoStack.empty()){ 
+       if(!undoStack.empty())
+       {       
                return undoStack.back();
        }
        return NULL;
@@ -110,7 +165,8 @@ T* HistoryHandler<T>::GetPrevious()
 template <class T>
 T* HistoryHandler<T>::GetNext()
 {
-       if(!redoStack.empty()){ 
+       if(!redoStack.empty())
+       {       
                return redoStack.back();
        }
        return NULL;
@@ -142,8 +198,9 @@ MeshModel::MeshModel(int id)
 
 MeshModel::MeshModel(vtkPolyData* mesh, int id)
 {
-       if(mesh != NULL){       
-               _meshBase = vtkPolyData::New();//mesh;
+       if(mesh != NULL)
+       {
+               _meshBase = vtkPolyData::New();
                _meshBase->DeepCopy(mesh);
                _meshTemp = vtkPolyData::New();
                _meshTemp->DeepCopy(_meshBase);
@@ -166,11 +223,14 @@ MeshModel::MeshModel(MeshModel* meshModel)
        _name = "mesh-" + std::to_string(meshModel->GetId());
 }
 
-MeshModel::~MeshModel(){
-       if(_meshBase != NULL){
+MeshModel::~MeshModel()
+{
+       if(_meshBase != NULL)
+       {
                _meshBase->Delete();
        }
-       if(_meshTemp != NULL){
+       if(_meshTemp != NULL)
+       {
                _meshTemp->Delete();
        }
 }
@@ -198,7 +258,8 @@ void MeshModel::SetMeshBase(vtkPolyData* mesh)
 {
     if (mesh!=NULL)
     {
-       if(_meshBase != NULL){
+       if(_meshBase != NULL)
+       {
                _meshBase->Delete();
        }
         _meshBase = vtkPolyData::New();
@@ -265,23 +326,56 @@ MeshManagerModel::MeshManagerModel()
 {
        currentMesh = 0;
        meshId = 0;
-       history = new HistoryHandler<ManagerState>(20);
+       history = new HistoryHandler<ManagerState>(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
 {
 }
 
+void MeshManagerModel::SetHistory(int maxCapacity)
+{
+       if(history != NULL){    
+               ResetHistory();
+               delete history;
+       }
+       history = new HistoryHandler<ManagerState>(maxCapacity);
+}
+
 void MeshManagerModel::ResetHistory()
 {
        history->CleanHistory();
-       //Save();
+}
+
+void MeshManagerModel::SetReferencePoint(std::vector<double> point)
+{
+       referencePoint = point;
+}
+
+std::vector<double> MeshManagerModel::GetReferencePoint()
+{
+       return referencePoint;
+}
+
+void MeshManagerModel::SetReferenceNormal(std::vector<double> normal)
+{
+       referenceNormal = normal;
+}
+
+std::vector<double> MeshManagerModel::GetReferenceNormal()
+{
+       return referenceNormal;
 }
 
 int MeshManagerModel::GetNumberOfMeshes()
@@ -291,11 +385,11 @@ int MeshManagerModel::GetNumberOfMeshes()
 
 void MeshManagerModel::AddMesh_(vtkPolyData* mesh)
 {
-       if(mesh != NULL){
+       if(mesh != NULL)
+       {
                _meshes.push_back(std::make_shared<MeshModel>(mesh, meshId));
                meshId++;
-       }
-       else{
+       }else{
                printf("PG MeshManagerModel::AddMesh Mesh is null \n");
        }
 }
@@ -370,10 +464,12 @@ void MeshManagerModel::InsertMeshesAtCurrent(std::vector<vtkPolyData*> meshList)
 
 void MeshManagerModel::SelectMesh(int i) 
 {
-       if(i >= 0 && i < _meshes.size()){
+       if(i >= 0 && i < _meshes.size())
+       {
                int prevCurrent = currentMesh;
                currentMesh = i;
-               if(prevCurrent != i){
+               if(prevCurrent != i)
+               {
                        RefreshOutputs(true);           
                }
        }
@@ -384,10 +480,12 @@ void MeshManagerModel::SelectMesh(int i)
 
 void MeshManagerModel::SelectMeshByName(std::string meshName) 
 {
-       if(!_meshes.empty()){
+       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);
                        }
@@ -397,10 +495,12 @@ void MeshManagerModel::SelectMeshByName(std::string meshName)
 
 void MeshManagerModel::DeleteMesh_(int position)
 {
-       if(position >= 0 && position < _meshes.size()){
+       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;
                }
        }
@@ -416,10 +516,12 @@ void MeshManagerModel::DeleteMesh(int position)
 
 void MeshManagerModel::DeleteMeshByName(std::string meshName)
 {
-       if(!_meshes.empty()){
+       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;
                                DeleteMesh_(i);
                                RefreshOutputs(true);
@@ -430,7 +532,8 @@ void MeshManagerModel::DeleteMeshByName(std::string meshName)
 
 void MeshManagerModel::DeleteCurrentMesh()
 {
-       if(!_meshes.empty()){
+       if(!_meshes.empty())
+       {
                Save();
                DeleteMesh_(currentMesh);
                lastModified = currentMesh;
@@ -471,7 +574,8 @@ void MeshManagerModel::DeleteAll()
 void MeshManagerModel::NextMesh()
 {
        currentMesh++;
-       if(currentMesh >= _meshes.size()){
+       if(currentMesh >= _meshes.size())
+       {
                currentMesh = _meshes.size()-1;
        }
        RefreshOutputs(true);
@@ -480,7 +584,8 @@ void MeshManagerModel::NextMesh()
 void MeshManagerModel::PreviousMesh()
 {
        currentMesh--;
-       if(currentMesh < 0){
+       if(currentMesh < 0)
+       {
                currentMesh = 0;
        }
        RefreshOutputs(true);
@@ -493,7 +598,8 @@ std::shared_ptr<MeshModel> MeshManagerModel::GetMeshModel()
 
 vtkPolyData*  MeshManagerModel::GetMeshBase()
 {
-       if(!_meshes.empty()){
+       if(!_meshes.empty())
+       {
                return _meshes.at(currentMesh)->GetMeshBase();
        }
        else{
@@ -503,7 +609,8 @@ vtkPolyData*  MeshManagerModel::GetMeshBase()
 
 vtkPolyData*  MeshManagerModel::GetMeshTemp()
 {
-       if(!_meshes.empty()){
+       if(!_meshes.empty())
+       {
                return _meshes.at(currentMesh)->GetMeshTemp();
        }
        else{
@@ -513,7 +620,8 @@ vtkPolyData*  MeshManagerModel::GetMeshTemp()
 
 void MeshManagerModel::SetMeshBase(vtkPolyData* mesh)
 {
-    if(!_meshes.empty()){
+    if(!_meshes.empty())
+    {
         Save();
         _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
         _meshes.at(currentMesh)->SetMeshBase(mesh);
@@ -524,6 +632,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)
@@ -535,6 +653,8 @@ void MeshManagerModel::SetMeshMemoryMode(vtkPolyData* mesh)
                AddEmptyMesh_();
        }
        _meshes.at(currentMesh)->SetMeshMemoryMode(mesh);
+       ResetHistory();
+       SaveMemoryMode();
        RefreshOutputs(true);
 }
 
@@ -589,25 +709,48 @@ int MeshManagerModel::GetCurrentMesh()
 
 void MeshManagerModel::Undo()
 {      
-       if(history->UndoSize() > 0){    
-               RestoreState(history->Undo(new ManagerState(_meshes, meshId, lastModified)));
-               RefreshOutputs(true);
+       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)
-       {       
-               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<std::shared_ptr<MeshModel>> savedMesh;
+               savedMesh.push_back(std::make_shared<MeshModel>(_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)
@@ -618,7 +761,25 @@ void MeshManagerModel::RestoreState(ManagerState* state)
                meshId = state->GetMeshId();
                currentMesh = state->GetModifiedPos();
                lastModified = state->GetModifiedPos();
-//             cout << "PG MeshManagerModel::RestoreState currentMesh: " << currentMesh << endl;
+               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");
        }
 }
 
@@ -632,8 +793,18 @@ MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshMod
        savedModifiedPos = modifiedPos;
 }
 
+MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int modifiedPos, std::vector<double> refPoint, std::vector<double> refNormal)
+{
+       savedMeshes = meshesToSave;
+       savedId = meshId;
+       savedModifiedPos = modifiedPos;
+       referencePoint = refPoint;
+       referenceNormal = refNormal;
+}
+
 MeshManagerModel::ManagerState::~ManagerState()
 {
+       savedMeshes.clear();
 }
 
 std::vector<std::shared_ptr<MeshModel>>& MeshManagerModel::ManagerState::GetMeshes()
@@ -650,3 +821,7 @@ int MeshManagerModel::ManagerState::GetModifiedPos()
        return savedModifiedPos;
 }
 
+std::vector<double>& MeshManagerModel::ManagerState::GetReferencePoint()
+{
+       return referencePoint;
+}