]> Creatis software - creaVtk.git/commitdiff
#3507 Undo and Redo Meshes
authorPablo Garzon <gapablo2001@gmail.com>
Tue, 30 May 2023 18:00:11 +0000 (20:00 +0200)
committerPablo Garzon <gapablo2001@gmail.com>
Tue, 30 May 2023 18:00:11 +0000 (20:00 +0200)
bbtk_creaVtk_PKG/src/bbcreaVtkBooleanOperationPolyDataFilter.cxx
bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx
bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx
bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx
bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.h
bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataConnectivityFilter.cxx
bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataNormals.cxx
lib/creaVtk/MeshManagerModel.cpp
lib/creaVtk/MeshManagerModel.h

index 79a92c2539abe2b87e7dc70041a09438a7e830a8..f610d86ac5c7b249268a24a67a14d9acea0f8e44 100644 (file)
@@ -40,31 +40,6 @@ void BooleanOperationPolyDataFilter::Process()
   
        if ((bbGetInputIn1()!=NULL)  && (bbGetInputIn2()!=NULL) )
        {
-/*        
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at the end of CreateMesh.. or create 2 new boxes\n");
-*/
-
-/*    
-        vtkCleanPolyData *clean1 = vtkCleanPolyData::New();
-               vtkCleanPolyData *clean2 = vtkCleanPolyData::New();
-               clean1->SetInputData( bbGetInputIn1() );
-               clean2->SetInputData( bbGetInputIn2() );
-               clean1->Update();
-               clean2->Update();
-               vtkTriangleFilter *triangle1 = vtkTriangleFilter::New();
-               vtkTriangleFilter *triangle2 = vtkTriangleFilter::New();
-               triangle1->SetInputData( clean1->GetOutput() );
-               triangle2->SetInputData( clean2->GetOutput() );
-               triangle1->Update();
-               triangle2->Update();
-*/
        //TRIANGLE FILTER NOT NEEDED, this can handle non triangle meshes.
        
 
@@ -123,17 +98,10 @@ printf("EED Warnning BooleanOperationPolyDataFilter::Process  Put this code at t
 //            bbSetOutputOut( fillHolesFilter->GetOutput() );
                        
                        /*
-                       *
                        *Added boxes(triangleFilter and CleanPolyData) to handle this outside the box
                        *
-                       
-                       //vtkTriangleFilter *triangleEnd = vtkTriangleFilter::New();
-                       //triangleEnd->SetInputData( booleanOperation->GetOutput() );
-                       //triangleEnd->Update();
-                       
+                       vtkTriangleFilter *triangleEnd = vtkTriangleFilter::New();
                        vtkCleanPolyData *cleanEnd = vtkCleanPolyData::New();
-                       cleanEnd->SetInputData( booleanOperation->GetOutput() );
-                       cleanEnd->Update();
                        bbSetOutputOut( cleanEnd->GetOutput() );
                        */
                        
index 58448a4fe7a84f819c63dcf8d215c3dbcbf3212a..b804dff795705d81e803d1bcdd80e364db1799e4 100644 (file)
@@ -38,6 +38,7 @@ void CreateMeshFromPoints::Process()
                std::vector<double> lstY                = bbGetInputLstY();
                std::vector<double> lstZ                = bbGetInputLstZ();
                std::vector<int> lstIndexs              = bbGetInputLstIndexs();
+               double pointsCentroid[3];
                if ( (lstIndexs.size()<1) || (lstX.size()==0) || (lstX.size()!=lstY.size()) || (lstY.size()!=lstZ.size()) )
                {
                        printf("Warning! CreateMeshFromPoints::Process: List of points X Y Z  and LstIndexes is not correct\n");
@@ -52,7 +53,52 @@ void CreateMeshFromPoints::Process()
                        for (i=0;i<sizeLstX;i++)
                        {
                                points->InsertNextPoint(lstX[i],lstY[i],lstZ[i]);
+                               pointsCentroid[0] += lstX[i];
+                               pointsCentroid[1] += lstY[i];
+                               pointsCentroid[2] += lstZ[i];
                        } // for i
+                       pointsCentroid[0] /= sizeLstX;
+                       pointsCentroid[1] /= sizeLstX;
+                       pointsCentroid[2] /= sizeLstX;
+                       
+                       if(bbGetInputCloseSurface())
+                       {
+                               //Correct surface normals if needed
+                               double pointSurf1[3], pointSurf2[3], pointSurf3[3];
+                               double vect1[3], vect2[3];
+                               double surfNormal[3], vectorCenter[3];
+                               double dotNormalSurf = 0;
+                               
+                               for(int pIndex = 0; pIndex < lstIndexs[0]-1; pIndex++){
+                                       pointSurf1[0] = lstX[pIndex];
+                                       pointSurf1[1] = lstY[pIndex];
+                                       pointSurf1[2] = lstZ[pIndex];
+                                       vtkMath::Subtract(pointsCentroid, pointSurf1, vectorCenter);
+                                       
+                                       pointSurf2[0] = lstX[pIndex+lstIndexs[1]];
+                                       pointSurf2[1] = lstY[pIndex+lstIndexs[1]];
+                                       pointSurf2[2] = lstZ[pIndex+lstIndexs[1]];
+                                       pointSurf3[0] = lstX[pIndex+1];
+                                       pointSurf3[1] = lstY[pIndex+1];
+                                       pointSurf3[2] = lstZ[pIndex+1];
+                                       vtkMath::Subtract(pointSurf2, pointSurf1, vect1);
+                                       vtkMath::Subtract(pointSurf3, pointSurf1, vect2);
+                                       vtkMath::Cross(vect1, vect2, surfNormal);
+                                       dotNormalSurf += vtkMath::Dot(surfNormal, vectorCenter);
+                               }
+                               if(dotNormalSurf > 0){
+                                       points->Delete();
+                                       points = vtkPoints::New();
+                                       for(int splineI = 0; splineI < lstIndexs.size(); splineI++){                            
+                                               for (i=lstIndexs[splineI]-1; i >= 0;i--)
+                                               {
+                                                       points->InsertNextPoint(lstX[splineI*lstIndexs[0]+i],lstY[splineI*lstIndexs[0]+i],lstZ[splineI*lstIndexs[0]+i]);
+                                               }
+                                       }
+                               }
+                       }
+                       //
+                       
 //                     vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
                        if (cells!=NULL) cells->Delete();
                        cells = vtkCellArray::New();
@@ -85,7 +131,8 @@ void CreateMeshFromPoints::Process()
                                iGeneral=iGeneral+sizeSegment1;
                                cells->InsertNextCell(triangleStrip);
                        } //for  LstIndexs
-
+                       
+                       
                        if(bbGetInputCloseSurface())
                        {
                                int lastId1 = lstIndexs[0]-1;
@@ -217,16 +264,7 @@ void CreateMeshFromPoints::CloseContourSides(std::vector<int> lstIndexs, bool uP
                                                        triangle->GetPointIds()->SetId(2, centroidId);
                                                        cells->InsertNextCell(triangle);
                                                }
-                                               /**triangleStrip->GetPointIds()->SetId(triangleIndex,index);
-                                               triangleStrip->GetPointIds()->SetId(triangleIndex+1,centroidId);
-                                               if(index-increment <= initial && !isClosedCont){
-                                                       triangleStrip->GetPointIds()->SetId(triangleIndex+2,triangleStripStart);
-                                                       triangleStrip->GetPointIds()->SetId(triangleIndex+3,centroidId);
-                                               }
-                                               triangleIndex+=2;
-                                               */
                                        }
-                                       //cells->InsertNextCell(triangleStrip);
                                }//if normalOrder
                        }//if validCentroid
                }//if numPointsFace
