#include "MeshManagerModel.h"
+//
+//HISTORY HANDLER
+//
+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;
+ }
+ redoStack.clear();
+ for (T* element : undoStack)
+ {
+ delete element;
+ }
+ undoStack.clear();
+}
+
+template <class T>
+T* HistoryHandler<T>::Undo(T* state)
+{
+ if(state == NULL)
+ {
+ return NULL;
+ }
+ if(!undoStack.empty())
+ {
+ auto lastElem = undoStack.back();
+ undoStack.pop_back();
+ redoStack.push_back(state);
+ return lastElem;
+ }else{
+ delete state;
+ }
+ return NULL;
+}
+
+template <class T>
+T* HistoryHandler<T>::Redo(T* state)
+{
+ if(state == NULL)
+ {
+ return NULL;
+ }
+ if(!redoStack.empty())
+ {
+ auto lastElem = redoStack.back();
+ redoStack.pop_back();
+ undoStack.push_back(state);
+ return lastElem;
+ }else{
+ delete state;
+ return NULL;
+ }
+}
+
+/**
+* To be used with RedoKeepCurrent
+* Will always maintain the current state in the undo stack as the first element
+* Useful when states are saved after actions and the initial state is saved.
+*/
+template <class T>
+T* HistoryHandler<T>::UndoKeepCurrent()
+{
+ if(undoStack.size() > 1)
+ {
+ auto lastElem = undoStack.back();
+ undoStack.pop_back();
+ redoStack.push_back(lastElem);
+ return undoStack.back();
+ }else{
+ return NULL;
+ }
+}
+
+/**
+* To be used with UndoKeepCurrent
+* Will always maintain the current state in the undo stack as the first element
+* Useful when states are saved after actions and the initial state is saved.
+*/
+template <class T>
+T* HistoryHandler<T>::RedoKeepCurrent()
+{
+ if(!redoStack.empty())
+ {
+ auto lastElem = redoStack.back();
+ redoStack.pop_back();
+ undoStack.push_back(lastElem);
+ return undoStack.back();
+ }else{
+ return NULL;
+ }
+}
+
+template <class T>
+void HistoryHandler<T>::Save(T* state)
+{
+ undoStack.push_back(state);
+ if(undoStack.size() > maxElements)
+ {
+ T* frontDel = undoStack.front();
+ undoStack.pop_front();
+ delete frontDel;
+ }
+ if(!redoStack.empty())
+ {
+ for (T* element : redoStack)
+ {
+ delete element;
+ }
+ redoStack.clear();
+ }
+}
+
+template <class T>
+T* HistoryHandler<T>::GetPrevious()
+{
+ if(!undoStack.empty())
+ {
+ return undoStack.back();
+ }
+ return NULL;
+}
+
+template <class T>
+T* HistoryHandler<T>::GetNext()
+{
+ if(!redoStack.empty())
+ {
+ return redoStack.back();
+ }
+ return NULL;
+}
+
+template <class T>
+int HistoryHandler<T>::UndoSize()
+{
+ return undoStack.size();
+}
+
+template <class T>
+int HistoryHandler<T>::RedoSize()
+{
+ return redoStack.size();
+}
+
////////////////////
/////////////////////// MESH MODEL
////////////////////
MeshModel::MeshModel(vtkPolyData* mesh, int id)
{
- if(mesh != NULL){
- _meshBase = mesh;
+ if(mesh != NULL)
+ {
+ _meshBase = vtkPolyData::New();
+ _meshBase->DeepCopy(mesh);
_meshTemp = vtkPolyData::New();
_meshTemp->DeepCopy(_meshBase);
_meshId = id;
}
}
-MeshModel::~MeshModel(){
- if(_meshBase != NULL){
+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();
}
- if(_meshTemp != NULL){
+ if(_meshTemp != NULL)
+ {
_meshTemp->Delete();
}
}
_meshTemp = vtkPolyData::New();
_meshTemp->DeepCopy(_meshBase);
} else {
- _meshTemp=NULL;
+ if (_meshTemp!=NULL)
+ {
+ _meshTemp->Delete();
+ _meshTemp = NULL;
+ }
}
}
{
if (mesh!=NULL)
{
- _meshBase = mesh;
+ if(_meshBase != NULL)
+ {
+ _meshBase->Delete();
+ }
+ _meshBase = vtkPolyData::New();
+ _meshBase->DeepCopy(mesh);
ResetMeshTemp_();
} // if mesh
}
void MeshModel::SetMeshMemoryMode(vtkPolyData* mesh)
{
- _meshBase = mesh;
+ if(_meshBase != NULL)
+ {
+ _meshBase->Delete();
+ _meshBase = NULL;
+ }
+ if(mesh != NULL)
+ {
+ _meshBase = vtkPolyData::New();
+ _meshBase->DeepCopy(mesh);
+ }
}
void MeshModel::ResetMeshTemp()
}
-vtkPolyData* MeshModel::GetMeshBase()
+vtkPolyData* MeshModel::GetMeshBase()
{
return _meshBase;
}
-vtkPolyData* MeshModel::GetMeshTemp()
+vtkPolyData* MeshModel::GetMeshTemp()
{
return _meshTemp;
}
MeshManagerModel::MeshManagerModel()
{
- //MeshModel* firstMesh = new MeshModel();
- //_meshes.push_back(firstMesh);
currentMesh = 0;
meshId = 0;
+ history = new HistoryHandler<ManagerState>(15);
+ lastModified = 0;
+ memoryMode = false;
+ referencePoint = {0, 0, 0};
+ referenceNormal = {0, 0, 1};
}
MeshManagerModel::~MeshManagerModel()
{
DeleteAll();
+ history->CleanHistory();
+ delete history;
}
void MeshManagerModel::RefreshOutputs(bool signalBox) // virtual
{
}
-int MeshManagerModel::GetNumberOfMeshes(){
+void MeshManagerModel::SetHistory(int maxCapacity)
+{
+ if(history != NULL){
+ ResetHistory();
+ delete history;
+ }
+ history = new HistoryHandler<ManagerState>(maxCapacity);
+}
+
+void MeshManagerModel::ResetHistory()
+{
+ history->CleanHistory();
+}
+
+void MeshManagerModel::SetReferencePoint(std::vector<double> point)
+{
+ referencePoint = point;
+}
+
+std::vector<double> MeshManagerModel::GetReferencePoint()
+{
+ return referencePoint;
+}
+
+void MeshManagerModel::SetReferenceNormal(std::vector<double> normal)
+{
+ referenceNormal = normal;
+}
+
+std::vector<double> MeshManagerModel::GetReferenceNormal()
+{
+ return referenceNormal;
+}
+
+int MeshManagerModel::GetNumberOfMeshes()
+{
return _meshes.size();
}
-void MeshManagerModel::AddMesh_(vtkPolyData* mesh){
- if(mesh != NULL){
- MeshModel *meshModel = new MeshModel(mesh, meshId);
- _meshes.push_back(meshModel);
+void MeshManagerModel::AddMesh_(vtkPolyData* mesh)
+{
+ if(mesh != NULL)
+ {
+ _meshes.push_back(std::make_shared<MeshModel>(mesh, meshId));
meshId++;
- }
- else{
+ }else{
printf("PG MeshManagerModel::AddMesh Mesh is null \n");
}
}
-void MeshManagerModel::AddMesh(vtkPolyData* mesh){
+void MeshManagerModel::AddMesh(vtkPolyData* mesh)
+{
+ Save();
AddMesh_(mesh);
+ lastModified = currentMesh;
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{
}
}
-void MeshManagerModel::AddMeshes(std::vector<vtkPolyData*> meshList){
+void MeshManagerModel::AddMeshes(std::vector<vtkPolyData*> meshList)
+{
+ Save();
AddMeshes_(meshList);
+ lastModified = currentMesh;
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()
+{
+ Save();
AddEmptyMesh_();
+ lastModified = currentMesh;
RefreshOutputs(true);
}
{
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)
{
+ Save();
InsertMeshesAtCurrent_(meshList);
+ lastModified = currentMesh;
RefreshOutputs(true);
}
-void MeshManagerModel::SelectMesh(int i) {
- if(i >= 0 && i < _meshes.size()){
+void MeshManagerModel::SelectMesh(int i)
+{
+ if(i >= 0 && i < _meshes.size())
+ {
int prevCurrent = currentMesh;
currentMesh = i;
- if(prevCurrent != i){
+ if(prevCurrent != i)
+ {
RefreshOutputs(true);
}
}
}
}
-void MeshManagerModel::SelectMeshByName(std::string meshName) {
- if(!_meshes.empty()){
+void MeshManagerModel::SelectMeshByName(std::string meshName)
+{
+ if(!_meshes.empty())
+ {
bool found = false;
for(int i = 0; i < _meshes.size() && !found; i++){
- if(_meshes.at(i)->GetName() == meshName){
+ if(_meshes.at(i)->GetName() == meshName)
+ {
found = true;
SelectMesh(i);
}
}
}
-void MeshManagerModel::DeleteMesh(int position){
- if(position >= 0 && position < _meshes.size()){
- delete _meshes.at(position);
+void MeshManagerModel::DeleteMesh_(int position)
+{
+ if(position >= 0 && position < _meshes.size())
+ {
_meshes.erase(_meshes.begin() + position);
currentMesh = currentMesh + (position <= currentMesh?-1:0);
- if(currentMesh < 0){
+ if(currentMesh < 0)
+ {
currentMesh = 0;
}
- RefreshOutputs(true);
}
}
-void MeshManagerModel::DeleteMeshByName(std::string meshName){
- if(!_meshes.empty()){
+void MeshManagerModel::DeleteMesh(int position)
+{
+ Save();
+ DeleteMesh_(position);
+ lastModified = currentMesh;
+ 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){
+ 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())
+ {
+ Save();
+ DeleteMesh_(currentMesh);
+ lastModified = currentMesh;
RefreshOutputs(true);
}
}
-void MeshManagerModel::DeleteAll(){
- if(!_meshes.empty()){
- for (MeshModel* element : _meshes)
- {
- delete element;
- }
+void MeshManagerModel::ReplaceMesh(std::vector<vtkPolyData*> meshList)
+{
+ Save();
+ if(GetNumberOfMeshes() >= 1)
+ {
+ DeleteMesh_(currentMesh);
+ }
+ InsertMeshesAtCurrent_(meshList);
+ lastModified = currentMesh;
+ RefreshOutputs(true);
+}
+
+void MeshManagerModel::DeleteAll_()
+{
+ if(!_meshes.empty())
+ {
+ currentMesh = 0;
_meshes.clear();
RefreshOutputs(true);
}
}
-void MeshManagerModel::NextMesh(){
+void MeshManagerModel::DeleteAll()
+{
+ Save();
+ DeleteAll_();
+ lastModified = currentMesh;
+ RefreshOutputs(true);
+}
+
+void MeshManagerModel::NextMesh()
+{
currentMesh++;
- if(currentMesh >= _meshes.size()){
+ if(currentMesh >= _meshes.size())
+ {
currentMesh = _meshes.size()-1;
}
RefreshOutputs(true);
}
-void MeshManagerModel::PreviousMesh(){
+void MeshManagerModel::PreviousMesh()
+{
currentMesh--;
- if(currentMesh < 0){
+ if(currentMesh < 0)
+ {
currentMesh = 0;
}
RefreshOutputs(true);
}
-MeshModel* MeshManagerModel::GetMeshModel(){
+std::shared_ptr<MeshModel> MeshManagerModel::GetMeshModel()
+{
return _meshes.at(currentMesh);
}
vtkPolyData* MeshManagerModel::GetMeshBase()
{
- if(!_meshes.empty()){
+ if(!_meshes.empty())
+ {
return _meshes.at(currentMesh)->GetMeshBase();
}
else{
vtkPolyData* MeshManagerModel::GetMeshTemp()
{
- if(!_meshes.empty()){
+ if(!_meshes.empty())
+ {
return _meshes.at(currentMesh)->GetMeshTemp();
}
else{
void MeshManagerModel::SetMeshBase(vtkPolyData* mesh)
{
- if(!_meshes.empty()){
+ if(!_meshes.empty())
+ {
+ Save();
+ _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
_meshes.at(currentMesh)->SetMeshBase(mesh);
+ lastModified = currentMesh;
RefreshOutputs(true);
}else{
- printf("PG MeshManagerModel::SetMeshMemoryMode Mesh vector is empty \n");
+ printf("PG MeshManagerModel::SetMeshBase Mesh vector is empty \n");
}
}
+void MeshManagerModel::MeshMemoryModeOn()
+{
+ memoryMode = true;
+}
+
+void MeshManagerModel::MeshMemoryModeOff()
+{
+ memoryMode = false;
+}
+
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);
+ ResetHistory();
+ SaveMemoryMode();
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())
+ {
+ Save();
+ _meshes.at(currentMesh) = std::make_shared<MeshModel>(_meshes.at(currentMesh).get());
_meshes.at(currentMesh)->CopySetMeshBase(mesh);
+ lastModified = currentMesh;
RefreshOutputs(true);
}
else{
}
return names;
}
+
+std::vector<vtkPolyData*> MeshManagerModel::GetAllPolyDatas()
+{
+ std::vector<vtkPolyData*> polydatas;
+ for(int i = 0; i < _meshes.size(); i++){
+ polydatas.push_back(_meshes.at(i)->GetMeshBase());
+ }
+ return polydatas;
+}
+
+int MeshManagerModel::GetCurrentMesh()
+{
+ return currentMesh;
+}
+
+void MeshManagerModel::Undo()
+{
+ if(history->UndoSize() > 0)
+ {
+ if(memoryMode == false){
+ RestoreState(history->Undo(new ManagerState(_meshes, meshId, lastModified)));
+ RefreshOutputs(true);
+ }
+ else if(history->UndoSize() > 1){
+ RestoreStateMemoryMode(history->UndoKeepCurrent());
+ }
+ }
+}
+
+void MeshManagerModel::Redo()
+{
+ if(history->RedoSize() > 0)
+ {
+ if(memoryMode == false){
+ RestoreState(history->Redo(new ManagerState(_meshes, meshId, lastModified)));
+ RefreshOutputs(true);
+ }
+ else{
+ RestoreStateMemoryMode(history->RedoKeepCurrent());
+ }
+ }
+}
+
+void MeshManagerModel::Save()
+{
+ history->Save(new ManagerState(_meshes, meshId, currentMesh));
+}
+
+void MeshManagerModel::SaveMemoryMode()
+{
+ if(_meshes.size() == 1 && memoryMode)
+ {
+ std::vector<std::shared_ptr<MeshModel>> savedMesh;
+ savedMesh.push_back(std::make_shared<MeshModel>(_meshes.at(0).get()));
+ history->Save(new ManagerState(savedMesh, meshId, 0, referencePoint, referenceNormal));
+ }
+ else{
+ printf("PG MeshManagerModel::SaveMemoryMode WARNING Mesh vector has invalid size or memoryMode is not set \n");
+ }
+}
+
+void MeshManagerModel::RestoreState(ManagerState* state)
+{
+ if(state != NULL)
+ {
+ _meshes = state->GetMeshes();
+ meshId = state->GetMeshId();
+ currentMesh = state->GetModifiedPos();
+ lastModified = state->GetModifiedPos();
+ delete state;
+ }
+ else{
+ printf("PG MeshManagerModel::RestoreState WARNING State is NULL \n");
+ }
+}
+
+void MeshManagerModel::RestoreStateMemoryMode(ManagerState* state){
+ if(_meshes.size() == 1 && state != NULL)
+ {
+ vtkPoints* statePoints = vtkPoints::New();
+ statePoints->DeepCopy(state->GetMeshes().at(0)->GetMeshBase()->GetPoints());
+ _meshes.at(0)->GetMeshBase()->SetPoints(statePoints);
+ _meshes.at(0)->GetMeshBase()->GetPoints()->Modified();
+ _meshes.at(0)->GetMeshBase()->Modified();
+ referencePoint = state->GetReferencePoint();
+ referenceNormal = state->referenceNormal;
+ }else{
+ printf("PG MeshManagerModel::RestoreStateMemoryMode WARNING Mesh vector has invalid size or state is NULL\n");
+ }
+}
+
+//
+//Manager State
+//
+MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int modifiedPos)
+{
+ savedMeshes = meshesToSave;
+ savedId = meshId;
+ savedModifiedPos = modifiedPos;
+}
+
+MeshManagerModel::ManagerState::ManagerState(std::vector<std::shared_ptr<MeshModel>> meshesToSave, int meshId, int modifiedPos, std::vector<double> refPoint, std::vector<double> refNormal)
+{
+ savedMeshes = meshesToSave;
+ savedId = meshId;
+ savedModifiedPos = modifiedPos;
+ referencePoint = refPoint;
+ referenceNormal = refNormal;
+}
+
+MeshManagerModel::ManagerState::~ManagerState()
+{
+ savedMeshes.clear();
+}
+
+std::vector<std::shared_ptr<MeshModel>>& MeshManagerModel::ManagerState::GetMeshes()
+{
+ return savedMeshes;
+}
+
+int MeshManagerModel::ManagerState::GetMeshId()
+{
+ return savedId;
+}
+int MeshManagerModel::ManagerState::GetModifiedPos()
+{
+ return savedModifiedPos;
+}
+
+std::vector<double>& MeshManagerModel::ManagerState::GetReferencePoint()
+{
+ return referencePoint;
+}