]> Creatis software - creaVtk.git/blob - lib/creaVtk/MeshManagerModel.cpp
#3517 Adjustments Undo - Redo for deformation
[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         referenceNormal = {0, 0, 1};
334 }
335
336 MeshManagerModel::~MeshManagerModel()
337 {
338         DeleteAll();
339         history->CleanHistory();
340         delete history;
341 }
342
343 void MeshManagerModel::RefreshOutputs(bool signalBox) // virtual
344 {
345 }
346
347 void MeshManagerModel::SetHistory(int maxCapacity)
348 {
349         if(history != NULL){    
350                 ResetHistory();
351                 delete history;
352         }
353         history = new HistoryHandler<ManagerState>(maxCapacity);
354 }
355
356 void MeshManagerModel::ResetHistory()
357 {
358         history->CleanHistory();
359 }
360
361 void MeshManagerModel::SetReferencePoint(std::vector<double> point)
362 {
363         referencePoint = point;
364 }
365
366 std::vector<double> MeshManagerModel::GetReferencePoint()
367 {
368         return referencePoint;
369 }
370
371 void MeshManagerModel::SetReferenceNormal(std::vector<double> normal)
372 {
373         referenceNormal = normal;
374 }
375
376 std::vector<double> MeshManagerModel::GetReferenceNormal()
377 {
378         return referenceNormal;
379 }
380
381 int MeshManagerModel::GetNumberOfMeshes()
382 {
383         return _meshes.size();
384 }
385
386 void MeshManagerModel::AddMesh_(vtkPolyData* mesh)
387 {
388         if(mesh != NULL)
389         {
390                 _meshes.push_back(std::make_shared<MeshModel>(mesh, meshId));
391                 meshId++;
392         }else{
393                 printf("PG MeshManagerModel::AddMesh Mesh is null \n");
394         }
395 }
396
397 void MeshManagerModel::AddMesh(vtkPolyData* mesh)
398 {
399         Save();
400         AddMesh_(mesh);
401         lastModified = currentMesh;
402         RefreshOutputs(true);
403 }
404
405 void MeshManagerModel::AddMeshes_(std::vector<vtkPolyData*> meshList)
406 {
407         if(!meshList.empty())
408         {
409                 MeshModel *meshModel;
410                 for(int i = 0; i < meshList.size(); i++){
411                         _meshes.push_back(std::make_shared<MeshModel>(meshList[i], meshId));
412                         meshId++;
413                 }
414         }else{
415                 printf("PG MeshManagerModel::AddMeshes Empty list of meshes \n");
416         }
417 }
418
419 void MeshManagerModel::AddMeshes(std::vector<vtkPolyData*> meshList)
420 {
421         Save();
422         AddMeshes_(meshList);
423         lastModified = currentMesh;
424         RefreshOutputs(true);
425 }
426
427 void MeshManagerModel::AddEmptyMesh_()
428 {
429         _meshes.push_back(std::make_shared<MeshModel>(meshId));
430         meshId++;
431 }
432
433 void MeshManagerModel::AddEmptyMesh()
434 {
435         Save();
436         AddEmptyMesh_();
437         lastModified = currentMesh;
438         RefreshOutputs(true);
439 }
440
441 void MeshManagerModel::InsertMeshesAtCurrent_(std::vector<vtkPolyData*> meshList)
442 {
443         if(!meshList.empty())
444         {
445                 std::vector<std::shared_ptr<MeshModel>> tmpVect;
446                 MeshModel *meshModel;
447                 for(int i = 0; i < meshList.size(); i++){
448                         tmpVect.push_back(std::make_shared<MeshModel>(meshList[i], meshId));
449                         meshId++;
450                 }
451                 _meshes.insert(_meshes.begin() + currentMesh, tmpVect.begin(), tmpVect.end());
452         }else{
453                 printf("PG MeshManagerModel::InsertMeshesAtCurrent Empty list of meshes \n");
454         }
455 }
456
457 void MeshManagerModel::InsertMeshesAtCurrent(std::vector<vtkPolyData*> meshList)
458 {
459         Save();
460         InsertMeshesAtCurrent_(meshList);
461         lastModified = currentMesh;
462         RefreshOutputs(true);
463 }
464
465 void MeshManagerModel::SelectMesh(int i) 
466 {
467         if(i >= 0 && i < _meshes.size())
468         {
469                 int prevCurrent = currentMesh;
470                 currentMesh = i;
471                 if(prevCurrent != i)
472                 {
473                         RefreshOutputs(true);           
474                 }
475         }
476         else{
477                 printf("PG MeshManagerModel::SelectMesh index out of bounds \n");
478         }
479 }
480
481 void MeshManagerModel::SelectMeshByName(std::string meshName) 
482 {
483         if(!_meshes.empty())
484         {
485                 bool found = false;
486                 for(int i = 0; i < _meshes.size() && !found; i++){
487                         if(_meshes.at(i)->GetName() == meshName)
488                         {
489                                 found = true;
490                                 SelectMesh(i);
491                         }
492                 }
493         }
494 }
495
496 void MeshManagerModel::DeleteMesh_(int position)
497 {
498         if(position >= 0 && position < _meshes.size())
499         {
500                 _meshes.erase(_meshes.begin() + position);
501                 currentMesh = currentMesh + (position <= currentMesh?-1:0);
502                 if(currentMesh < 0)
503                 {
504                         currentMesh = 0;
505                 }
506         }
507 }
508
509 void MeshManagerModel::DeleteMesh(int position)
510 {
511         Save();
512         DeleteMesh_(position);
513         lastModified = currentMesh;
514         RefreshOutputs(true);
515 }
516
517 void MeshManagerModel::DeleteMeshByName(std::string meshName)
518 {
519         if(!_meshes.empty())
520         {
521                 bool found = false;
522                 for(int i = 0; i < _meshes.size() && !found; i++){
523                         if(_meshes.at(i)->GetName() == meshName)
524                         {
525                                 found = true;
526                                 DeleteMesh_(i);
527                                 RefreshOutputs(true);
528                         }
529                 }
530         }
531 }
532
533 void MeshManagerModel::DeleteCurrentMesh()
534 {
535         if(!_meshes.empty())
536         {
537                 Save();
538                 DeleteMesh_(currentMesh);
539                 lastModified = currentMesh;
540                 RefreshOutputs(true);
541         }
542 }
543
544 void MeshManagerModel::ReplaceMesh(std::vector<vtkPolyData*> meshList)
545 {
546         Save();
547         if(GetNumberOfMeshes() >= 1)
548         {
549                 DeleteMesh_(currentMesh);
550         }
551         InsertMeshesAtCurrent_(meshList);
552         lastModified = currentMesh;
553         RefreshOutputs(true);
554 }
555
556 void MeshManagerModel::DeleteAll_()
557 {
558         if(!_meshes.empty())
559         {
560                 currentMesh = 0;
561                 _meshes.clear();
562                 RefreshOutputs(true);
563         }
564 }
565
566 void MeshManagerModel::DeleteAll()
567 {
568         Save();
569         DeleteAll_();
570         lastModified = currentMesh;
571         RefreshOutputs(true);
572 }
573
574 void MeshManagerModel::NextMesh()
575 {
576         currentMesh++;
577         if(currentMesh >= _meshes.size())
578         {
579                 currentMesh = _meshes.size()-1;
580         }
581         RefreshOutputs(true);
582 }
583
584 void MeshManagerModel::PreviousMesh()
585 {
586         currentMesh--;
587         if(currentMesh < 0)
588         {
589                 currentMesh = 0;
590         }
591         RefreshOutputs(true);
592 }
593
594 std::shared_ptr<MeshModel> MeshManagerModel::GetMeshModel()
595 {
596         return _meshes.at(currentMesh);
597 }
598
599 vtkPolyData*  MeshManagerModel::GetMeshBase()
600 {
601         if(!_meshes.empty())
602         {
603                 return _meshes.at(currentMesh)->GetMeshBase();
604         }
605         else{
606                 return NULL;
607         }
608 }
609
610 vtkPolyData*  MeshManagerModel::GetMeshTemp()
611 {
612         if(!_meshes.empty())
613         {
614                 return _meshes.at(currentMesh)->GetMeshTemp();
615         }
616         else{
617                 return NULL;
618         }
619 }
620
621 void MeshManagerModel::SetMeshBase(vtkPolyData* mesh)
622 {
623     if(!_meshes.empty())
624     {
625         Save();
626         _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
627         _meshes.at(currentMesh)->SetMeshBase(mesh);
628         lastModified = currentMesh;
629         RefreshOutputs(true);
630     }else{
631         printf("PG MeshManagerModel::SetMeshBase Mesh vector is empty \n");
632     }
633 }
634
635 void MeshManagerModel::MeshMemoryModeOn()
636 {
637         memoryMode = true;
638 }
639
640 void MeshManagerModel::MeshMemoryModeOff()
641 {
642         memoryMode = false;
643 }
644
645 void MeshManagerModel::SetMeshMemoryMode(vtkPolyData* mesh)
646 {
647         if(_meshes.size() > 1)
648         {
649                 DeleteAll_();
650         }
651         if(_meshes.size() == 0)
652         {
653                 AddEmptyMesh_();
654         }
655         _meshes.at(currentMesh)->SetMeshMemoryMode(mesh);
656         ResetHistory();
657         SaveMemoryMode();
658         RefreshOutputs(true);
659 }
660
661 void MeshManagerModel::ResetMeshTemp()
662 {
663         if(!_meshes.empty())
664         {
665         _meshes.at(currentMesh)->ResetMeshTemp();
666         RefreshOutputs(true);
667     }else{
668         printf("PG MeshManagerModel::ResetMeshTemp Mesh vector is empty \n");
669     }
670 }
671
672 void MeshManagerModel::CopySetMeshBase(vtkPolyData* mesh)
673 {
674         if(!_meshes.empty())
675         {
676                 Save();
677                 _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
678                 _meshes.at(currentMesh)->CopySetMeshBase(mesh);
679                 lastModified = currentMesh;
680                 RefreshOutputs(true);
681         }
682         else{
683                 printf("PG MeshManagerModel::CopySetMeshBase Mesh vector is empty \n");
684         }
685 }
686
687 std::vector<std::string> MeshManagerModel::GetMeshNames()
688 {
689         std::vector<std::string> names;
690         for(int i = 0; i < _meshes.size(); i++){
691                 names.push_back(_meshes.at(i)->GetName());
692         }
693         return names;
694 }
695
696 std::vector<vtkPolyData*> MeshManagerModel::GetAllPolyDatas()
697 {
698         std::vector<vtkPolyData*> polydatas;
699         for(int i = 0; i < _meshes.size(); i++){
700                 polydatas.push_back(_meshes.at(i)->GetMeshBase());
701         }
702         return polydatas;
703 }
704
705 int MeshManagerModel::GetCurrentMesh()
706 {
707         return currentMesh;
708 }
709
710 void MeshManagerModel::Undo()
711 {       
712         if(history->UndoSize() > 0)
713         {
714                 if(memoryMode == false){
715                         RestoreState(history->Undo(new ManagerState(_meshes, meshId, lastModified)));
716                         RefreshOutputs(true);
717                 }
718                 else if(history->UndoSize() > 1){
719                         RestoreStateMemoryMode(history->UndoKeepCurrent());
720                 }
721         }
722 }
723
724 void MeshManagerModel::Redo()
725 {
726         if(history->RedoSize() > 0)
727         {
728                 if(memoryMode == false){
729                         RestoreState(history->Redo(new ManagerState(_meshes, meshId, lastModified)));
730                         RefreshOutputs(true);
731                 }
732                 else{
733                         RestoreStateMemoryMode(history->RedoKeepCurrent());
734                 }
735         }
736 }
737
738 void MeshManagerModel::Save()
739 {
740         history->Save(new ManagerState(_meshes, meshId, currentMesh));
741 }
742
743 void MeshManagerModel::SaveMemoryMode()
744 {
745         if(_meshes.size() == 1 && memoryMode)
746         {
747                 std::vector<std::shared_ptr<MeshModel>> savedMesh;
748                 savedMesh.push_back(std::make_shared<MeshModel>(_meshes.at(0).get()));
749                 history->Save(new ManagerState(savedMesh, meshId, 0, referencePoint, referenceNormal));
750         }
751         else{
752                 printf("PG MeshManagerModel::SaveMemoryMode WARNING Mesh vector has invalid size or memoryMode is not set \n");
753         }
754 }
755
756 void MeshManagerModel::RestoreState(ManagerState* state)
757 {
758         if(state != NULL)
759         {       
760                 _meshes = state->GetMeshes();
761                 meshId = state->GetMeshId();
762                 currentMesh = state->GetModifiedPos();
763                 lastModified = state->GetModifiedPos();
764                 delete state;
765         }
766         else{
767                 printf("PG MeshManagerModel::RestoreState WARNING State is NULL \n");
768         }
769 }
770
771 void MeshManagerModel::RestoreStateMemoryMode(ManagerState* state){
772         if(_meshes.size() == 1 && state != NULL)
773         {
774                 vtkPoints* statePoints = vtkPoints::New();
775                 statePoints->DeepCopy(state->GetMeshes().at(0)->GetMeshBase()->GetPoints());
776                 _meshes.at(0)->GetMeshBase()->SetPoints(statePoints);
777                 _meshes.at(0)->GetMeshBase()->GetPoints()->Modified();
778         _meshes.at(0)->GetMeshBase()->Modified();
779         referencePoint = state->GetReferencePoint();
780         referenceNormal = state->referenceNormal;
781         }else{
782                 printf("PG MeshManagerModel::RestoreStateMemoryMode WARNING Mesh vector has invalid size or state is NULL\n");
783         }
784 }
785
786 //
787 //Manager State
788 //
789 MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int modifiedPos)
790 {
791         savedMeshes = meshesToSave;
792         savedId = meshId;
793         savedModifiedPos = modifiedPos;
794 }
795
796 MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int modifiedPos, std::vector<double> refPoint, std::vector<double> refNormal)
797 {
798         savedMeshes = meshesToSave;
799         savedId = meshId;
800         savedModifiedPos = modifiedPos;
801         referencePoint = refPoint;
802         referenceNormal = refNormal;
803 }
804
805 MeshManagerModel::ManagerState::~ManagerState()
806 {
807         savedMeshes.clear();
808 }
809
810 std::vector<std::shared_ptr<MeshModel>>& MeshManagerModel::ManagerState::GetMeshes()
811 {
812         return savedMeshes;
813 }
814
815 int MeshManagerModel::ManagerState::GetMeshId()
816 {
817         return savedId;
818 }
819 int MeshManagerModel::ManagerState::GetModifiedPos()
820 {
821         return savedModifiedPos;
822 }
823
824 std::vector<double>& MeshManagerModel::ManagerState::GetReferencePoint()
825 {
826         return referencePoint;
827 }