@@ -364,13 +402,27 @@ void CreateMeshFromPoints::CloseContourBottom(bool uPointOrder){
        
        vtkSmartPointer<vtkTriangleStrip> triangleStripBottom = vtkSmartPointer<vtkTriangleStrip>::New();
        triangleStripBottom->GetPointIds()->SetNumberOfIds(sizeLstIdexes*2);
+       
+       double originPoint[3];
+       points->GetPoint(0, originPoint);
+       int middleMeshPoint = uPointOrder?lstIndexs[0]/2:lstIndexs[0]*sizeLstIdexes/2;
+       
+       bool normalOrder = isPointingCorrectly(uPointOrder?lstIndexs[0]-1:sizeLstX-lstIndexs[0], uPointOrder?lstIndexs[0]:1, originPoint, middleMeshPoint);
+       
        int triangleIndex = 0, currentId = 0, nextId = 0;
        for(int splineIndex = 0; splineIndex < sizeLstIdexes;splineIndex++){
-               triangleStripBottom->GetPointIds()->SetId(triangleIndex, currentId);
                nextId = uPointOrder?currentId + lstIndexs[splineIndex] - 1:sizeLstX - sizeLstIdexes + splineIndex;
-               triangleStripBottom->GetPointIds()->SetId(triangleIndex+1, nextId);
-               triangleIndex+=2;
+               if(normalOrder)
+               {
+                       triangleStripBottom->GetPointIds()->SetId(triangleIndex, currentId);
+                       triangleStripBottom->GetPointIds()->SetId(triangleIndex+1, nextId);
+               }
+               else{
+                       triangleStripBottom->GetPointIds()->SetId(triangleIndex, nextId);
+                       triangleStripBottom->GetPointIds()->SetId(triangleIndex+1, currentId);
+               }
                currentId = uPointOrder?nextId + 1: splineIndex+1;
+               triangleIndex+=2;
        }
        cells->InsertNextCell(triangleStripBottom);
 }
