]> Creatis software - creaVtk.git/blob - lib/creaVtk/MeshManagerModel.cpp
#3527 Deformation Undo-Redo fixes
[creaVtk.git] / lib / creaVtk / MeshManagerModel.cpp
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 #                        pour la Sante)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 #  This software is governed by the CeCILL-B license under French law and
11 #  abiding by the rules of distribution of free software. You can  use,
12 #  modify and/ or redistribute the software under the terms of the CeCILL-B
13 #  license as circulated by CEA, CNRS and INRIA at the following URL
14 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 #  or in the file LICENSE.txt.
16 #
17 #  As a counterpart to the access to the source code and  rights to copy,
18 #  modify and redistribute granted by the license, users are provided only
19 #  with a limited warranty  and the software's author,  the holder of the
20 #  economic rights,  and the successive licensors  have only  limited
21 #  liability.
22 #
23 #  The fact that you are presently reading this means that you have had
24 #  knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
26 */
27
28 #include "MeshManagerModel.h"
29
30 //
31 //HISTORY HANDLER
32 //
33 template <class T>
34 HistoryHandler<T>::HistoryHandler(int maxElements)
35 {
36         this->maxElements = maxElements;
37 }
38 template <class T>
39 HistoryHandler<T>::~HistoryHandler()
40 {
41         CleanHistory();
42 }
43
44 template <class T>
45 void HistoryHandler<T>::CleanHistory()
46 {
47         for (T* element : redoStack)
48         {
49                 delete element;
50         }
51         redoStack.clear();
52         for (T* element : undoStack)
53         {
54                 delete element;
55         }
56         undoStack.clear();
57 }
58
59 template <class T>
60 T* HistoryHandler<T>::Undo(T* state)
61 {
62         if(state == NULL)
63         {
64                 return NULL;
65         }
66         if(!undoStack.empty())
67         {
68                 auto lastElem = undoStack.back();
69                 undoStack.pop_back();
70                 redoStack.push_back(state);
71                 return lastElem;
72         }else{
73                 delete state;
74         }
75         return NULL;
76 }
77
78 template <class T>
79 T* HistoryHandler<T>::Redo(T* state)
80 {
81         if(state == NULL)
82         {
83                 return NULL;
84         }
85         if(!redoStack.empty())
86         {
87                 auto lastElem = redoStack.back();
88                 redoStack.pop_back();
89                 undoStack.push_back(state);
90                 return lastElem;
91         }else{
92                 delete state;
93                 return NULL;
94         }
95 }
96
97 /**
98 * To be used with RedoKeepCurrent
99 * Will always maintain the current state in the undo stack as the first element
100 * Useful when states are saved after actions and the initial state is saved.
101 */
102 template <class T>
103 T* HistoryHandler<T>::UndoKeepCurrent()
104 {
105         if(undoStack.size() > 1)
106         {
107                 auto lastElem = undoStack.back();
108                 undoStack.pop_back();
109                 redoStack.push_back(lastElem);
110                 return undoStack.back();
111         }else{
112                 return NULL;
113         }
114 }
115
116 /**
117 * To be used with UndoKeepCurrent
118 * Will always maintain the current state in the undo stack as the first element
119 * Useful when states are saved after actions and the initial state is saved.
120 */
121 template <class T>
122 T* HistoryHandler<T>::RedoKeepCurrent()
123 {
124         if(!redoStack.empty())
125         {
126                 auto lastElem = redoStack.back();
127                 redoStack.pop_back();
128                 undoStack.push_back(lastElem);
129                 return undoStack.back();
130         }else{
131                 return NULL;
132         }
133 }
134
135 template <class T>
136 void HistoryHandler<T>::Save(T* state)
137 {
138         undoStack.push_back(state);
139         if(undoStack.size() > maxElements)
140         {
141                 T* frontDel = undoStack.front();
142                 undoStack.pop_front();
143                 delete frontDel;
144         }
145         if(!redoStack.empty())
146         {
147                 for (T* element : redoStack)
148                 {
149                         delete element;
150                 } 
151                 redoStack.clear();
152         }
153 }
154
155 template <class T>
156 T* HistoryHandler<T>::GetPrevious()
157 {
158         if(!undoStack.empty())
159         {       
160                 return undoStack.back();
161         }
162         return NULL;
163 }
164
165 template <class T>
166 T* HistoryHandler<T>::GetNext()
167 {
168         if(!redoStack.empty())
169         {       
170                 return redoStack.back();
171         }
172         return NULL;
173 }
174
175 template <class T>
176 int HistoryHandler<T>::UndoSize()
177 {
178         return undoStack.size();
179 }
180
181 template <class T>
182 int HistoryHandler<T>::RedoSize()
183 {
184         return redoStack.size();
185 }
186
187 ////////////////////
188 /////////////////////// MESH MODEL
189 ////////////////////
190
191 MeshModel::MeshModel(int id)
192 {
193         _meshBase = NULL;
194     _meshTemp = NULL;
195     _meshId = id;
196     _name = "mesh-" + std::to_string(id);
197 }
198
199 MeshModel::MeshModel(vtkPolyData* mesh, int id)
200 {
201         if(mesh != NULL)
202         {
203                 _meshBase = vtkPolyData::New();
204                 _meshBase->DeepCopy(mesh);
205                 _meshTemp = vtkPolyData::New();
206                 _meshTemp->DeepCopy(_meshBase);
207                 _meshId = id;
208         _name = "mesh-" + std::to_string(id);
209         }
210 }
211
212 MeshModel::MeshModel(MeshModel* meshModel)
213 {
214         _meshBase = NULL;
215     _meshTemp = NULL;
216         if(meshModel->GetMeshBase() != NULL)
217         {
218                 _meshBase = vtkPolyData::New();
219                 _meshBase->DeepCopy(meshModel->GetMeshBase());
220                 ResetMeshTemp_();
221         }
222         _meshId = meshModel->GetId();
223         _name = "mesh-" + std::to_string(meshModel->GetId());
224 }
225
226 MeshModel::~MeshModel()
227 {
228         if(_meshBase != NULL)
229         {
230                 _meshBase->Delete();
231         }
232         if(_meshTemp != NULL)
233         {
234                 _meshTemp->Delete();
235         }
236 }
237
238 void MeshModel::ResetMeshTemp_()
239 {
240     if (_meshBase!=NULL)
241     {
242         if (_meshTemp!=NULL)
243         {
244             _meshTemp->Delete();
245         } // if
246         _meshTemp = vtkPolyData::New();
247         _meshTemp->DeepCopy(_meshBase);
248     } else {
249         if (_meshTemp!=NULL)
250         {
251             _meshTemp->Delete();
252             _meshTemp = NULL;
253         }
254     }
255 }
256
257 void MeshModel::SetMeshBase(vtkPolyData* mesh)
258 {
259     if (mesh!=NULL)
260     {
261         if(_meshBase != NULL)
262         {
263                 _meshBase->Delete();
264         }
265         _meshBase = vtkPolyData::New();
266         _meshBase->DeepCopy(mesh);
267         ResetMeshTemp_();
268     } // if mesh
269 }
270
271 void MeshModel::SetMeshMemoryMode(vtkPolyData* mesh)
272 {
273         if(_meshBase != NULL)
274         {
275                 _meshBase->Delete();
276                 _meshBase = NULL;
277         }
278         if(mesh != NULL)
279         {
280                 _meshBase = vtkPolyData::New();
281                 _meshBase->DeepCopy(mesh);
282         }
283 }
284
285 void MeshModel::ResetMeshTemp()
286 {
287     ResetMeshTemp_();
288 }
289
290 void MeshModel::CopySetMeshBase(vtkPolyData* mesh)
291 {
292     if (mesh!=NULL)
293     {
294       vtkPolyData *newMesh = vtkPolyData::New();
295       newMesh->DeepCopy( mesh );
296       SetMeshBase(newMesh);
297     } // if mesh
298 }
299
300
301 vtkPolyData* MeshModel::GetMeshBase()
302 {
303    return _meshBase;
304 }
305
306 vtkPolyData* MeshModel::GetMeshTemp()
307 {
308    return _meshTemp;
309 }
310
311 int MeshModel::GetId()
312 {
313         return _meshId;
314 }
315
316 std::string MeshModel::GetName()
317 {
318         return _name;
319 }
320
321 ////////////////////
322 /////////////////////// MESH MANAGER
323 ////////////////////
324
325 MeshManagerModel::MeshManagerModel()
326 {
327         currentMesh = 0;
328         meshId = 0;
329         history = new HistoryHandler<ManagerState>(15);
330         lastModified = 0;
331         memoryMode = false;
332         referencePoint = {0, 0, 0};
333 }
334
335 MeshManagerModel::~MeshManagerModel()
336 {
337         DeleteAll();
338         history->CleanHistory();
339         delete history;
340 }
341
342 void MeshManagerModel::RefreshOutputs(bool signalBox) // virtual
343 {
344 }
345
346 void MeshManagerModel::SetHistory(int maxCapacity)
347 {
348         if(history != NULL){    
349                 ResetHistory();
350                 delete history;
351         }
352         history = new HistoryHandler<ManagerState>(maxCapacity);
353 }
354
355 void MeshManagerModel::ResetHistory()
356 {
357         history->CleanHistory();
358 }
359
360 void MeshManagerModel::SetReferencePoint(std::vector<double> point)
361 {
362         referencePoint = point;
363 }
364
365 std::vector<double> MeshManagerModel::GetReferencePoint()
366 {
367         return referencePoint;
368 }
369
370 int MeshManagerModel::GetNumberOfMeshes()
371 {
372         return _meshes.size();
373 }
374
375 void MeshManagerModel::AddMesh_(vtkPolyData* mesh)
376 {
377         if(mesh != NULL)
378         {
379                 _meshes.push_back(std::make_shared<MeshModel>(mesh, meshId));
380                 meshId++;
381         }else{
382                 printf("PG MeshManagerModel::AddMesh Mesh is null \n");
383         }
384 }
385
386 void MeshManagerModel::AddMesh(vtkPolyData* mesh)
387 {
388         Save();
389         AddMesh_(mesh);
390         lastModified = currentMesh;
391         RefreshOutputs(true);
392 }
393
394 void MeshManagerModel::AddMeshes_(std::vector<vtkPolyData*> meshList)
395 {
396         if(!meshList.empty())
397         {
398                 MeshModel *meshModel;
399                 for(int i = 0; i < meshList.size(); i++){
400                         _meshes.push_back(std::make_shared<MeshModel>(meshList[i], meshId));
401                         meshId++;
402                 }
403         }else{
404                 printf("PG MeshManagerModel::AddMeshes Empty list of meshes \n");
405         }
406 }
407
408 void MeshManagerModel::AddMeshes(std::vector<vtkPolyData*> meshList)
409 {
410         Save();
411         AddMeshes_(meshList);
412         lastModified = currentMesh;
413         RefreshOutputs(true);
414 }
415
416 void MeshManagerModel::AddEmptyMesh_()
417 {
418         _meshes.push_back(std::make_shared<MeshModel>(meshId));
419         meshId++;
420 }
421
422 void MeshManagerModel::AddEmptyMesh()
423 {
424         Save();
425         AddEmptyMesh_();
426         lastModified = currentMesh;
427         RefreshOutputs(true);
428 }
429
430 void MeshManagerModel::InsertMeshesAtCurrent_(std::vector<vtkPolyData*> meshList)
431 {
432         if(!meshList.empty())
433         {
434                 std::vector<std::shared_ptr<MeshModel>> tmpVect;
435                 MeshModel *meshModel;
436                 for(int i = 0; i < meshList.size(); i++){
437                         tmpVect.push_back(std::make_shared<MeshModel>(meshList[i], meshId));
438                         meshId++;
439                 }
440                 _meshes.insert(_meshes.begin() + currentMesh, tmpVect.begin(), tmpVect.end());
441         }else{
442                 printf("PG MeshManagerModel::InsertMeshesAtCurrent Empty list of meshes \n");
443         }
444 }
445
446 void MeshManagerModel::InsertMeshesAtCurrent(std::vector<vtkPolyData*> meshList)
447 {
448         Save();
449         InsertMeshesAtCurrent_(meshList);
450         lastModified = currentMesh;
451         RefreshOutputs(true);
452 }
453
454 void MeshManagerModel::SelectMesh(int i) 
455 {
456         if(i >= 0 && i < _meshes.size())
457         {
458                 int prevCurrent = currentMesh;
459                 currentMesh = i;
460                 if(prevCurrent != i)
461                 {
462                         RefreshOutputs(true);           
463                 }
464         }
465         else{
466                 printf("PG MeshManagerModel::SelectMesh index out of bounds \n");
467         }
468 }
469
470 void MeshManagerModel::SelectMeshByName(std::string meshName) 
471 {
472         if(!_meshes.empty())
473         {
474                 bool found = false;
475                 for(int i = 0; i < _meshes.size() && !found; i++){
476                         if(_meshes.at(i)->GetName() == meshName)
477                         {
478                                 found = true;
479                                 SelectMesh(i);
480                         }
481                 }
482         }
483 }
484
485 void MeshManagerModel::DeleteMesh_(int position)
486 {
487         if(position >= 0 && position < _meshes.size())
488         {
489                 _meshes.erase(_meshes.begin() + position);
490                 currentMesh = currentMesh + (position <= currentMesh?-1:0);
491                 if(currentMesh < 0)
492                 {
493                         currentMesh = 0;
494                 }
495         }
496 }
497
498 void MeshManagerModel::DeleteMesh(int position)
499 {
500         Save();
501         DeleteMesh_(position);
502         lastModified = currentMesh;
503         RefreshOutputs(true);
504 }
505
506 void MeshManagerModel::DeleteMeshByName(std::string meshName)
507 {
508         if(!_meshes.empty())
509         {
510                 bool found = false;
511                 for(int i = 0; i < _meshes.size() && !found; i++){
512                         if(_meshes.at(i)->GetName() == meshName)
513                         {
514                                 found = true;
515                                 DeleteMesh_(i);
516                                 RefreshOutputs(true);
517                         }
518                 }
519         }
520 }
521
522 void MeshManagerModel::DeleteCurrentMesh()
523 {
524         if(!_meshes.empty())
525         {
526                 Save();
527                 DeleteMesh_(currentMesh);
528                 lastModified = currentMesh;
529                 RefreshOutputs(true);
530         }
531 }
532
533 void MeshManagerModel::ReplaceMesh(std::vector<vtkPolyData*> meshList)
534 {
535         Save();
536         if(GetNumberOfMeshes() >= 1)
537         {
538                 DeleteMesh_(currentMesh);
539         }
540         InsertMeshesAtCurrent_(meshList);
541         lastModified = currentMesh;
542         RefreshOutputs(true);
543 }
544
545 void MeshManagerModel::DeleteAll_()
546 {
547         if(!_meshes.empty())
548         {
549                 currentMesh = 0;
550                 _meshes.clear();
551                 RefreshOutputs(true);
552         }
553 }
554
555 void MeshManagerModel::DeleteAll()
556 {
557         Save();
558         DeleteAll_();
559         lastModified = currentMesh;
560         RefreshOutputs(true);
561 }
562
563 void MeshManagerModel::NextMesh()
564 {
565         currentMesh++;
566         if(currentMesh >= _meshes.size())
567         {
568                 currentMesh = _meshes.size()-1;
569         }
570         RefreshOutputs(true);
571 }
572
573 void MeshManagerModel::PreviousMesh()
574 {
575         currentMesh--;
576         if(currentMesh < 0)
577         {
578                 currentMesh = 0;
579         }
580         RefreshOutputs(true);
581 }
582
583 std::shared_ptr<MeshModel> MeshManagerModel::GetMeshModel()
584 {
585         return _meshes.at(currentMesh);
586 }
587
588 vtkPolyData*  MeshManagerModel::GetMeshBase()
589 {
590         if(!_meshes.empty())
591         {
592                 return _meshes.at(currentMesh)->GetMeshBase();
593         }
594         else{
595                 return NULL;
596         }
597 }
598
599 vtkPolyData*  MeshManagerModel::GetMeshTemp()
600 {
601         if(!_meshes.empty())
602         {
603                 return _meshes.at(currentMesh)->GetMeshTemp();
604         }
605         else{
606                 return NULL;
607         }
608 }
609
610 void MeshManagerModel::SetMeshBase(vtkPolyData* mesh)
611 {
612     if(!_meshes.empty())
613     {
614         Save();
615         _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
616         _meshes.at(currentMesh)->SetMeshBase(mesh);
617         lastModified = currentMesh;
618         RefreshOutputs(true);
619     }else{
620         printf("PG MeshManagerModel::SetMeshBase Mesh vector is empty \n");
621     }
622 }
623
624 void MeshManagerModel::MeshMemoryModeOn()
625 {
626         memoryMode = true;
627 }
628
629 void MeshManagerModel::MeshMemoryModeOff()
630 {
631         memoryMode = false;
632 }
633
634 void MeshManagerModel::SetMeshMemoryMode(vtkPolyData* mesh)
635 {
636         if(_meshes.size() > 1)
637         {
638                 DeleteAll_();
639         }
640         if(_meshes.size() == 0)
641         {
642                 AddEmptyMesh_();
643         }
644         _meshes.at(currentMesh)->SetMeshMemoryMode(mesh);
645         ResetHistory();
646         SaveMemoryMode();
647         RefreshOutputs(true);
648 }
649
650 void MeshManagerModel::ResetMeshTemp()
651 {
652         if(!_meshes.empty())
653         {
654         _meshes.at(currentMesh)->ResetMeshTemp();
655         RefreshOutputs(true);
656     }else{
657         printf("PG MeshManagerModel::ResetMeshTemp Mesh vector is empty \n");
658     }
659 }
660
661 void MeshManagerModel::CopySetMeshBase(vtkPolyData* mesh)
662 {
663         if(!_meshes.empty())
664         {
665                 Save();
666                 _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
667                 _meshes.at(currentMesh)->CopySetMeshBase(mesh);
668                 lastModified = currentMesh;
669                 RefreshOutputs(true);
670         }
671         else{
672                 printf("PG MeshManagerModel::CopySetMeshBase Mesh vector is empty \n");
673         }
674 }
675
676 std::vector<std::string> MeshManagerModel::GetMeshNames()
677 {
678         std::vector<std::string> names;
679         for(int i = 0; i < _meshes.size(); i++){
680                 names.push_back(_meshes.at(i)->GetName());
681         }
682         return names;
683 }
684
685 std::vector<vtkPolyData*> MeshManagerModel::GetAllPolyDatas()
686 {
687         std::vector<vtkPolyData*> polydatas;
688         for(int i = 0; i < _meshes.size(); i++){
689                 polydatas.push_back(_meshes.at(i)->GetMeshBase());
690         }
691         return polydatas;
692 }
693
694 int MeshManagerModel::GetCurrentMesh()
695 {
696         return currentMesh;
697 }
698
699 void MeshManagerModel::Undo()
700 {       
701         if(history->UndoSize() > 0)
702         {
703                 if(memoryMode == false){
704                         RestoreState(history->Undo(new ManagerState(_meshes, meshId, lastModified, referencePoint)));
705                         RefreshOutputs(true);
706                 }
707                 else if(history->UndoSize() > 1){
708                         RestoreStateMemoryMode(history->UndoKeepCurrent());
709                 }
710         }
711 }
712
713 void MeshManagerModel::Redo()
714 {
715         if(history->RedoSize() > 0)
716         {
717                 if(memoryMode == false){
718                         RestoreState(history->Redo(new ManagerState(_meshes, meshId, lastModified, referencePoint)));
719                         RefreshOutputs(true);
720                 }
721                 else{
722                         RestoreStateMemoryMode(history->RedoKeepCurrent());
723                 }
724         }
725 }
726
727 void MeshManagerModel::Save()
728 {
729         history->Save(new ManagerState(_meshes, meshId, currentMesh, referencePoint));
730 }
731
732 void MeshManagerModel::SaveMemoryMode()
733 {
734         if(_meshes.size() == 1 && memoryMode)
735         {
736                 std::vector<std::shared_ptr<MeshModel>> savedMesh;
737                 savedMesh.push_back(std::make_shared<MeshModel>(_meshes.at(0).get()));
738                 history->Save(new ManagerState(savedMesh, meshId, 0, referencePoint));
739         }
740         else{
741                 printf("PG MeshManagerModel::SaveMemoryMode WARNING Mesh vector has invalid size or memoryMode is not set \n");
742         }
743 }
744
745 void MeshManagerModel::RestoreState(ManagerState* state)
746 {
747         if(state != NULL)
748         {       
749                 _meshes = state->GetMeshes();
750                 meshId = state->GetMeshId();
751                 currentMesh = state->GetModifiedPos();
752                 lastModified = state->GetModifiedPos();
753                 delete state;
754         }
755         else{
756                 printf("PG MeshManagerModel::RestoreState WARNING State is NULL \n");
757         }
758 }
759
760 void MeshManagerModel::RestoreStateMemoryMode(ManagerState* state){
761         if(_meshes.size() == 1 && state != NULL)
762         {
763                 vtkPoints* statePoints = vtkPoints::New();
764                 statePoints->DeepCopy(state->GetMeshes().at(0)->GetMeshBase()->GetPoints());
765                 _meshes.at(0)->GetMeshBase()->SetPoints(statePoints);
766                 _meshes.at(0)->GetMeshBase()->GetPoints()->Modified();
767         _meshes.at(0)->GetMeshBase()->Modified();
768         referencePoint = state->GetReferencePoint();
769         }else{
770                 printf("PG MeshManagerModel::RestoreStateMemoryMode WARNING Mesh vector has invalid size or state is NULL\n");
771         }
772 }
773
774 //
775 //Manager State
776 //
777 MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int modifiedPos, std::vector<double> refPoint)
778 {
779         savedMeshes = meshesToSave;
780         savedId = meshId;
781         savedModifiedPos = modifiedPos;
782         referencePoint = refPoint;
783 }
784
785 MeshManagerModel::ManagerState::~ManagerState()
786 {
787         savedMeshes.clear();
788 }
789
790 std::vector<std::shared_ptr<MeshModel>>& MeshManagerModel::ManagerState::GetMeshes()
791 {
792         return savedMeshes;
793 }
794
795 int MeshManagerModel::ManagerState::GetMeshId()
796 {
797         return savedId;
798 }
799 int MeshManagerModel::ManagerState::GetModifiedPos()
800 {
801         return savedModifiedPos;
802 }
803
804 std::vector<double>& MeshManagerModel::ManagerState::GetReferencePoint()
805 {
806         return referencePoint;
807 }