diff --git a/Modules/Simulation/mitkSimulation.cpp b/Modules/Simulation/mitkSimulation.cpp index 181bd9f969..c499c7b059 100644 --- a/Modules/Simulation/mitkSimulation.cpp +++ b/Modules/Simulation/mitkSimulation.cpp @@ -1,158 +1,238 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimulation.h" +#include "mitkSimulationPropAssemblyVisitor.h" +#include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include const float mitk::Simulation::ScaleFactor = 1000.0f; static sofa::simulation::Simulation::SPtr CreateSimulation(mitk::Simulation::SimulationType type = mitk::Simulation::Tree) { if (type == mitk::Simulation::DAG) return sofa::core::objectmodel::New(); else if (type == mitk::Simulation::Bgl) return sofa::core::objectmodel::New(); else return sofa::core::objectmodel::New(); } void mitk::Simulation::SetActiveSimulation(mitk::Simulation* simulation) { if (simulation == NULL) { sofa::simulation::setSimulation(NULL); sofa::core::visual::VisualParams::defaultInstance()->drawTool() = NULL; } else { sofa::simulation::Simulation* sofaSimulation = simulation->m_Simulation.get(); if (sofa::simulation::getSimulation() != sofaSimulation) { sofa::simulation::setSimulation(sofaSimulation); sofa::core::visual::VisualParams::defaultInstance()->drawTool() = &simulation->m_DrawTool; } } } mitk::Simulation::Simulation() : m_Simulation(CreateSimulation()), m_DefaultDT(0.0) { } mitk::Simulation::~Simulation() { if (m_Simulation != NULL) { if (m_RootNode != NULL) m_Simulation->unload(m_RootNode); if (sofa::simulation::getSimulation() == m_Simulation.get()) SetActiveSimulation(NULL); } } +void mitk::Simulation::AppendSnapshot(mitk::Surface::Pointer surface) const +{ + if (surface.IsNull()) + return; + + vtkSmartPointer snapshot = this->CreateSnapshot(); + + if (snapshot != NULL) + { + unsigned int timeStep = surface->GetSizeOfPolyDataSeries(); + + if (timeStep != 0 && surface->GetVtkPolyData(timeStep - 1) == NULL) + --timeStep; + + surface->SetVtkPolyData(snapshot, timeStep); + } +} + +vtkSmartPointer mitk::Simulation::CreateSnapshot() const +{ + if (m_RootNode == NULL) + return NULL; + + vtkSmartPointer propAssembly = vtkSmartPointer::New(); + SimulationPropAssemblyVisitor propAssemblyVisitor(propAssembly); + + m_RootNode->executeVisitor(&propAssemblyVisitor); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + + vtkPropCollection* propCollection = propAssembly->GetParts(); + vtkProp* prop = NULL; + + for (propCollection->InitTraversal(); (prop = propCollection->GetNextProp()) != NULL; ) + { + vtkActor* actor = vtkActor::SafeDownCast(prop); + vtkPolyData* polyData = vtkPolyData::SafeDownCast(actor->GetMapper()->GetInput()); + + appendFilter->AddInput(polyData); + } + + vtkSmartPointer scaleTransform = vtkSmartPointer::New(); + scaleTransform->Scale(ScaleFactor, ScaleFactor, ScaleFactor); + + vtkSmartPointer transformFilter = vtkSmartPointer::New(); + transformFilter->SetInputConnection(appendFilter->GetOutputPort()); + transformFilter->SetTransform(scaleTransform); + + transformFilter->Update(); + + vtkSmartPointer snapshot = vtkSmartPointer::New(); + snapshot->ShallowCopy(transformFilter->GetOutputDataObject(0)); + + return snapshot; +} + double mitk::Simulation::GetDefaultDT() const { return m_DefaultDT; } mitk::SimulationDrawTool* mitk::Simulation::GetDrawTool() { return &m_DrawTool; } sofa::simulation::Node::SPtr mitk::Simulation::GetRootNode() const { return m_RootNode; } sofa::simulation::Simulation::SPtr mitk::Simulation::GetSimulation() const { return m_Simulation; } bool mitk::Simulation::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } void mitk::Simulation::SetAsActiveSimulation() { SetActiveSimulation(this); } void mitk::Simulation::SetDefaultDT(double dt) { m_DefaultDT = std::max(0.0, dt); } void mitk::Simulation::SetRequestedRegion(itk::DataObject*) { } void mitk::Simulation::SetRequestedRegionToLargestPossibleRegion() { } void mitk::Simulation::SetRootNode(sofa::simulation::Node* rootNode) { m_RootNode.reset(rootNode); } +mitk::Surface::Pointer mitk::Simulation::TakeSnapshot() const +{ + vtkSmartPointer snapshot = this->CreateSnapshot(); + + if (snapshot == NULL) + return NULL; + + Surface::Pointer surface = Surface::New(); + surface->SetVtkPolyData(snapshot); + + return surface; +} + void mitk::Simulation::UpdateOutputInformation() { if (this->GetSource().IsNotNull()) this->GetSource()->UpdateOutputInformation(); if (m_RootNode != NULL) { const sofa::defaulttype::BoundingBox& boundingBox = m_RootNode->f_bbox.getValue(); const sofa::defaulttype::Vector3& min = boundingBox.minBBox(); const sofa::defaulttype::Vector3& max = boundingBox.maxBBox(); mitk::Geometry3D::BoundsArrayType bounds; bounds[0] = static_cast(min.x() * ScaleFactor); bounds[1] = static_cast(max.x() * ScaleFactor); bounds[2] = static_cast(min.y() * ScaleFactor); bounds[3] = static_cast(max.y() * ScaleFactor); bounds[4] = static_cast(min.z() * ScaleFactor); bounds[5] = static_cast(max.z() * ScaleFactor); if(this->GetGeometry() != NULL) { this->GetGeometry()->SetBounds(bounds); } else { Geometry3D::Pointer geometry = Geometry3D::New(); geometry->SetBounds(bounds); this->SetGeometry(geometry); } } this->GetTimeSlicedGeometry()->UpdateInformation(); } bool mitk::Simulation::VerifyRequestedRegion() { return true; } diff --git a/Modules/Simulation/mitkSimulation.h b/Modules/Simulation/mitkSimulation.h index e0324cf73c..d58c61a614 100644 --- a/Modules/Simulation/mitkSimulation.h +++ b/Modules/Simulation/mitkSimulation.h @@ -1,71 +1,77 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkSimulation_h #define mitkSimulation_h #include "mitkSimulationDrawTool.h" -#include +#include #include #include +#include +#include namespace mitk { class Simulation_EXPORT Simulation : public BaseData { public: enum SimulationType { Tree, DAG, Bgl }; mitkClassMacro(Simulation, BaseData); itkNewMacro(Self); static void SetActiveSimulation(Self* simulation); static const float ScaleFactor; + void AppendSnapshot(Surface::Pointer surface) const; double GetDefaultDT() const; SimulationDrawTool* GetDrawTool(); sofa::simulation::Node::SPtr GetRootNode() const; sofa::simulation::Simulation::SPtr GetSimulation() const; bool RequestedRegionIsOutsideOfTheBufferedRegion(); void SetAsActiveSimulation(); void SetDefaultDT(double dt); void SetRequestedRegion(itk::DataObject* data); void SetRequestedRegionToLargestPossibleRegion(); void SetRootNode(sofa::simulation::Node* rootNode); + Surface::Pointer TakeSnapshot() const; void UpdateOutputInformation(); bool VerifyRequestedRegion(); private: Simulation(); ~Simulation(); Simulation(Self&); Self& operator=(const Self&); + vtkSmartPointer CreateSnapshot() const; + sofa::simulation::Simulation::SPtr m_Simulation; sofa::simulation::Node::SPtr m_RootNode; SimulationDrawTool m_DrawTool; double m_DefaultDT; }; } #endif diff --git a/Modules/Simulation/mitkSimulationDrawTool.cpp b/Modules/Simulation/mitkSimulationDrawTool.cpp index 6b566f2ca6..69687e89c4 100644 --- a/Modules/Simulation/mitkSimulationDrawTool.cpp +++ b/Modules/Simulation/mitkSimulationDrawTool.cpp @@ -1,643 +1,577 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimulation.h" #include "mitkSimulationDrawTool.h" -#include #include #include #include #include #include #include #include #include #include #include #include mitk::SimulationDrawTool::SimulationDrawTool() : m_PolygonMode(0), m_Wireframe(false), m_Update(true) { } mitk::SimulationDrawTool::~SimulationDrawTool() { - this->DeleteVtkObjects(); -} - -void mitk::SimulationDrawTool::DeleteVtkObjects() -{ - for (std::vector::const_iterator object = m_VtkObjects.begin(); object != m_VtkObjects.end(); ++object) - (*object)->Delete(); - - m_VtkObjects.clear(); - - for (std::vector::const_iterator actor = m_Actors.begin(); actor != m_Actors.end(); ++actor) - (*actor)->Delete(); - m_Actors.clear(); } void mitk::SimulationDrawTool::DisableUpdate() { m_Update = false; } - -std::vector mitk::SimulationDrawTool::GetActors() const +std::vector > mitk::SimulationDrawTool::GetActors() const { return m_Actors; } void mitk::SimulationDrawTool::InitProperty(vtkProperty* property) const { if (m_Wireframe) property->SetRepresentationToWireframe(); else property->SetRepresentationToSurface(); } void mitk::SimulationDrawTool::Reset() { - this->DeleteVtkObjects(); + m_Actors.clear(); m_Update = true; } void mitk::SimulationDrawTool::drawPoints(const std::vector& points, float pointSize, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numPoints = points.size(); - vtkPoints* vtkPoints = vtkPoints::New(); + vtkSmartPointer vtkPoints = vtkSmartPointer<::vtkPoints>::New(); vtkPoints->SetNumberOfPoints(numPoints); - vtkCellArray* cellArray = vtkCellArray::New(); + vtkSmartPointer cellArray = vtkSmartPointer::New(); for (unsigned int i = 0; i < numPoints; ++i) { vtkPoints->SetPoint(i, points[i].elems); cellArray->InsertNextCell(1); cellArray->InsertCellPoint(i); } - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(vtkPoints); polyData->SetVerts(cellArray); - vtkPoints->Delete(); - cellArray->Delete(); - - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyData); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); property->SetColor(color.x(), color.y(), color.z()); property->SetPointSize(pointSize); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } void mitk::SimulationDrawTool::drawLines(const std::vector& points, float lineWidth, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numPoints = points.size(); std::vector indices; for (unsigned int i = 0; i < numPoints; i += 2) indices.push_back(Vec2i(i, i + 1)); this->drawLines(points, indices, lineWidth, color); } void mitk::SimulationDrawTool::drawLines(const std::vector& points, const std::vector& indices, float lineWidth, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numPoints = points.size(); - vtkPoints* vtkPoints = vtkPoints::New(); + vtkSmartPointer vtkPoints = vtkSmartPointer<::vtkPoints>::New(); vtkPoints->SetNumberOfPoints(numPoints); for (unsigned int i = 0; i < numPoints; ++i) vtkPoints->SetPoint(i, points[i].elems); - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(vtkPoints); - vtkPoints->Delete(); - - vtkCellArray* lines = vtkCellArray::New(); + vtkSmartPointer lines = vtkSmartPointer::New(); unsigned int numIndices = indices.size(); for (unsigned int i = 0; i < numIndices; ++i) { lines->InsertNextCell(2); lines->InsertCellPoint(indices[i].elems[0]); lines->InsertCellPoint(indices[i].elems[1]); } polyData->SetLines(lines); - lines->Delete(); - - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyData); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); property->SetLineWidth(lineWidth); property->SetColor(color.x(), color.y(), color.z()); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } void mitk::SimulationDrawTool::drawTriangles(const std::vector& points, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numPoints = points.size(); - vtkPoints* vtkPoints = vtkPoints::New(); + vtkSmartPointer vtkPoints = vtkSmartPointer<::vtkPoints>::New(); vtkPoints->SetNumberOfPoints(numPoints); for (unsigned int i = 0; i < numPoints; ++i) vtkPoints->SetPoint(i, points[i].elems); - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(vtkPoints); - vtkPoints->Delete(); - - vtkCellArray* triangles = vtkCellArray::New(); + vtkSmartPointer triangles = vtkSmartPointer::New(); for (unsigned int i = 0; i < points.size(); i += 3) { triangles->InsertNextCell(3); triangles->InsertCellPoint(i); triangles->InsertCellPoint(i + 1); triangles->InsertCellPoint(i + 2); } polyData->SetPolys(triangles); - triangles->Delete(); - - vtkPolyDataNormals* polyDataNormals = vtkPolyDataNormals::New(); + vtkSmartPointer polyDataNormals = vtkSmartPointer::New(); polyDataNormals->ComputeCellNormalsOff(); polyDataNormals->SetInput(polyData); polyDataNormals->SplittingOff(); - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyDataNormals->GetOutput()); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); - this->InitProperty(property); - property->SetColor(color.x(), color.y(), color.z()); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); - m_VtkObjects.push_back(polyDataNormals); m_Actors.push_back(actor); } void mitk::SimulationDrawTool::drawTriangles(const std::vector& points, const Vector3 normal, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numPoints = points.size(); + unsigned int numNormals = numPoints / 3; - vtkPoints* vtkPoints = vtkPoints::New(); + vtkSmartPointer vtkPoints = vtkSmartPointer<::vtkPoints>::New(); vtkPoints->SetNumberOfPoints(numPoints); for (unsigned int i = 0; i < numPoints; ++i) vtkPoints->SetPoint(i, points[i].elems); - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(vtkPoints); - vtkPoints->Delete(); - - vtkCellArray* triangles = vtkCellArray::New(); + vtkSmartPointer triangles = vtkSmartPointer::New(); for (unsigned int i = 0; i < points.size(); i += 3) { triangles->InsertNextCell(3); triangles->InsertCellPoint(i); triangles->InsertCellPoint(i + 1); triangles->InsertCellPoint(i + 2); } polyData->SetPolys(triangles); - triangles->Delete(); - - vtkFloatArray* normals = vtkFloatArray::New(); + vtkSmartPointer normals = vtkSmartPointer::New(); normals->SetNumberOfComponents(3); + normals->SetNumberOfTuples(numNormals); normals->SetName("Normals"); - for (int i = 0; i < numPoints; i += 3) - normals->InsertNextTuple(normal.elems); + for (unsigned int i = 0; i < numNormals; ++i) + normals->SetTuple(i, normal.elems); polyData->GetCellData()->SetNormals(normals); - normals->Delete(); - - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyData); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); - this->InitProperty(property); - property->SetColor(color.x(), color.y(), color.z()); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } void mitk::SimulationDrawTool::drawTriangles(const std::vector& points, const std::vector& indices, const std::vector& normals, const Vec4f color) { if (!m_Update || points.empty() || indices.empty() || normals.empty()) return; unsigned int numPoints = points.size(); - vtkPoints* vtkPoints = vtkPoints::New(); + vtkSmartPointer vtkPoints = vtkSmartPointer<::vtkPoints>::New(); vtkPoints->SetNumberOfPoints(numPoints); for (unsigned int i = 0; i < numPoints; ++i) vtkPoints->SetPoint(i, points[i].elems); - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(vtkPoints); - vtkPoints->Delete(); - - vtkCellArray* triangles = vtkCellArray::New(); + vtkSmartPointer triangles = vtkSmartPointer::New(); unsigned int numIndices = indices.size(); for (unsigned int i = 0; i < numIndices; ++i) { triangles->InsertNextCell(3); triangles->InsertCellPoint(indices[i].elems[0]); triangles->InsertCellPoint(indices[i].elems[1]); triangles->InsertCellPoint(indices[i].elems[2]); } polyData->SetPolys(triangles); - triangles->Delete(); - unsigned int numNormals = normals.size(); - vtkFloatArray* vtkNormals = vtkFloatArray::New(); + vtkSmartPointer vtkNormals = vtkSmartPointer::New(); vtkNormals->SetNumberOfComponents(3); + vtkNormals->SetNumberOfTuples(numNormals); vtkNormals->SetName("Normals"); - for (int i = 0; i < numNormals; ++i) - vtkNormals->InsertNextTuple(normals[i].elems); + for (unsigned int i = 0; i < numNormals; ++i) + vtkNormals->SetTuple(i, normals[i].elems); polyData->GetCellData()->SetNormals(vtkNormals); - vtkNormals->Delete(); - - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyData); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); - this->InitProperty(property); - property->SetColor(color.x(), color.y(), color.z()); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } void mitk::SimulationDrawTool::drawTriangles(const std::vector&, const std::vector&, const std::vector&) { } void mitk::SimulationDrawTool::drawTriangleStrip(const std::vector&, const std::vector&, const Vec4f) { } void mitk::SimulationDrawTool::drawTriangleFan(const std::vector&, const std::vector&, const Vec4f) { } void mitk::SimulationDrawTool::drawFrame(const Vector3& position, const Quaternion& orientation, const Vec3f& size) { if (!m_Update) return; float minSize = std::min(std::min(size.x(), size.y()), size.z()); float maxSize = std::max(std::max(size.x(), size.y()), size.z()); if (maxSize > minSize * 2.0f) { if (minSize > 0.0f) maxSize = minSize * 2.0f; else minSize = maxSize * 0.707f; } const float radii[] = { minSize * 0.1f, maxSize * 0.2f }; bool wireframeBackup = m_Wireframe; m_Wireframe = false; if (size.x() != 0.0f) { Vector3 point2 = position + orientation.rotate(Vec3f(size.x(), 0.0f, 0.0f)); Vector3 point3 = point2 + orientation.rotate(Vec3f(radii[1], 0.0f, 0.0f)); Vec4f red(1.0f, 0.0f, 0.0f, 1.0f); this->drawCylinder(position, point2, radii[0], red); this->drawCone(point2, point3, radii[1], 0.0f, red); } if (size.y() != 0.0f) { Vector3 point2 = position + orientation.rotate(Vec3f(0.0f, size.y(), 0.0f)); Vector3 point3 = point2 + orientation.rotate(Vec3f(0.0f, radii[1], 0.0f)); Vec4f green(0.0f, 1.0f, 0.0f, 1.0f); this->drawCylinder(position, point2, radii[0], green); this->drawCone(point2, point3, radii[1], 0.0f, green); } if (size.z() != 0.0f) { Vector3 point2 = position + orientation.rotate(Vec3f(0.0f, 0.0f, size.z())); Vector3 point3 = point2 + orientation.rotate(Vec3f(0.0f, 0.0f, radii[1])); Vec4f blue(0.0f, 0.0f, 1.0f, 1.0f); this->drawCylinder(position, point2, radii[0], blue); this->drawCone(point2, point3, radii[1], 0.0f, blue); } m_Wireframe = wireframeBackup; } void mitk::SimulationDrawTool::drawSpheres(const std::vector& points, const std::vector& radii, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numSpheres = points.size(); for (unsigned int i = 0; i < numSpheres; ++i) { - vtkSphereSource *sphereSource = vtkSphereSource::New(); + vtkSmartPointer sphereSource = vtkSmartPointer::New(); sphereSource->SetCenter(const_cast(points[i].elems)); sphereSource->SetRadius(radii[i]); sphereSource->SetPhiResolution(16); sphereSource->SetThetaResolution(32); sphereSource->LatLongTessellationOn(); - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); - polyDataMapper->SetInput(sphereSource->GetOutput()); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); + polyDataMapper->SetInputConnection(sphereSource->GetOutputPort()); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); - this->InitProperty(property); - property->SetColor(color.x(), color.y(), color.z()); - m_VtkObjects.push_back(sphereSource); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } } void mitk::SimulationDrawTool::drawSpheres(const std::vector& points, float radius, const Vec4f color) { if (!m_Update || points.empty()) return; unsigned int numPoints = points.size(); std::vector radii(numPoints, radius); this->drawSpheres(points, radii, color); } void mitk::SimulationDrawTool::drawCone(const Vector3& point1, const Vector3& point2, float radius1, float radius2, const Vec4f color, int subdivisions) { if (!m_Update) return; - vtkPoints* points = vtkPoints::New(); + vtkSmartPointer points = vtkSmartPointer::New(); points->SetNumberOfPoints(2); points->SetPoint(0, point1.elems); points->SetPoint(1, point2.elems); - vtkCellArray* line = vtkCellArray::New(); + vtkSmartPointer line = vtkSmartPointer::New(); line->InsertNextCell(2); line->InsertCellPoint(0); line->InsertCellPoint(1); - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(points); polyData->SetLines(line); - points->Delete(); - line->Delete(); - const char* radiiName = "Radii"; - vtkFloatArray* radii = vtkFloatArray::New(); + vtkSmartPointer radii = vtkSmartPointer::New(); radii->SetName(radiiName); radii->SetNumberOfTuples(2); radii->SetTuple1(0, radius1); radii->SetTuple1(1, radius2); vtkPointData* pointData = polyData->GetPointData(); pointData->AddArray(radii); pointData->SetActiveScalars(radiiName); - radii->Delete(); - - vtkTubeFilter* tubeFilter = vtkTubeFilter::New(); + vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetInput(polyData); tubeFilter->CappingOn(); tubeFilter->SetNumberOfSides(subdivisions); tubeFilter->SetVaryRadiusToVaryRadiusByAbsoluteScalar(); - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); - polyDataMapper->SetInput(tubeFilter->GetOutput()); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); + polyDataMapper->SetInputConnection(tubeFilter->GetOutputPort()); polyDataMapper->ScalarVisibilityOff(); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); vtkProperty* property = actor->GetProperty(); - this->InitProperty(property); - property->SetColor(color.x(), color.y(), color.z()); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(tubeFilter); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } void mitk::SimulationDrawTool::drawCube(const float&, const Vec4f&, const int&) { } void mitk::SimulationDrawTool::drawCylinder(const Vector3& point1, const Vector3& point2, float radius, const Vec4f color, int subdivisions) { if (!m_Update) return; this->drawCone(point1, point2, radius, radius, color, subdivisions); } void mitk::SimulationDrawTool::drawCapsule(const Vector3&, const Vector3&, float, const Vec4f, int) { } void mitk::SimulationDrawTool::drawArrow(const Vector3& point1, const Vector3& point2, float radius, const Vec4f color, int subdivisions) { if (!m_Update) return; Vector3 point3 = point1 * 0.2f + point2 * 0.8f; this->drawCylinder(point1, point3, radius, color, subdivisions); this->drawCone(point3, point2, radius * 2.5f, 0.0f, color, subdivisions); } void mitk::SimulationDrawTool::drawPlus(const float& edgeRadius, const Vec4f& color, const int& subdivisions) { if (!m_Update) return; this->drawCylinder(Vector3(-1.0, 0.0, 0.0), Vector3(1.0, 0.0, 0.0), edgeRadius, color, subdivisions); this->drawCylinder(Vector3(0.0, -1.0, 0.0), Vector3(0.0, 1.0, 0.0), edgeRadius, color, subdivisions); this->drawCylinder(Vector3(0.0, 0.0, -1.0), Vector3(0.0, 0.0, 1.0), edgeRadius, color, subdivisions); } void mitk::SimulationDrawTool::drawPoint(const Vector3&, const Vec4f&) { } void mitk::SimulationDrawTool::drawPoint(const Vector3&, const Vector3&, const Vec4f&) { } void mitk::SimulationDrawTool::drawTriangle(const Vector3&, const Vector3&, const Vector3&, const Vector3&) { } void mitk::SimulationDrawTool::drawTriangle(const Vector3&, const Vector3&, const Vector3&, const Vector3&, const Vec4f&) { } void mitk::SimulationDrawTool::drawTriangle(const Vector3&, const Vector3&, const Vector3&, const Vector3&, const Vec4f&, const Vec4f&, const Vec4f&) { } void mitk::SimulationDrawTool::drawSphere(const Vector3&, float) { } void mitk::SimulationDrawTool::pushMatrix() { } void mitk::SimulationDrawTool::popMatrix() { } void mitk::SimulationDrawTool::multMatrix(float*) { } void mitk::SimulationDrawTool::scale(float) { } void mitk::SimulationDrawTool::setMaterial(const Vec4f&, std::string) { } void mitk::SimulationDrawTool::resetMaterial(const Vec4f&, std::string) { } void mitk::SimulationDrawTool::setPolygonMode(int mode, bool wireframe) { if (!m_Update) return; m_PolygonMode = mode; m_Wireframe = wireframe; } void mitk::SimulationDrawTool::setLightingEnabled(bool) { } void mitk::SimulationDrawTool::writeOverlayText(int, int, unsigned int, const Vec4f&, const char*) { } diff --git a/Modules/Simulation/mitkSimulationDrawTool.h b/Modules/Simulation/mitkSimulationDrawTool.h index 519b39c82b..948638a254 100644 --- a/Modules/Simulation/mitkSimulationDrawTool.h +++ b/Modules/Simulation/mitkSimulationDrawTool.h @@ -1,109 +1,107 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkSimulationDrawTool_h #define mitkSimulationDrawTool_h #include #include +#include +#include -class vtkActor; -class vtkObjectBase; class vtkProperty; namespace mitk { /** \brief Utility class used by SOFA classes to draw objects other than visual models. * * Implements the sofa::core::visual::DrawTool interface and replaces the default SOFA OpenGL implementation sofa::core::visual::DrawToolGL. * All draw methods create a VTK actor and append it to an internal list which can be queried by calling GetActors() to finally draw them. * In contrary to the original concept of DrawToolGL, which is set once during initialization of SOFA applications, every mitk::Simulation has its own exclusive copy of mitk::SimulationDrawTool. * Since SOFA can handle only a single DrawTool at once it must be ensured that the correct mitk::SimulationDrawTool is set when switching the active simulation. * * Each draw method checks if it is necessary to generate a new up-to-date VTK actor, i.e. after a simulation step, or if it is sufficient to use the already generated one. * This decision is controlled through the methods Reset() and DisableUpdate(). * The former method must be called right before a simulation step and mitk::SimulationMapper3D calls the latter method during rendering to disable unnecessary updates until the next simulation step. */ class Simulation_EXPORT SimulationDrawTool : public sofa::core::visual::DrawTool { public: SimulationDrawTool(); ~SimulationDrawTool(); /** \brief Disables creation of new VTK actors when calling draw methods. */ void DisableUpdate(); /** \brief Returns current list of VTK actors which were generated by draw methods since the last reset. * * \note Do not delete the VTK actors returned by this method. */ - std::vector GetActors() const; + std::vector > GetActors() const; /** \brief Clears internal lists of current VTK objects and enables creation of new VTK actors when calling draw methods. */ void Reset(); void drawPoints(const std::vector& points, float pointSize, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawLines(const std::vector& points, float lineWidth, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawLines(const std::vector& points, const std::vector& indices, float lineWidth, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangles(const std::vector& points, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangles(const std::vector& points, const Vector3 normal, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangles(const std::vector& points, const std::vector& indices, const std::vector& normals, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangles(const std::vector& points, const std::vector& normals, const std::vector& colors); void drawTriangleStrip(const std::vector& points, const std::vector& normals, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangleFan(const std::vector& points, const std::vector& normals, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawFrame(const Vector3& position, const Quaternion& orientation, const Vec3f& size); void drawSpheres(const std::vector& points, const std::vector& radii, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawSpheres(const std::vector& points, float radius, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawCone(const Vector3& point1, const Vector3& point2, float radius1, float radius2, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f), int subdivisions = 16); void drawCube(const float& edgeRadius, const Vec4f& color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f), const int& subdivisions = 16); void drawCylinder(const Vector3& point1, const Vector3& point2, float radius, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f), int subdivisions = 16); void drawCapsule(const Vector3& point1, const Vector3& point2, float radius, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f), int subdivisions = 16); void drawArrow(const Vector3& point1, const Vector3& point2, float radius, const Vec4f color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f), int subdivisions = 16); void drawPlus(const float& edgeRadius, const Vec4f& color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f), const int& subdivisions = 16); void drawPoint(const Vector3& position, const Vec4f& color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawPoint(const Vector3& position, const Vector3& normal, const Vec4f& color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangle(const Vector3& point1, const Vector3& point2, const Vector3& point3, const Vector3& normal); void drawTriangle(const Vector3& point1, const Vector3& point2, const Vector3& point3, const Vector3& normal, const Vec4f& color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f)); void drawTriangle(const Vector3& point1, const Vector3& point2, const Vector3& point3, const Vector3& normal, const Vec4f& color1, const Vec4f& color2, const Vec4f& color3); void drawSphere(const Vector3& position, float radius); void pushMatrix(); void popMatrix(); void multMatrix(float* matrix); void scale(float factor); void setMaterial(const Vec4f& color, std::string name = ""); void resetMaterial(const Vec4f& color, std::string name = ""); void setPolygonMode(int mode, bool wireframe); void setLightingEnabled(bool isEnabled); void writeOverlayText(int x, int y, unsigned int fontSize, const Vec4f& color, const char* text); private: SimulationDrawTool(const SimulationDrawTool&); SimulationDrawTool& operator=(const SimulationDrawTool&); - void DeleteVtkObjects(); void InitProperty(vtkProperty* property) const; - std::vector m_VtkObjects; - std::vector m_Actors; + std::vector > m_Actors; int m_PolygonMode; bool m_Wireframe; bool m_Update; }; } #endif diff --git a/Modules/Simulation/mitkSimulationMapper3D.cpp b/Modules/Simulation/mitkSimulationMapper3D.cpp index fc65b28ae7..8b7a5c64f0 100644 --- a/Modules/Simulation/mitkSimulationMapper3D.cpp +++ b/Modules/Simulation/mitkSimulationMapper3D.cpp @@ -1,242 +1,242 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimulation.h" #include "mitkSimulationMapper3D.h" #include "mitkSimulationModel.h" #include "mitkSimulationPropAssemblyVisitor.h" #include #include mitk::SimulationMapper3D::LocalStorage::LocalStorage() : m_VtkProp(vtkSmartPointer::New()) { } mitk::SimulationMapper3D::LocalStorage::~LocalStorage() { } void mitk::SimulationMapper3D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer, bool overwrite) { if (node != NULL) { mitk::Simulation* simulation = dynamic_cast(node->GetData()); if (simulation != NULL) { sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); sofa::component::visualmodel::VisualStyle::SPtr visualStyle; rootNode->get(visualStyle); if (!visualStyle) { visualStyle = sofa::core::objectmodel::New(); sofa::core::visual::DisplayFlags* displayFlags = visualStyle->displayFlags.beginEdit(); displayFlags->setShowVisualModels(); visualStyle->displayFlags.endEdit(); rootNode->addObject(visualStyle); } const sofa::core::visual::DisplayFlags& displayFlags = visualStyle->displayFlags.getValue(); node->AddProperty("Simulation.Behavior.Behavior Models", BoolProperty::New(displayFlags.getShowBehaviorModels()), renderer, overwrite); node->AddProperty("Simulation.Behavior.Force Fields", BoolProperty::New(displayFlags.getShowForceFields()), renderer, overwrite); node->AddProperty("Simulation.Behavior.Interactions", BoolProperty::New(displayFlags.getShowInteractionForceFields()), renderer, overwrite); node->AddProperty("Simulation.Collision.Bounding Trees", BoolProperty::New(displayFlags.getShowBoundingCollisionModels()), renderer, overwrite); node->AddProperty("Simulation.Collision.Collision Models", BoolProperty::New(displayFlags.getShowCollisionModels()), renderer, overwrite); node->AddProperty("Simulation.Mapping.Mechanical Mappings", BoolProperty::New(displayFlags.getShowMechanicalMappings()), renderer, overwrite); node->AddProperty("Simulation.Mapping.Visual Mappings", BoolProperty::New(displayFlags.getShowMappings()), renderer, overwrite); node->AddProperty("Simulation.Options.Normals", BoolProperty::New(displayFlags.getShowNormals()), renderer, overwrite); node->AddProperty("Simulation.Options.Wire Frame", BoolProperty::New(displayFlags.getShowWireFrame()), renderer, overwrite); node->AddProperty("Simulation.Visual.Visual Models", BoolProperty::New(displayFlags.getShowVisualModels()), renderer, overwrite); } Superclass::SetDefaultProperties(node, renderer, overwrite); } } mitk::SimulationMapper3D::SimulationMapper3D() { } mitk::SimulationMapper3D::~SimulationMapper3D() { } void mitk::SimulationMapper3D::ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer) { if (actor == NULL) { mitk::DataNode* node = this->GetDataNode(); bool showBehaviorModels; bool showForceFields; bool showInteractionForceFields; bool showBoundingCollisionModels; bool showCollisionModels; bool showMechanicalMappings; bool showMappings; bool showNormals; bool showWireFrame; bool showVisualModels; node->GetBoolProperty("Simulation.Behavior.Behavior Models", showBehaviorModels, renderer); node->GetBoolProperty("Simulation.Behavior.Force Fields", showForceFields, renderer); node->GetBoolProperty("Simulation.Behavior.Interactions", showInteractionForceFields, renderer); node->GetBoolProperty("Simulation.Collision.Bounding Trees", showBoundingCollisionModels, renderer); node->GetBoolProperty("Simulation.Collision.Collision Models", showCollisionModels, renderer); node->GetBoolProperty("Simulation.Mapping.Mechanical Mappings", showMechanicalMappings, renderer); node->GetBoolProperty("Simulation.Mapping.Visual Mappings", showMappings, renderer); node->GetBoolProperty("Simulation.Options.Normals", showNormals, renderer); node->GetBoolProperty("Simulation.Options.Wire Frame", showWireFrame, renderer); node->GetBoolProperty("Simulation.Visual.Visual Models", showVisualModels, renderer); mitk::Simulation* simulation = static_cast(this->GetData()); sofa::component::visualmodel::VisualStyle::SPtr visualStyle; simulation->GetRootNode()->get(visualStyle); bool update = false; sofa::core::visual::DisplayFlags* displayFlags = visualStyle->displayFlags.beginEdit(); if (showBehaviorModels != displayFlags->getShowBehaviorModels()) { displayFlags->setShowBehaviorModels(showBehaviorModels); update = true; } if (showForceFields != displayFlags->getShowForceFields()) { displayFlags->setShowForceFields(showForceFields); update = true; } if (showInteractionForceFields != displayFlags->getShowInteractionForceFields()) { displayFlags->setShowInteractionForceFields(showInteractionForceFields); update = true; } if (showBoundingCollisionModels != displayFlags->getShowBoundingCollisionModels()) { displayFlags->setShowBoundingCollisionModels(showBoundingCollisionModels); update = true; } if (showCollisionModels != displayFlags->getShowCollisionModels()) { displayFlags->setShowCollisionModels(showCollisionModels); update = true; } if (showMechanicalMappings != displayFlags->getShowMechanicalMappings()) { displayFlags->setShowMechanicalMappings(showMechanicalMappings); update = true; } if (showMappings != displayFlags->getShowMappings()) { displayFlags->setShowMappings(showMappings); update = true; } displayFlags->setShowNormals(showNormals); if (showWireFrame != displayFlags->getShowWireFrame()) { displayFlags->setShowWireFrame(showWireFrame); update = true; } displayFlags->setShowVisualModels(showVisualModels); visualStyle->displayFlags.endEdit(); if (update) simulation->GetDrawTool()->Reset(); } } void mitk::SimulationMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { mitk::Simulation* simulation = dynamic_cast(this->GetData()); if (sofa::simulation::getSimulation() == NULL) { if (simulation != NULL) { simulation->SetAsActiveSimulation(); simulation->GetDrawTool()->Reset(); } else { return; } } LocalStorage* localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); localStorage->m_VtkProp = vtkSmartPointer::New(); if (simulation != NULL) { sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); sofa::core::visual::VisualParams* vParams = sofa::core::visual::VisualParams::defaultInstance(); SimulationDrawTool* drawTool = simulation->GetDrawTool(); sofa::simulation::Simulation* backupSimulation = NULL; sofa::core::visual::DrawTool* backupDrawTool = NULL; if (sofa::simulation::getSimulation() != sofaSimulation.get()) { backupSimulation = sofa::simulation::getSimulation(); backupDrawTool = vParams->drawTool(); sofa::simulation::setSimulation(sofaSimulation.get()); vParams->drawTool() = drawTool; } this->ApplyProperties(NULL, renderer); sofaSimulation->updateVisual(rootNode.get()); sofaSimulation->draw(vParams, rootNode.get()); drawTool->DisableUpdate(); SimulationPropAssemblyVisitor propAssemblyVisitor(localStorage->m_VtkProp); rootNode->executeVisitor(&propAssemblyVisitor); - std::vector actors = drawTool->GetActors(); + std::vector > actors = drawTool->GetActors(); - for (std::vector::const_iterator actor = actors.begin(); actor != actors.end(); ++actor) + for (std::vector >::const_iterator actor = actors.begin(); actor != actors.end(); ++actor) localStorage->m_VtkProp->AddPart(*actor); if (backupSimulation != NULL) { sofa::simulation::setSimulation(backupSimulation); vParams->drawTool() = backupDrawTool; } } } vtkProp* mitk::SimulationMapper3D::GetVtkProp(mitk::BaseRenderer* renderer) { return m_LocalStorageHandler.GetLocalStorage(renderer)->m_VtkProp; } diff --git a/Modules/Simulation/mitkSimulationModel.cpp b/Modules/Simulation/mitkSimulationModel.cpp index cebf7e866a..bd9c4a816d 100644 --- a/Modules/Simulation/mitkSimulationModel.cpp +++ b/Modules/Simulation/mitkSimulationModel.cpp @@ -1,337 +1,300 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimulation.h" #include "mitkSimulationModel.h" #include #include -#include #include #include #include #include #include #include #include #include -#include mitk::SimulationModel::SimulationModel() : m_LastTime(-1.0), m_LastShowNormals(false), m_LastShowVisualModels(true), m_LastShowWireFrame(false) { } mitk::SimulationModel::~SimulationModel() { - this->DeleteVtkTextures(); - this->DeleteVtkObjects(); -} - -void mitk::SimulationModel::DeleteVtkObjects() -{ - for (std::vector::const_iterator object = m_VtkObjects.begin(); object != m_VtkObjects.end(); ++object) - (*object)->Delete(); - - m_VtkObjects.clear(); - - for (std::vector::const_iterator actor = m_Actors.begin(); actor != m_Actors.end(); ++actor) - (*actor)->Delete(); - m_Actors.clear(); -} - -void mitk::SimulationModel::DeleteVtkTextures() -{ - for (std::map::const_iterator texture = m_Textures.begin(); texture != m_Textures.end(); ++texture) - texture->second->Delete(); - m_Textures.clear(); } void mitk::SimulationModel::DrawGroup(int ig, const sofa::core::visual::VisualParams* vparams, bool transparent) { const sofa::defaulttype::ResizableExtVector& triangles = this->getTriangles(); const sofa::defaulttype::ResizableExtVector& quads = this->getQuads(); FaceGroup g; if (ig < 0) { g.materialId = -1; g.tri0 = 0; g.nbt = triangles.size(); g.quad0 = 0; g.nbq = quads.size(); } else { g = groups.getValue()[ig]; } const sofa::defaulttype::ResizableExtVector& vertices = this->getVertices(); unsigned int numVertices = vertices.size(); - vtkPoints* points = vtkPoints::New(); + vtkSmartPointer points = vtkSmartPointer::New(); points->SetNumberOfPoints(numVertices); for (unsigned int i = 0; i < numVertices; ++i) points->SetPoint(i, vertices[i].elems); - vtkPolyData* polyData = vtkPolyData::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(points); - points->Delete(); - - vtkCellArray* polys = vtkCellArray::New(); + vtkSmartPointer polys = vtkSmartPointer::New(); int numTriangles = g.tri0 + g.nbt; int numQuads = g.quad0 + g.nbq; for (int i = g.tri0; i < numTriangles; ++i) { polys->InsertNextCell(3); polys->InsertCellPoint(triangles[i].elems[0]); polys->InsertCellPoint(triangles[i].elems[1]); polys->InsertCellPoint(triangles[i].elems[2]); } for (int i = g.quad0; i < numQuads; ++i) { polys->InsertNextCell(4); polys->InsertCellPoint(quads[i].elems[0]); polys->InsertCellPoint(quads[i].elems[1]); polys->InsertCellPoint(quads[i].elems[2]); polys->InsertCellPoint(quads[i].elems[3]); } polyData->SetPolys(polys); - polys->Delete(); - const sofa::defaulttype::ResizableExtVector& normals = this->getVnormals(); unsigned int numNormals = normals.size(); - vtkFloatArray* vtkNormals = vtkFloatArray::New(); + vtkSmartPointer vtkNormals = vtkSmartPointer::New(); vtkNormals->SetNumberOfComponents(3); + vtkNormals->SetNumberOfTuples(numNormals); for (unsigned int i = 0; i < numNormals; ++i) - vtkNormals->InsertNextTuple(normals[i].elems); + vtkNormals->SetTuple(i, normals[i].elems); polyData->GetPointData()->SetNormals(vtkNormals); - vtkNormals->Delete(); - sofa::core::loader::Material m = g.materialId >= 0 ? materials.getValue()[g.materialId] : material.getValue(); if (m.useTexture && m.activated) { const sofa::defaulttype::ResizableExtVector& texCoords = this->getVtexcoords(); unsigned int numTexCoords = texCoords.size(); - vtkFloatArray* vtkTexCoords = vtkFloatArray::New(); + vtkSmartPointer vtkTexCoords = vtkSmartPointer::New(); vtkTexCoords->SetNumberOfComponents(2); + vtkTexCoords->SetNumberOfTuples(numTexCoords); for (unsigned int i = 0; i < numTexCoords; ++i) - vtkTexCoords->InsertNextTuple(texCoords[i].elems); + vtkTexCoords->SetTuple(i, texCoords[i].elems); polyData->GetPointData()->SetTCoords(vtkTexCoords); - - vtkTexCoords->Delete(); } - vtkPolyDataMapper* polyDataMapper = vtkPolyDataMapper::New(); + vtkSmartPointer polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyData); - vtkActor* actor = vtkActor::New(); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); if (m.useTexture && m.activated) actor->SetTexture(m_Textures[g.materialId]); sofa::defaulttype::Vec4f ambient = !m.useAmbient ? sofa::defaulttype::Vec4f() : m.ambient; sofa::defaulttype::Vec4f diffuse = !m.useDiffuse ? sofa::defaulttype::Vec4f() : m.diffuse; sofa::defaulttype::Vec4f specular = !m.useSpecular ? sofa::defaulttype::Vec4f() : m.specular; float shininess = m.useShininess ? m.shininess : 45.0f; if (shininess == 0.0f) { specular.clear(); shininess = 1.0f; } vtkProperty* property = actor->GetProperty(); property->SetAmbientColor(ambient.x(), ambient.y(), ambient.z()); property->SetDiffuseColor(diffuse.x(), diffuse.y(), diffuse.z()); property->SetSpecular(1.0); property->SetSpecularColor(specular.x(), specular.y(), specular.z()); property->SetSpecularPower(shininess); if (vparams->displayFlags().getShowWireFrame()) property->SetRepresentationToWireframe(); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); if (!m_LastShowNormals) return; - points = vtkPoints::New(); + points = vtkSmartPointer::New(); points->SetNumberOfPoints(numVertices * 2); - vtkCellArray* lines = vtkCellArray::New(); + vtkSmartPointer lines = vtkSmartPointer::New(); for (unsigned int i = 0; i < numVertices; ++i) { unsigned int j = 2 * i; unsigned int k = j + 1; points->SetPoint(j, vertices[i].elems); points->SetPoint(k, (vertices[i] + normals[i]).elems); lines->InsertNextCell(2); lines->InsertCellPoint(j); lines->InsertCellPoint(k); } - polyData = vtkPolyData::New(); + polyData = vtkSmartPointer::New(); polyData->SetPoints(points); polyData->SetLines(lines); - points->Delete(); - lines->Delete(); - - polyDataMapper = vtkPolyDataMapper::New(); + polyDataMapper = vtkSmartPointer::New(); polyDataMapper->SetInput(polyData); - actor = vtkActor::New(); + actor = vtkSmartPointer::New(); actor->SetMapper(polyDataMapper); actor->SetScale(Simulation::ScaleFactor); - m_VtkObjects.push_back(polyData); - m_VtkObjects.push_back(polyDataMapper); m_Actors.push_back(actor); } -std::vector mitk::SimulationModel::GetActors() const +std::vector > mitk::SimulationModel::GetActors() const { return m_Actors; } void mitk::SimulationModel::internalDraw(const sofa::core::visual::VisualParams* vparams, bool transparent) { double time = this->getContext()->getTime(); const sofa::core::visual::DisplayFlags& displayFlags = vparams->displayFlags(); bool showNormals = displayFlags.getShowNormals(); bool showVisualModels = displayFlags.getShowVisualModels(); bool showWireFrame = displayFlags.getShowWireFrame(); if (time == m_LastTime && showNormals == m_LastShowNormals && showVisualModels == m_LastShowVisualModels && showWireFrame == m_LastShowWireFrame) return; m_LastTime = time; m_LastShowNormals = showNormals; m_LastShowVisualModels = showVisualModels; m_LastShowWireFrame = showWireFrame; if (transparent) return; - this->DeleteVtkObjects(); + m_Actors.clear(); if (!vparams->displayFlags().getShowVisualModels()) return; sofa::helper::ReadAccessor > > groups = this->groups; if (groups.empty()) { this->DrawGroup(-1, vparams, transparent); } else { for (unsigned int i = 0; i < groups.size(); ++i) this->DrawGroup(i, vparams, transparent); } } bool mitk::SimulationModel::loadTexture(const std::string& filename) { return false; } bool mitk::SimulationModel::loadTextures() { - this->DeleteVtkTextures(); + m_Textures.clear(); std::vector activatedTextures; const sofa::helper::vector& materials = this->materials.getValue(); unsigned int numMaterials = materials.size(); for (unsigned int i = 0; i < numMaterials; ++i) { const sofa::core::loader::Material& material = materials[i]; if (material.useTexture && material.activated) activatedTextures.push_back(i); } unsigned int numActivatedTextures = activatedTextures.size(); for (unsigned int i = 0; i < numActivatedTextures; ++i) { std::string textureFilename = materials[activatedTextures[i]].textureFilename; if (!sofa::helper::system::DataRepository.findFile(textureFilename)) return false; - vtkImageReader2* imageReader = vtkImageReader2Factory::CreateImageReader2(textureFilename.c_str()); + vtkSmartPointer imageReader; + imageReader.TakeReference(vtkImageReader2Factory::CreateImageReader2(textureFilename.c_str())); if (imageReader == NULL) return false; imageReader->SetFileName(textureFilename.c_str()); - vtkTexture* texture = vtkTexture::New(); + vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInput(imageReader->GetOutputDataObject(0)); texture->InterpolateOn(); - imageReader->Delete(); - m_Textures.insert(std::make_pair(activatedTextures[i], texture)); } return true; } diff --git a/Modules/Simulation/mitkSimulationModel.h b/Modules/Simulation/mitkSimulationModel.h index b2a06fe9e1..e252966d3c 100644 --- a/Modules/Simulation/mitkSimulationModel.h +++ b/Modules/Simulation/mitkSimulationModel.h @@ -1,64 +1,60 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkSimulationModel_h #define mitkSimulationModel_h #include #include - -class vtkActor; -class vtkObjectBase; -class vtkTexture; +#include +#include +#include namespace mitk { class Simulation_EXPORT SimulationModel : public sofa::component::visualmodel::VisualModelImpl { public: SOFA_CLASS(SimulationModel, sofa::component::visualmodel::VisualModelImpl); - std::vector GetActors() const; + std::vector > GetActors() const; bool loadTexture(const std::string& filename); bool loadTextures(); protected: void internalDraw(const sofa::core::visual::VisualParams* vparams, bool transparent); private: SimulationModel(); ~SimulationModel(); SimulationModel(const MyType&); MyType& operator=(const MyType&); - void DeleteVtkObjects(); - void DeleteVtkTextures(); void DrawGroup(int ig, const sofa::core::visual::VisualParams* vparams, bool transparent); - std::vector m_VtkObjects; - std::vector m_Actors; - std::map m_Textures; + std::vector > m_Actors; + std::map > m_Textures; double m_LastTime; bool m_LastShowNormals; bool m_LastShowVisualModels; bool m_LastShowWireFrame; }; } #endif diff --git a/Modules/Simulation/mitkSimulationPropAssemblyVisitor.cpp b/Modules/Simulation/mitkSimulationPropAssemblyVisitor.cpp index ac546b6e11..60f9917385 100644 --- a/Modules/Simulation/mitkSimulationPropAssemblyVisitor.cpp +++ b/Modules/Simulation/mitkSimulationPropAssemblyVisitor.cpp @@ -1,51 +1,51 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimulationPropAssemblyVisitor.h" #include "mitkSimulationModel.h" #include #include mitk::SimulationPropAssemblyVisitor::SimulationPropAssemblyVisitor(vtkPropAssembly* propAssembly, const sofa::core::ExecParams* params) : Visitor(params), m_PropAssembly(propAssembly) { } mitk::SimulationPropAssemblyVisitor::~SimulationPropAssemblyVisitor() { } sofa::simulation::Visitor::Result mitk::SimulationPropAssemblyVisitor::processNodeTopDown(sofa::simulation::Node* node) { typedef sofa::simulation::Node::Sequence::const_iterator VisualModelIterator; VisualModelIterator end = node->visualModel.end(); for (VisualModelIterator visualModel = node->visualModel.begin(); visualModel != end; ++visualModel) { SimulationModel* simulationModel = dynamic_cast(*visualModel); if (simulationModel != NULL) { - std::vector actors = simulationModel->GetActors(); + std::vector > actors = simulationModel->GetActors(); - for (std::vector::const_iterator actor = actors.begin(); actor != actors.end(); ++actor) + for (std::vector >::const_iterator actor = actors.begin(); actor != actors.end(); ++actor) m_PropAssembly->AddPart(*actor); } } return RESULT_CONTINUE; } diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationPreferencePage.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationPreferencePage.cpp index 8b40802167..d22ca55d04 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationPreferencePage.cpp @@ -1,244 +1,244 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkSimulationPreferencePage.h" #include #include #include #include #include typedef sofa::helper::system::Plugin Plugin; typedef sofa::helper::system::PluginManager PluginManager; typedef sofa::helper::system::PluginManager::PluginIterator PluginIterator; typedef sofa::helper::system::PluginManager::PluginMap PluginMap; berry::IPreferences::Pointer getSimulationPreferences() { berry::ServiceRegistry& serviceRegistry = berry::Platform::GetServiceRegistry(); berry::IPreferencesService::Pointer preferencesService = serviceRegistry.GetServiceById(berry::IPreferencesService::ID); berry::IPreferences::Pointer preferences = preferencesService->GetSystemPreferences(); return preferences->Node("/org.mitk.views.simulation"); } void initSOFAPlugins(berry::IPreferences::Pointer preferences) { if (preferences.IsNull()) return; QString pluginPaths = preferences->GetByteArray(QmitkSimulationPreferencePage::PLUGIN_PATHS, "").c_str(); if (pluginPaths.isEmpty()) return; QStringList pluginPathList = pluginPaths.split(';', QString::SkipEmptyParts); QStringListIterator it(pluginPathList); typedef sofa::helper::system::PluginManager PluginManager; PluginManager& pluginManager = PluginManager::getInstance(); while (it.hasNext()) { std::string path = it.next().toStdString(); std::ostringstream errlog; pluginManager.loadPlugin(path, &errlog); if (errlog.str().empty()) pluginManager.getPluginMap()[path].initExternalModule(); } } const std::string QmitkSimulationPreferencePage::PLUGIN_PATHS = "plugin paths"; QmitkSimulationPreferencePage::QmitkSimulationPreferencePage() : m_Preferences(getSimulationPreferences()), m_Control(NULL) { initSOFAPlugins(m_Preferences); } QmitkSimulationPreferencePage::~QmitkSimulationPreferencePage() { } void QmitkSimulationPreferencePage::CreateQtControl(QWidget* parent) { m_Control = new QWidget(parent); m_Controls.setupUi(m_Control); QStringList headerLabels; headerLabels << "Name" << "License" << "Version" << "Path"; m_Controls.pluginsTreeWidget->setHeaderLabels(headerLabels); connect(m_Controls.pluginsTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(OnPluginTreeWidgetItemSelectionChanged())); connect(m_Controls.addButton, SIGNAL(clicked()), this, SLOT(OnAddButtonClicked())); connect(m_Controls.removeButton, SIGNAL(clicked()), this, SLOT(OnRemoveButtonClicked())); this->Update(); } QWidget* QmitkSimulationPreferencePage::GetQtControl() const { return m_Control; } void QmitkSimulationPreferencePage::Init(berry::IWorkbench::Pointer) { } void QmitkSimulationPreferencePage::OnAddButtonClicked() { QString filter = "SOFA Plugins "; #if defined(__APPLE__) filter += "(*.dylib*)"; #elif defined(WIN32) filter += "(*.dll)"; #else filter += "(*.so)"; #endif std::string path = QFileDialog::getOpenFileName(m_Control, "Add SOFA Library", "", filter).toStdString(); PluginManager &pluginManager = PluginManager::getInstance(); std::ostringstream errlog; if (pluginManager.loadPlugin(path, &errlog)) { if (!errlog.str().empty()) { QMessageBox* messageBox = new QMessageBox(m_Control); messageBox->setIcon(QMessageBox::Warning); messageBox->setStandardButtons(QMessageBox::Ok); messageBox->setText(errlog.str().c_str()); messageBox->setWindowTitle("Warning"); messageBox->show(); } Plugin& plugin = pluginManager.getPluginMap()[path]; plugin.initExternalModule(); QStringList pluginItem; pluginItem << plugin.getModuleName() << plugin.getModuleLicense() << plugin.getModuleVersion() << path.c_str(); m_Controls.pluginsTreeWidget->addTopLevelItem(new QTreeWidgetItem(pluginItem)); } else { QMessageBox* messageBox = new QMessageBox(m_Control); messageBox->setIcon(QMessageBox::Critical); messageBox->setStandardButtons(QMessageBox::Ok); messageBox->setText(errlog.str().c_str()); messageBox->setWindowTitle("Error"); messageBox->show(); } } void QmitkSimulationPreferencePage::OnPluginTreeWidgetItemSelectionChanged() { QList selectedItems = m_Controls.pluginsTreeWidget->selectedItems(); if (!selectedItems.isEmpty()) { PluginMap& pluginMap = sofa::helper::system::PluginManager::getInstance().getPluginMap(); std::string path = selectedItems[0]->text(3).toStdString(); m_Controls.descriptionPlainTextEdit->setPlainText(pluginMap[path].getModuleDescription()); m_Controls.removeButton->setEnabled(true); } else { m_Controls.descriptionPlainTextEdit->clear(); m_Controls.componentsListWidget->clear(); - m_Controls.removeButton->setDisabled(true); + m_Controls.removeButton->setEnabled(false); } } void QmitkSimulationPreferencePage::OnRemoveButtonClicked() { QList selectedItems = m_Controls.pluginsTreeWidget->selectedItems(); if (selectedItems.isEmpty()) return; std::string path = selectedItems[0]->text(3).toStdString(); PluginManager& pluginManager = PluginManager::getInstance(); std::ostringstream errlog; if (pluginManager.unloadPlugin(path, &errlog)) { delete selectedItems[0]; } else { QMessageBox* messageBox = new QMessageBox(m_Control); messageBox->setIcon(QMessageBox::Critical); messageBox->setStandardButtons(QMessageBox::Ok); messageBox->setText(errlog.str().c_str()); messageBox->setWindowTitle("Error"); messageBox->show(); } } void QmitkSimulationPreferencePage::PerformCancel() { } bool QmitkSimulationPreferencePage::PerformOk() { PluginManager& pluginManager = PluginManager::getInstance(); PluginMap& pluginMap = pluginManager.getPluginMap(); std::string pluginPaths; for (PluginIterator it = pluginMap.begin(); it != pluginMap.end(); ++it) { if (!pluginPaths.empty()) pluginPaths += ";"; pluginPaths += it->first; } m_Preferences->PutByteArray(PLUGIN_PATHS, pluginPaths); return true; } void QmitkSimulationPreferencePage::Update() { PluginManager& pluginManager = PluginManager::getInstance(); PluginMap& pluginMap = pluginManager.getPluginMap(); for (PluginIterator it = pluginMap.begin(); it != pluginMap.end(); ++it) { Plugin& plugin = it->second; QStringList pluginItem; pluginItem << plugin.getModuleName() << plugin.getModuleLicense() << plugin.getModuleVersion() << it->first.c_str(); m_Controls.pluginsTreeWidget->addTopLevelItem(new QTreeWidgetItem(pluginItem)); } } diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp index 5bb6a5d37a..d54415ee0d 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp @@ -1,161 +1,263 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkSimulationPreferencePage.h" #include "QmitkSimulationView.h" +#include #include #include #include #include #include +static void InitializeViews(mitk::IRenderWindowPart* renderWindowPart, mitk::Geometry3D* geometry) +{ + if (renderWindowPart == NULL || geometry == NULL) + return; + + mitk::IRenderingManager* renderingManager = renderWindowPart->GetRenderingManager(); + + if (renderingManager != NULL) + renderingManager->InitializeViews(geometry, mitk::RenderingManager::REQUEST_UPDATE_ALL, true); +} + QmitkSimulationView::QmitkSimulationView() - : m_Timer(this) + : m_SelectionWasRemovedFromDataStorage(false), + m_Timer(this) { + this->GetDataStorage()->RemoveNodeEvent.AddListener( + mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); + connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimerTimeout())); initSOFAPlugins(); } QmitkSimulationView::~QmitkSimulationView() { + this->GetDataStorage()->RemoveNodeEvent.RemoveListener( + mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); } void QmitkSimulationView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); - m_Controls.cmbSimulation->SetDataStorage(this->GetDataStorage()); - m_Controls.cmbSimulation->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); + m_Controls.simulationComboBox->SetDataStorage(this->GetDataStorage()); + m_Controls.simulationComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); + + m_Controls.stepsRecordedLabel->hide(); - connect(m_Controls.btnAnimate, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool))); - connect(m_Controls.btnResetScene, SIGNAL(clicked()), this, SLOT(OnResetSceneButtonClicked())); - connect(m_Controls.btnStep, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked())); - connect(m_Controls.cmbSimulation, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSimulationComboBoxSelectionChanged(const mitk::DataNode*))); - connect(m_Controls.spnDT, SIGNAL(valueChanged(double)), this, SLOT(OnDTSpinBoxValueChanged(double))); + connect(m_Controls.animateButton, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool))); + connect(m_Controls.recordButton, SIGNAL(toggled(bool)), this, SLOT(OnRecordButtonToggled(bool))); + connect(m_Controls.resetButton, SIGNAL(clicked()), this, SLOT(OnResetButtonClicked())); + connect(m_Controls.stepButton, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked())); + connect(m_Controls.simulationComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSimulationComboBoxSelectionChanged(const mitk::DataNode*))); + connect(m_Controls.dtSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDTSpinBoxValueChanged(double))); + connect(m_Controls.snapshotButton, SIGNAL(clicked()), this, SLOT(OnSnapshotButtonClicked())); + + if (m_Controls.simulationComboBox->GetSelectedNode().IsNotNull()) + this->OnSimulationComboBoxSelectionChanged(m_Controls.simulationComboBox->GetSelectedNode()); } void QmitkSimulationView::OnAnimateButtonToggled(bool toggled) { - if (SetSelectionAsCurrentSimulation()) + if (this->SetSelectionAsCurrentSimulation()) { - mitk::Simulation::Pointer simulation = dynamic_cast(m_Controls.cmbSimulation->GetSelectedNode()->GetData()); + mitk::Simulation::Pointer simulation = dynamic_cast(m_Selection->GetData()); sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); rootNode->getContext()->setAnimate(toggled); if (toggled) { - m_Controls.btnStep->setEnabled(false); + m_Controls.stepButton->setEnabled(false); m_Timer.start(0); } } if (!toggled) { m_Timer.stop(); - m_Controls.btnStep->setEnabled(true); + m_Controls.stepButton->setEnabled(true); } } void QmitkSimulationView::OnDTSpinBoxValueChanged(double value) { - if (SetSelectionAsCurrentSimulation()) + if (!this->SetSelectionAsCurrentSimulation()) + return; + + mitk::Simulation::Pointer simulation = dynamic_cast(m_Selection->GetData()); + sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); + + rootNode->setDt(value == 0.0 + ? simulation->GetDefaultDT() + : value); +} + +void QmitkSimulationView::OnNodeRemovedFromDataStorage(const mitk::DataNode* node) +{ + if (m_Selection.IsNotNull() && m_Selection.GetPointer() == node) + m_SelectionWasRemovedFromDataStorage = true; +} + +void QmitkSimulationView::OnRecordButtonToggled(bool toggled) +{ + if (!toggled) { - mitk::Simulation::Pointer simulation = dynamic_cast(m_Controls.cmbSimulation->GetSelectedNode()->GetData()); - sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); + if (m_Record.IsNotNull()) + { + mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); + dataNode->SetData(m_Record); + dataNode->SetName(m_Record->GetTimeSteps() == 1 ? "Snapshot" : "Record"); - rootNode->setDt(value == 0.0 - ? simulation->GetDefaultDT() - : value); + this->GetDataStorage()->Add(dataNode, m_Selection); + InitializeViews(this->GetRenderWindowPart(), m_Record->GetTimeSlicedGeometry()); + + m_Record = NULL; + } + + m_Controls.stepsRecordedLabel->hide(); + m_Controls.stepsRecordedLabel->setText("0 steps recorded"); + } + else if (toggled) + { + m_Controls.stepsRecordedLabel->show(); } } -void QmitkSimulationView::OnResetSceneButtonClicked() +void QmitkSimulationView::OnResetButtonClicked() { - if (SetSelectionAsCurrentSimulation()) - { - mitk::Simulation::Pointer simulation = dynamic_cast(m_Controls.cmbSimulation->GetSelectedNode()->GetData()); - sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); - sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); + if (!this->SetSelectionAsCurrentSimulation()) + return; - m_Controls.spnDT->setValue(0.0); - sofaSimulation->reset(rootNode.get()); + if (m_Controls.recordButton->isChecked()) + m_Controls.recordButton->setChecked(false); - rootNode->setTime(0.0); - rootNode->execute(sofa::core::ExecParams::defaultInstance()); + mitk::Simulation::Pointer simulation = dynamic_cast(m_Selection->GetData()); + sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); + sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); - simulation->GetDrawTool()->Reset(); + m_Controls.dtSpinBox->setValue(0.0); + sofaSimulation->reset(rootNode.get()); - this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); - } + rootNode->setTime(0.0); + rootNode->execute(sofa::core::ExecParams::defaultInstance()); + + simulation->GetDrawTool()->Reset(); + + this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnSimulationComboBoxSelectionChanged(const mitk::DataNode* node) { - if (m_Controls.btnAnimate->isChecked()) - m_Controls.btnAnimate->setChecked(false); + if (m_Controls.animateButton->isChecked()) + m_Controls.animateButton->setChecked(false); + + if (m_SelectionWasRemovedFromDataStorage) + { + m_SelectionWasRemovedFromDataStorage = false; + m_Selection = NULL; + } + + if (m_Controls.recordButton->isChecked()) + m_Controls.recordButton->setChecked(false); if (node != NULL) { - m_Controls.grpSimulation->setEnabled(true); + m_Selection = m_Controls.simulationComboBox->GetSelectedNode(); + m_Controls.sceneGroupBox->setEnabled(true); + m_Controls.snapshotButton->setEnabled(true); static_cast(node->GetData())->SetAsActiveSimulation(); } else { - m_Controls.grpSimulation->setEnabled(false); + m_Selection = NULL; + m_Controls.sceneGroupBox->setEnabled(false); + m_Controls.snapshotButton->setEnabled(false); mitk::Simulation::SetActiveSimulation(NULL); } } +void QmitkSimulationView::OnSnapshotButtonClicked() +{ + if (!this->SetSelectionAsCurrentSimulation()) + return; + + mitk::Simulation::Pointer simulation = dynamic_cast(m_Selection->GetData()); + + mitk::Surface::Pointer snapshot = simulation->TakeSnapshot(); + + if (snapshot.IsNull()) + return; + + mitk::DataNode::Pointer snapshotDataNode = mitk::DataNode::New(); + snapshotDataNode->SetData(snapshot); + snapshotDataNode->SetName("Snapshot"); + + this->GetDataStorage()->Add(snapshotDataNode, m_Selection); +} + void QmitkSimulationView::OnStepButtonClicked() { - if (SetSelectionAsCurrentSimulation()) + if (!this->SetSelectionAsCurrentSimulation()) + return; + + mitk::Simulation::Pointer simulation = dynamic_cast(m_Controls.simulationComboBox->GetSelectedNode()->GetData()); + sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); + sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); + + simulation->GetDrawTool()->Reset(); + + sofaSimulation->animate(rootNode.get(), rootNode->getDt()); + + this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); + + if (m_Controls.recordButton->isChecked()) { - mitk::Simulation::Pointer simulation = dynamic_cast(m_Controls.cmbSimulation->GetSelectedNode()->GetData()); - sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); - sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); + if (m_Record.IsNull()) + m_Record = mitk::Surface::New(); - simulation->GetDrawTool()->Reset(); + simulation->AppendSnapshot(m_Record); - sofaSimulation->animate(rootNode.get(), rootNode->getDt()); + unsigned int numSteps = m_Record->GetTimeSteps(); + QString plural = numSteps != 1 ? "s" : ""; - this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); + m_Controls.stepsRecordedLabel->setText(QString("%1 step%2 recorded").arg(numSteps).arg(plural)); } } void QmitkSimulationView::SetFocus() { - m_Controls.btnAnimate->setFocus(); + m_Controls.animateButton->setFocus(); } bool QmitkSimulationView::SetSelectionAsCurrentSimulation() const { - mitk::DataNode::Pointer selectedNode = m_Controls.cmbSimulation->GetSelectedNode(); - - if (selectedNode.IsNotNull()) + if (m_Selection.IsNotNull()) { - static_cast(m_Controls.cmbSimulation->GetSelectedNode()->GetData())->SetAsActiveSimulation(); + static_cast(m_Selection->GetData())->SetAsActiveSimulation(); return true; } return false; } void QmitkSimulationView::OnTimerTimeout() { this->OnStepButtonClicked(); } diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h index ffce7519ae..95284276ba 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h @@ -1,53 +1,60 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkSimulationView_h #define QmitkSimulationView_h +#include #include #include #include class QmitkSimulationView : public QmitkAbstractView { Q_OBJECT public: QmitkSimulationView(); ~QmitkSimulationView(); void CreateQtPartControl(QWidget* parent); void SetFocus(); +private slots: + void OnAnimateButtonToggled(bool toggled); + void OnDTSpinBoxValueChanged(double value); + void OnRecordButtonToggled(bool toggled); + void OnResetButtonClicked(); + void OnSimulationComboBoxSelectionChanged(const mitk::DataNode* node); + void OnSnapshotButtonClicked(); + void OnStepButtonClicked(); + void OnTimerTimeout(); + private: QmitkSimulationView(const QmitkSimulationView&); QmitkSimulationView& operator=(const QmitkSimulationView&); + void OnNodeRemovedFromDataStorage(const mitk::DataNode* node); bool SetSelectionAsCurrentSimulation() const; Ui::QmitkSimulationViewControls m_Controls; + bool m_SelectionWasRemovedFromDataStorage; + mitk::DataNode::Pointer m_Selection; + mitk::Surface::Pointer m_Record; QTimer m_Timer; - -private slots: - void OnAnimateButtonToggled(bool toggled); - void OnDTSpinBoxValueChanged(double value); - void OnResetSceneButtonClicked(); - void OnSimulationComboBoxSelectionChanged(const mitk::DataNode* node); - void OnStepButtonClicked(); - void OnTimerTimeout(); }; #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui index 5ee48dfb0d..12a7bd372f 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui @@ -1,167 +1,179 @@ QmitkSimulationViewControls true 0 0 301 548 Simulation - + - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Simulation - - - - - - - - 0 - 0 - - - - - - - - + false - + Scene - - + + + + + 0 + 0 + + + + + + 0 0 Animate true false - - + + 0 0 Step - - + + 0 0 - Reset Scene + Reset - - - - - - - 0 - 0 - - - - dt - - - - - - - - 0 - 0 - - - - s - - - 3 - - - 0.010000000000000 - - - - + + + + + 0 + 0 + + + + dt + + + + + + + + 0 + 0 + + + + s + + + 3 + + + 0.010000000000000 + + + + + + + + + + Surface Recording + + + + + + Record + + + true + + + + + + + false + + + Take Snapshot + + + + + + + 0 step(s) recorded + + Qt::Vertical 20 421 QmitkDataStorageComboBox - QWidget + QComboBox
QmitkDataStorageComboBox.h