index 3fa8d4b50775e338915f2a6b09029889c9ab355d..9e641450ae7fd32c53140558fa4b6d4bf01e0e7c 100644 (file)
@@ -54,6 +54,8 @@ void MeshManager::Process()
         meshManagerModel_Box->AddMeshes_( bbGetInputMeshVector() );
 
                meshManagerModel_Box->AddMesh_( bbGetInputMesh() );
+               
+               meshManagerModel_Box->ResetHistory();
         //meshManagerModel_Box->SetMeshBase( bbGetInputMesh() );
         meshManagerModel_Box->RefreshOutputs(false);
         bbSetOutputMeshManagerModel( meshManagerModel_Box );
index e39e25fd66ef4e531c2a0d259875f32b3b1d3871..546ba7470e3cb129335ecac2011f162cc663e125 100644 (file)
@@ -31,12 +31,14 @@ void MeshManager_tool::Process()
     {
         if (bbGetInputTool()==10) // Undo
         {
-            printf("EED Warning!   MeshManager_tool Undo   Not implemented.\n");
+               bbGetInputMeshManagerModel()->Undo();
+            //printf("EED Warning!   MeshManager_tool Undo   Not implemented.\n");
         } // if Tool 10 Undo
         
         if (bbGetInputTool()==20) // Redo
         {
-            printf("EED Warning!   MeshManager_tool Redo   Not implemented.\n");
+               bbGetInputMeshManagerModel()->Redo();
+            //printf("EED Warning!   MeshManager_tool Redo   Not implemented.\n");
         } // if Tool 20 Redo
 
         if (bbGetInputTool()==30)  // Set
@@ -49,6 +51,17 @@ void MeshManager_tool::Process()
                 } // if points!=NULL
             } // Mesh!=NULL
         } // if Tool 30 Set
