From cc1075b3a78bdc5339b919450b88178bbf9ff1f7 Mon Sep 17 00:00:00 2001 From: Pablo Garzon Date: Tue, 30 May 2023 20:00:11 +0200 Subject: [PATCH] #3507 Undo and Redo Meshes --- ...bcreaVtkBooleanOperationPolyDataFilter.cxx | 34 +- .../src/bbcreaVtkCreateMeshFromPoints.cxx | 78 ++++- bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx | 2 + .../src/bbcreaVtkMeshManager_tool.cxx | 26 +- .../src/bbcreaVtkMeshManager_tool.h | 2 +- .../bbcreaVtkPolyDataConnectivityFilter.cxx | 4 +- .../src/bbcreaVtkPolyDataNormals.cxx | 3 +- lib/creaVtk/MeshManagerModel.cpp | 331 ++++++++++++++---- lib/creaVtk/MeshManagerModel.h | 77 +++- 9 files changed, 426 insertions(+), 131 deletions(-) diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkBooleanOperationPolyDataFilter.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkBooleanOperationPolyDataFilter.cxx index 79a92c2..f610d86 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkBooleanOperationPolyDataFilter.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkBooleanOperationPolyDataFilter.cxx @@ -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() ); */ diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx index 58448a4..b804dff 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx @@ -38,6 +38,7 @@ void CreateMeshFromPoints::Process() std::vector lstY = bbGetInputLstY(); std::vector lstZ = bbGetInputLstZ(); std::vector 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;iInsertNextPoint(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 cells = vtkSmartPointer::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 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 triangleStripBottom = vtkSmartPointer::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); } diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx index 3fa8d4b..9e64145 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager.cxx @@ -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 ); diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx index e39e25f..546ba74 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.cxx @@ -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 diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.h b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.h index 76ba719..d5723c0 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.h +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkMeshManager_tool.h @@ -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,""); BBTK_INPUT(MeshManager_tool,StringParam,"String input",std::string,""); diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataConnectivityFilter.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataConnectivityFilter.cxx index fdce1f4..b2becd1 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataConnectivityFilter.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataConnectivityFilter.cxx @@ -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 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 output; connFilter->SetInputData( bbGetInputIn() ); connFilter->SetExtractionModeToSpecifiedRegions(); connFilter->Update(); diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataNormals.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataNormals.cxx index b560cc9..46bc24a 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataNormals.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkPolyDataNormals.cxx @@ -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); diff --git a/lib/creaVtk/MeshManagerModel.cpp b/lib/creaVtk/MeshManagerModel.cpp index 677727c..c03e9e8 100644 --- a/lib/creaVtk/MeshManagerModel.cpp +++ b/lib/creaVtk/MeshManagerModel.cpp @@ -27,6 +27,82 @@ #include "MeshManagerModel.h" +template +HistoryHandler::HistoryHandler(int maxElements) +{ + this->maxElements = maxElements; +} +template +HistoryHandler::~HistoryHandler() +{ + CleanHistory(); +} + +template +void HistoryHandler::CleanHistory() +{ + for (T* element : redoStack) + { + delete element; + } + for (T* element : undoStack) + { + delete element; + } +} + +template +T* HistoryHandler::Undo() +{ + if(!undoStack.empty() && undoStack.size()>1) + { + auto lastElem = undoStack.back(); + undoStack.pop_back(); + redoStack.push_back(lastElem); + return undoStack.back(); + } + return NULL; +} + +template +T* HistoryHandler::Redo() +{ + if(!redoStack.empty()) + { + auto lastElem = redoStack.back(); + redoStack.pop_back(); + undoStack.push_back(lastElem); + return lastElem; + } + return NULL; +} + +template +void HistoryHandler::Save(T* state) +{ + undoStack.push_back(state); + if(!redoStack.empty()) + { + for (T* element : redoStack) + { + delete element; + } + redoStack.clear(); + } +} + +template +int HistoryHandler::UndoSize() +{ + return undoStack.size(); +} + +template +int HistoryHandler::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(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(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 meshList){ +void MeshManagerModel::AddMeshes_(std::vector meshList) +{ if(!meshList.empty()) { MeshModel *meshModel; for(int i = 0; i < meshList.size(); i++){ - meshModel = new MeshModel(meshList[i], meshId); - _meshes.push_back(meshModel); + _meshes.push_back(std::make_shared(meshList[i], meshId)); meshId++; } }else{ @@ -179,19 +300,23 @@ void MeshManagerModel::AddMeshes_(std::vector meshList){ } } -void MeshManagerModel::AddMeshes(std::vector meshList){ +void MeshManagerModel::AddMeshes(std::vector 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(meshId)); meshId++; } -void MeshManagerModel::AddEmptyMesh(){ +void MeshManagerModel::AddEmptyMesh() +{ AddEmptyMesh_(); + Save(); RefreshOutputs(true); } @@ -199,26 +324,27 @@ void MeshManagerModel::InsertMeshesAtCurrent_(std::vector meshList { if(!meshList.empty()) { - std::vector tmpVect; + std::vector> tmpVect; MeshModel *meshModel; for(int i = 0; i < meshList.size(); i++){ - meshModel = new MeshModel(meshList[i], meshId); - tmpVect.push_back(meshModel); + tmpVect.push_back(std::make_shared(meshList[i], meshId)); meshId++; } _meshes.insert(_meshes.begin() + currentMesh, tmpVect.begin(), tmpVect.end()); }else{ - printf("PG MeshManagerModel::AddMeshes Empty list of meshes \n"); + printf("PG MeshManagerModel::InsertMeshesAtCurrent Empty list of meshes \n"); } } void MeshManagerModel::InsertMeshesAtCurrent(std::vector meshList) { 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 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 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(_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(_meshes.at(currentMesh).get()); _meshes.at(currentMesh)->CopySetMeshBase(mesh); + Save(); RefreshOutputs(true); } else{ @@ -392,3 +541,59 @@ std::vector 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> meshesToSave, int meshId, int currentMesh) +{ + savedMeshes = meshesToSave; + savedId = meshId; + savedCurrentMesh = currentMesh; +} + +MeshManagerModel::ManagerState::~ManagerState() +{ +} + +std::vector>& MeshManagerModel::ManagerState::GetMeshes() +{ + return savedMeshes; +} + +int MeshManagerModel::ManagerState::GetMeshId() +{ + return savedId; +} +int MeshManagerModel::ManagerState::GetCurrentMesh() +{ + return savedCurrentMesh; +} + diff --git a/lib/creaVtk/MeshManagerModel.h b/lib/creaVtk/MeshManagerModel.h index b679255..d8e6a78 100644 --- a/lib/creaVtk/MeshManagerModel.h +++ b/lib/creaVtk/MeshManagerModel.h @@ -25,12 +25,33 @@ # ------------------------------------------------------------------------ */ #include +#include +#include + +template +class HistoryHandler{ +public: + HistoryHandler(int maxElements); + ~HistoryHandler(); + void CleanHistory(); + StateType* Undo(); + StateType* Redo(); + void Save(StateType* State); + int UndoSize(); + int RedoSize(); + +private: + std::deque undoStack; + std::deque 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 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 GetMeshModel(); int GetNumberOfMeshes(); void AddMesh_(vtkPolyData* mesh); @@ -95,14 +122,28 @@ public : void InsertMeshesAtCurrent_(std::vector meshList); void InsertMeshesAtCurrent(std::vector meshList); + void InsertMeshModels_(std::vector meshModelList); + void InsertMeshModels(std::vector 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 meshList); + void NextMesh(); void PreviousMesh(); + + void Undo(); + void Redo(); + std::vector GetMeshNames(); //--Method template---------------------------- @@ -119,9 +160,29 @@ protected: //--------------------------------------------- private: - std::vector _meshes; - int currentMesh; - int meshId; + std::vector> _meshes; + int currentMesh; + int meshId; + + class ManagerState{ + public: + ManagerState(std::vector> meshesToSave, int meshId, int currentMesh); + ~ManagerState(); + std::vector>& GetMeshes(); + int GetMeshId(); + int GetCurrentMesh(); + private: + std::vector> savedMeshes; + int savedCurrentMesh; + int savedId; + }; + + void Save(); + void RestoreState(ManagerState* state); + + HistoryHandler *history; + + }; //-end of _MESHMANAGERMODEL_H_------------------------------------------------------ -- 2.45.1