+        
+        if (bbGetInputTool()==31)  // Set/Update PolyData Reference
+        {
+            if (bbGetInputMesh()!=NULL){
+                vtkPoints   *points = bbGetInputMesh()->GetPoints();
+                if (points!=NULL)
+                {
+                    bbGetInputMeshManagerModel()->UpdateMeshReference( bbGetInputMesh() );
+                } // if points!=NULL
+            } // Mesh!=NULL
+        } // if Tool 30 Set
 
         if (bbGetInputTool()==35)  // Set memory mode
         {
@@ -70,14 +83,7 @@ void MeshManager_tool::Process()
         {
                if(bbGetInputMeshes().size() > 1)
                {
-                       if(bbGetInputMeshManagerModel()->GetNumberOfMeshes() == 1){
-                                       bbGetInputMeshManagerModel()->DeleteAll();
-                       }
-                       if(bbGetInputMeshManagerModel()->GetNumberOfMeshes() > 1)
-                       {
-                               bbGetInputMeshManagerModel()->DeleteCurrentMesh();
-                       }
-                               bbGetInputMeshManagerModel()->InsertMeshesAtCurrent(bbGetInputMeshes());
+                       bbGetInputMeshManagerModel()->ReplaceMesh(bbGetInputMeshes());
                    }
         }
         if(bbGetInputTool() == 60) // Select Mesh by Name
index 76ba719e2999fcfa98dac4f41064d16033f40883..d5723c0d22cb0773230265d15c6a5d25af7af9cb 100644 (file)
@@ -40,7 +40,7 @@ BBTK_BEGIN_DESCRIBE_BLACK_BOX(MeshManager_tool,bbtk::AtomicBlackBox);
   BBTK_DESCRIPTION("No Description.");
   BBTK_CATEGORY("empty");
 
-  BBTK_INPUT(MeshManager_tool,Tool,"(default 0) 0:Nothing  10:Undo  20:ReDo  30:Set  32:Copy and Set  35:Set memory mode  40:ResetMeshTemp     50: Set Array of meshes  60:Select mesh by name  70:Delete current mesh",int,"");
+  BBTK_INPUT(MeshManager_tool,Tool,"(default 0) 0:Nothing  10:Undo  20:ReDo  30:Set  31:Update polydata ref  32:Copy and Set  35:Set memory mode  40:ResetMeshTemp     50: Set Array of meshes  60:Select mesh by name  70:Delete current mesh",int,"");
   BBTK_INPUT(MeshManager_tool,Mesh,"Mesh",vtkPolyData*,"");
   BBTK_INPUT(MeshManager_tool,Meshes,"Input meshes, required for tool 50",std::vector<vtkPolyData*>,"");
   BBTK_INPUT(MeshManager_tool,StringParam,"String input",std::string,"");
index fdce1f4ae4740141fbdbebc46bf5b41c822b34ed..b2becd106f9649fe4eb6b1221bbb8c1c7ebecb28 100644 (file)
@@ -26,14 +26,16 @@ void PolyDataConnectivityFilter::Process()
 //    * TYPE is the C++ type of the input/output
 //      (the one provided in the attribute 'type' of the tag 'input')
     
+    std::vector<vtkPolyData*> output;
+    
     //Get all connected components in a polydata vector
     if(bbGetInputIn() == NULL){
        printf("PG PolyDataConnectivityFilter::Process Input polydata is null \n");
+       bbSetOutputOut(output);
        return;
     }
     
        if(bbGetInputType() == 1){
-               std::vector<vtkPolyData*> output;
                connFilter->SetInputData( bbGetInputIn() );
                connFilter->SetExtractionModeToSpecifiedRegions();
                connFilter->Update();
index b560cc95095dc6dabd1dbcac6dd7dc04355c61b4..46bc24a56656d27a216545591e1f3005b3df1908 100644 (file)
@@ -39,9 +39,8 @@ void PolyDataNormals::Process()
     if (bbGetInputIn()!=NULL)
     {
         vtkPolyDataNormals* normal = vtkPolyDataNormals::New();
-
 //      Automatically change the orientation fo normals, put it from inside to outside
-        normal->SetAutoOrientNormals(true);
+//        normal->SetAutoOrientNormals(true);
         normal->SetConsistency(true);
 //      this force to not change the order of triangles, keep the original order        
 //        normal->SetAutoOrientNormals(false);
index 677727c6057a054b06ecb097298ba36977c1f78a..c03e9e8b2268567199c8b62237d72bd8fb469b35 100644 (file)
 
 #include "MeshManagerModel.h"
 
+template <class T>
+HistoryHandler<T>::HistoryHandler(int maxElements)
+{
+       this->maxElements = maxElements;
+}
+template <class T>
+HistoryHandler<T>::~HistoryHandler()
+{
+       CleanHistory();
+}
+
+template <class T>
+void HistoryHandler<T>::CleanHistory()
+{
+       for (T* element : redoStack)
+       {
+               delete element;
+       }
+       for (T* element : undoStack)
+       {
+               delete element;
+       }
+}
+
+template <class T>
+T* HistoryHandler<T>::Undo()
+{
+       if(!undoStack.empty() && undoStack.size()>1)
+       {
+               auto lastElem = undoStack.back();
+               undoStack.pop_back();
+               redoStack.push_back(lastElem);
+               return undoStack.back();
+       }
+       return NULL;
+}
+
+template <class T>
+T* HistoryHandler<T>::Redo()
+{
+       if(!redoStack.empty())
+       {
+               auto lastElem = redoStack.back();
+               redoStack.pop_back();
+               undoStack.push_back(lastElem);
+               return lastElem;
+       }
+       return NULL;
+}
+
+template <class T>
+void HistoryHandler<T>::Save(T* state)
+{
+       undoStack.push_back(state);
+       if(!redoStack.empty())
+       {
+               for (T* element : redoStack)
+               {
+                       delete element;
+               } 
+               redoStack.clear();
+       }
+}
+
+template <class T>
+int HistoryHandler<T>::UndoSize()
+{
+       return undoStack.size();
+}
+
+template <class T>
+int HistoryHandler<T>::RedoSize()
+{
+       return redoStack.size();
+}
+
 ////////////////////
 /////////////////////// MESH MODEL
 ////////////////////
@@ -50,6 +126,20 @@ MeshModel::MeshModel(vtkPolyData* mesh, int id)
        }
 }
 
+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();
@@ -70,7 +160,11 @@ void MeshModel::ResetMeshTemp_()
         _meshTemp = vtkPolyData::New();
         _meshTemp->DeepCopy(_meshBase);
     } else {
-        _meshTemp=NULL;
+        if (_meshTemp!=NULL)
+        {
+            _meshTemp->Delete();
+            _meshTemp = NULL;
+        }
     }
 }
 
@@ -78,6 +172,9 @@ void MeshModel::SetMeshBase(vtkPolyData* mesh)
 {
     if (mesh!=NULL)
     {
+       if(_meshBase != NULL){
+               _meshBase->Delete();
+       }
         _meshBase = mesh;
         ResetMeshTemp_();
     } // if mesh
@@ -85,7 +182,17 @@ void MeshModel::SetMeshBase(vtkPolyData* mesh)
 
 void MeshModel::SetMeshMemoryMode(vtkPolyData* mesh)
 {
-    _meshBase = mesh;
+       //if(_meshBase != NULL)
+       //{
+       //      _meshBase->Delete();
+       //      _meshBase = NULL;
+       //}
+       //if (_meshTemp != NULL)
+    //{
+    //    _meshTemp->Delete();
+    //    _meshTemp = NULL;
+       //}
+       _meshBase = mesh;
 }
 
 void MeshModel::ResetMeshTemp()
@@ -104,12 +211,12 @@ void MeshModel::CopySetMeshBase(vtkPolyData* mesh)
 }
 
 
-vtkPolyData*  MeshModel::GetMeshBase()
+vtkPolyData* MeshModel::GetMeshBase()
 {
    return _meshBase;
 }
 
-vtkPolyData*  MeshModel::GetMeshTemp()
+vtkPolyData* MeshModel::GetMeshTemp()
 {
    return _meshTemp;
 }
@@ -130,10 +237,9 @@ std::string MeshModel::GetName()
 
 MeshManagerModel::MeshManagerModel()
 {
-       //MeshModel* firstMesh = new MeshModel();
-       //_meshes.push_back(firstMesh);
        currentMesh = 0;
        meshId = 0;
+       history = new HistoryHandler<ManagerState>(20);
 }
 
 MeshManagerModel::~MeshManagerModel()
@@ -145,14 +251,27 @@ void MeshManagerModel::RefreshOutputs(bool signalBox) // virtual
 {
 }
 
-int MeshManagerModel::GetNumberOfMeshes(){
+void MeshManagerModel::ResetHistory()
+{
+       history->CleanHistory();
+       Save();
+}
+
+void MeshManagerModel::UpdateMeshReference(vtkPolyData* mesh)
+{
+       _meshes.at(currentMesh)->SetMeshBase(mesh);
+       RefreshOutputs(true);
+}
+
+int MeshManagerModel::GetNumberOfMeshes()
+{
        return _meshes.size();
 }
 
-void MeshManagerModel::AddMesh_(vtkPolyData* mesh){
+void MeshManagerModel::AddMesh_(vtkPolyData* mesh)
+{
        if(mesh != NULL){
-               MeshModel *meshModel = new MeshModel(mesh, meshId);
-               _meshes.push_back(meshModel);
+               _meshes.push_back(std::make_shared<MeshModel>(mesh, meshId));
                meshId++;
        }
        else{
@@ -160,18 +279,20 @@ void MeshManagerModel::AddMesh_(vtkPolyData* mesh){
        }
 }
 
-void MeshManagerModel::AddMesh(vtkPolyData* mesh){
+void MeshManagerModel::AddMesh(vtkPolyData* mesh)
+{
        AddMesh_(mesh);
+       Save();
        RefreshOutputs(true);
 }
 
-void MeshManagerModel::AddMeshes_(std::vector<vtkPolyData*> meshList){
+void MeshManagerModel::AddMeshes_(std::vector<vtkPolyData*> 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<MeshModel>(meshList[i], meshId));
                        meshId++;
                }
        }else{
@@ -179,19 +300,23 @@ void MeshManagerModel::AddMeshes_(std::vector<vtkPolyData*> meshList){
        }
 }
 
-void MeshManagerModel::AddMeshes(std::vector<vtkPolyData*> meshList){
+void MeshManagerModel::AddMeshes(std::vector<vtkPolyData*> meshList)
+{
        AddMeshes_(meshList);
+       Save();
        RefreshOutputs(true);
 }
 
-void MeshManagerModel::AddEmptyMesh_(){
-       MeshModel *meshModel = new MeshModel(meshId);
-       _meshes.push_back(meshModel);
+void MeshManagerModel::AddEmptyMesh_()
+{
+       _meshes.push_back(std::make_shared<MeshModel>(meshId));
        meshId++;
 }
 
-void MeshManagerModel::AddEmptyMesh(){
+void MeshManagerModel::AddEmptyMesh()
+{
        AddEmptyMesh_();
+       Save();
        RefreshOutputs(true);
 }
 
@@ -199,26 +324,27 @@ void MeshManagerModel::InsertMeshesAtCurrent_(std::vector<vtkPolyData*> meshList
 {
        if(!meshList.empty())
        {
-               std::vector<MeshModel*> tmpVect;
+               std::vector<std::shared_ptr<MeshModel>> 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<MeshModel>(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<vtkPolyData*> meshList)
 {
        InsertMeshesAtCurrent_(meshList);
+       Save();
        RefreshOutputs(true);
 }
 
-void MeshManagerModel::SelectMesh(int i) {
+void MeshManagerModel::SelectMesh(int i) 
+{
        if(i >= 0 && i < _meshes.size()){
                int prevCurrent = currentMesh;
                currentMesh = i;
@@ -231,7 +357,8 @@ void MeshManagerModel::SelectMesh(int i) {
        }
 }
 
-void MeshManagerModel::SelectMeshByName(std::string meshName) {
+void MeshManagerModel::SelectMeshByName(std::string meshName) 
+{
        if(!_meshes.empty()){
                bool found = false;
                for(int i = 0; i < _meshes.size() && !found; i++){
@@ -243,60 +370,77 @@ void MeshManagerModel::SelectMeshByName(std::string meshName) {
        }
 }
 
-void MeshManagerModel::DeleteMesh(int position){
+void MeshManagerModel::DeleteMesh_(int position)
+{
        if(position >= 0 && position < _meshes.size()){
-               delete _meshes.at(position);
                _meshes.erase(_meshes.begin() + position);
                currentMesh = currentMesh + (position <= currentMesh?-1:0);
                if(currentMesh < 0){
                        currentMesh = 0;
                }
-               RefreshOutputs(true);
        }
 }
 
-void MeshManagerModel::DeleteMeshByName(std::string meshName){
+void MeshManagerModel::DeleteMesh(int position)
+{
+       DeleteMesh_(position);
+       Save();
+       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){
                                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()){
+               DeleteMesh_(currentMesh);
+               Save();
                RefreshOutputs(true);
        }
 }
 
-void MeshManagerModel::DeleteAll(){
-       if(!_meshes.empty()){   
-               for (MeshModel* element : _meshes)
-               {
-                       delete element;
-               } 
+void MeshManagerModel::ReplaceMesh(std::vector<vtkPolyData*> meshList)
+{
+       if(GetNumberOfMeshes() >= 1)
+       {
+               DeleteMesh_(currentMesh);
+       }
+       InsertMeshesAtCurrent_(meshList);
+       Save();
+       RefreshOutputs(true);
+}
+
+void MeshManagerModel::DeleteAll_()
+{
+       if(!_meshes.empty())
+       {
+               currentMesh = 0;
                _meshes.clear();
                RefreshOutputs(true);
        }
 }
 
-void MeshManagerModel::NextMesh(){
+void MeshManagerModel::DeleteAll()
+{
+       DeleteAll_();
+       Save();
+       RefreshOutputs(true);
+}
+
+void MeshManagerModel::NextMesh()
+{
        currentMesh++;
        if(currentMesh >= _meshes.size()){
                currentMesh = _meshes.size()-1;
@@ -304,7 +448,8 @@ void MeshManagerModel::NextMesh(){
        RefreshOutputs(true);
 }
 
-void MeshManagerModel::PreviousMesh(){
+void MeshManagerModel::PreviousMesh()
+{
        currentMesh--;
        if(currentMesh < 0){
                currentMesh = 0;
@@ -312,7 +457,8 @@ void MeshManagerModel::PreviousMesh(){
        RefreshOutputs(true);
 }
 
-MeshModel* MeshManagerModel::GetMeshModel(){
+std::shared_ptr<MeshModel> MeshManagerModel::GetMeshModel()
+{
        return _meshes.at(currentMesh);
 }
 
@@ -339,44 +485,47 @@ vtkPolyData*  MeshManagerModel::GetMeshTemp()
 void MeshManagerModel::SetMeshBase(vtkPolyData* mesh)
 {
     if(!_meshes.empty()){
+        _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
         _meshes.at(currentMesh)->SetMeshBase(mesh);
+        Save();
         RefreshOutputs(true);
     }else{
-       printf("PG MeshManagerModel::SetMeshMemoryMode Mesh vector is empty \n");
+       printf("PG MeshManagerModel::SetMeshBase Mesh vector is empty \n");
     }
 }
 
 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);
        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())
+       {
+               _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
                _meshes.at(currentMesh)->CopySetMeshBase(mesh);
+               Save();
                RefreshOutputs(true);
        }
        else{
@@ -392,3 +541,59 @@ std::vector<std::string> MeshManagerModel::GetMeshNames()
        }
        return names;
 }
+
+void MeshManagerModel::Undo()
+{      
+       RestoreState(history->Undo());
+       RefreshOutputs(true);
+}
+
+void MeshManagerModel::Redo()
+{
+       RestoreState(history->Redo());
+       RefreshOutputs(true);
+}
+
+void MeshManagerModel::Save()
+{
+       history->Save(new ManagerState(_meshes, meshId, currentMesh));
+}
+
+void MeshManagerModel::RestoreState(ManagerState* state)
+{
+       if(state != NULL)
+       {       
+               _meshes = state->GetMeshes();
+               meshId = state->GetMeshId();
+               currentMesh = state->GetCurrentMesh();
+       }
+}
+
+//
+//Manager State
+//
+MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int currentMesh)
+{
+       savedMeshes = meshesToSave;
+       savedId = meshId;
+       savedCurrentMesh = currentMesh;
+}
+
+MeshManagerModel::ManagerState::~ManagerState()
+{
+}
+
+std::vector<std::shared_ptr<MeshModel>>& MeshManagerModel::ManagerState::GetMeshes()
+{
+       return savedMeshes;
+}
+
+int MeshManagerModel::ManagerState::GetMeshId()
+{
+       return savedId;
+}
+int MeshManagerModel::ManagerState::GetCurrentMesh()
+{
+       return savedCurrentMesh;
+}
+
index b679255a55e1686afbf39b4ad59a030752c4aedf..d8e6a780a52814ed6cd5a22087b093262f364f7c 100644 (file)
 # ------------------------------------------------------------------------
 */
 #include <vtkPolyData.h>
+#include <deque>
+#include <memory>
+
+template<class StateType>
+class HistoryHandler{
+public:
+       HistoryHandler(int maxElements);
+       ~HistoryHandler();
+       void            CleanHistory();
+       StateType*      Undo();
+       StateType*      Redo();
+       void            Save(StateType* State);
+       int             UndoSize();
+       int             RedoSize();
+       
+private:
+       std::deque<StateType*>  undoStack;
+       std::deque<StateType*>  redoStack;
+       int                                     maxElements;
+};
 
 class MeshModel{
 
 public:
        MeshModel(int id);
        MeshModel(vtkPolyData* mesh, int id);
+       MeshModel(MeshModel* meshModel);
        ~MeshModel();
        
        void                    SetMeshBase(vtkPolyData* mesh);
@@ -43,13 +64,14 @@ public:
     int                        GetId();
     std::string        GetName();
     
+
 protected:
 
 private:
-       vtkPolyData                             *_meshBase;
-    vtkPolyData                                *_meshTemp;
-    int                                                        _meshId;
-    std::string                                        _name;
+       vtkPolyData     *_meshBase;
+    vtkPolyData        *_meshTemp;
+    int                                _meshId;
+    std::string                _name;
 };
 
 #ifndef _MESHMANAGERMODEL_H_
@@ -68,8 +90,13 @@ class MeshManagerModel
 //---------------------------------------------
 public :
   MeshManagerModel();
+  MeshManagerModel(std::vector<vtkPolyData*> meshList);
   ~MeshManagerModel();
 
+       void ResetHistory();
+       void ResetAll();
+       
+       void UpdateMeshReference(vtkPolyData* mesh);
     void SetMeshBase(vtkPolyData* mesh);
     void SetMeshMemoryMode(vtkPolyData* mesh);
     void CopySetMeshBase(vtkPolyData* mesh);
@@ -80,7 +107,7 @@ public :
     
     virtual void RefreshOutputs(bool signalBox);
     
-    MeshModel* GetMeshModel();
+    std::shared_ptr<MeshModel> GetMeshModel();
     int GetNumberOfMeshes();
     
     void AddMesh_(vtkPolyData* mesh);
@@ -95,14 +122,28 @@ public :
     void InsertMeshesAtCurrent_(std::vector<vtkPolyData*> meshList);
     void InsertMeshesAtCurrent(std::vector<vtkPolyData*> meshList);
     
+    void InsertMeshModels_(std::vector<MeshModel*> meshModelList);
+       void InsertMeshModels(std::vector<MeshModel*> meshModelList);
+    
     void SelectMesh(int i);
     void SelectMeshByName(std::string meshName);
+    
+    void DeleteMesh_(int position);
     void DeleteMesh(int position);
     void DeleteMeshByName(std::string meshName);
     void DeleteCurrentMesh();
+    
+    void DeleteAll_();
     void DeleteAll();
+    
+    void ReplaceMesh(std::vector<vtkPolyData*> meshList);
+    
     void NextMesh();
     void PreviousMesh();
+    
+    void Undo();
+    void Redo();
+    
     std::vector<std::string> GetMeshNames();
 
 //--Method template----------------------------
@@ -119,9 +160,29 @@ protected:
 //---------------------------------------------
 private:
     
-    std::vector<MeshModel*>    _meshes;
-    int                                                currentMesh;
-    int                                                        meshId;
+    std::vector<std::shared_ptr<MeshModel>> _meshes;
+    int                                                                        currentMesh;
+    int                                                                                meshId;
+    
+    class ManagerState{
+       public:
+               ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int currentMesh);
+               ~ManagerState();
+               std::vector<std::shared_ptr<MeshModel>>& GetMeshes();
+               int GetMeshId();
+               int GetCurrentMesh();
+       private:
+               std::vector<std::shared_ptr<MeshModel>> savedMeshes;
+               int savedCurrentMesh;
+               int savedId;
+    };
+    
+    void                                                       Save();
+    void                                                       RestoreState(ManagerState* state);
+    
+    HistoryHandler<ManagerState>       *history;
+    
+    
 };
 
 //-end of _MESHMANAGERMODEL_H_------------------------------------------------------