diff --git a/Modules/Simulation/mitkExportMitkVisitor.cpp b/Modules/Simulation/mitkExportMitkVisitor.cpp index 4d9ef80592..c0645954c3 100644 --- a/Modules/Simulation/mitkExportMitkVisitor.cpp +++ b/Modules/Simulation/mitkExportMitkVisitor.cpp @@ -1,230 +1,230 @@ /*=================================================================== 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 "mitkExportMitkVisitor.h" #include #include #include #include #include #include #include #include #include -static void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material& material) +void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material& material) { using sofa::defaulttype::Vec4f; if (dataNode.IsNull() || dynamic_cast(dataNode->GetData()) == NULL) return; if (material.useDiffuse) dataNode->SetFloatProperty("opacity", material.diffuse[3]); Vec4f ambient = material.useAmbient ? material.ambient : Vec4f(); Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f(); Vec4f specular = material.useSpecular ? material.specular : Vec4f(); float shininess = material.useShininess ? std::min(material.shininess, 128.0f) : 45.0f; if (shininess == 0.0f) { specular.clear(); shininess = 1.0f; } dataNode->SetFloatProperty("material.ambientCoefficient", 1.0f); - dataNode->SetProperty("material.ambientColor", mitk::ColorProperty::New(material.ambient.elems)); + dataNode->SetProperty("material.ambientColor", mitk::ColorProperty::New(ambient.elems)); dataNode->SetFloatProperty("material.diffuseCoefficient", 1.0f); - dataNode->SetProperty("color", mitk::ColorProperty::New(material.diffuse.elems)); + dataNode->SetProperty("color", mitk::ColorProperty::New(diffuse.elems)); dataNode->SetFloatProperty("material.specularCoefficient", 1.0f); dataNode->SetProperty("material.specularColor", mitk::ColorProperty::New(specular.elems)); dataNode->SetFloatProperty("material.specularPower", shininess); } static mitk::DataNode::Pointer GetSimulationDataNode(mitk::DataStorage::Pointer dataStorage, sofa::core::objectmodel::BaseNode::SPtr rootNode) { if (dataStorage.IsNull()) return NULL; if (!rootNode) return NULL; mitk::TNodePredicateDataType::Pointer predicate = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate); for (mitk::DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it) { mitk::DataNode::Pointer dataNode = it.Value(); mitk::Simulation::Pointer simulation = static_cast(dataNode->GetData()); if (simulation->GetRootNode() == rootNode) return dataNode; } return NULL; } mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params) : Visitor(params), m_DataStorage(dataStorage) { } mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params) : Visitor(params), m_DataStorage(dataStorage), m_VisualModelName(visualModelName) { } mitk::ExportMitkVisitor::~ExportMitkVisitor() { } sofa::simulation::Visitor::Result mitk::ExportMitkVisitor::processNodeTopDown(sofa::simulation::Node* node) { if (m_DataStorage.IsNotNull()) { for_each(this, node, node->visualModel, &ExportMitkVisitor::processVisualModel); return RESULT_CONTINUE; } return RESULT_PRUNE; } void mitk::ExportMitkVisitor::processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel) { using sofa::defaulttype::ResizableExtVector; typedef sofa::component::visualmodel::VisualModelImpl::VecCoord VecCoord; typedef sofa::component::visualmodel::VisualModelImpl::Triangle Triangle; typedef sofa::component::visualmodel::VisualModelImpl::Quad Quad; typedef sofa::component::visualmodel::VisualModelImpl::Deriv Deriv; typedef sofa::component::visualmodel::VisualModelImpl::VecTexCoord VecTexCoord; sofa::component::visualmodel::VisualModelImpl* visualModelImpl = dynamic_cast(visualModel); if (visualModelImpl == NULL) return; if (!m_VisualModelName.empty() && m_VisualModelName != visualModelImpl->name.getValue()) return; vtkSmartPointer polyData = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); const VecCoord& vertices = visualModelImpl->m_vertices2.getValue().empty() ? visualModelImpl->m_positions.getValue() : visualModelImpl->m_vertices2.getValue(); size_t numPoints = vertices.size(); points->SetNumberOfPoints(numPoints); for (size_t i = 0; i < numPoints; ++i) points->SetPoint(i, vertices[i].elems); polyData->SetPoints(points); vtkSmartPointer polys = vtkSmartPointer::New(); const ResizableExtVector& triangles = visualModelImpl->m_triangles.getValue(); if (!triangles.empty()) { ResizableExtVector::const_iterator trianglesEnd = triangles.end(); for (ResizableExtVector::const_iterator it = triangles.begin(); it != trianglesEnd; ++it) { const Triangle& triangle = *it; polys->InsertNextCell(3); polys->InsertCellPoint(triangle[0]); polys->InsertCellPoint(triangle[1]); polys->InsertCellPoint(triangle[2]); } } const ResizableExtVector& quads = visualModelImpl->m_quads.getValue(); if (!quads.empty()) { ResizableExtVector::const_iterator quadsEnd = quads.end(); for (ResizableExtVector::const_iterator it = quads.begin(); it != quadsEnd; ++it) { const Quad& quad = *it; polys->InsertNextCell(4); polys->InsertCellPoint(quad[0]); polys->InsertCellPoint(quad[1]); polys->InsertCellPoint(quad[2]); polys->InsertCellPoint(quad[3]); } } polyData->SetPolys(polys); const ResizableExtVector& normals = visualModelImpl->m_vnormals.getValue(); if (!normals.empty()) { size_t numNormals = normals.size(); vtkSmartPointer vtkNormals = vtkSmartPointer::New(); vtkNormals->SetNumberOfComponents(3); vtkNormals->SetNumberOfTuples(numNormals); for (size_t i = 0; i < numNormals; ++i) vtkNormals->SetTuple(i, normals[i].elems); polyData->GetPointData()->SetNormals(vtkNormals); } const VecTexCoord& texCoords = visualModelImpl->m_vtexcoords.getValue(); if (!texCoords.empty()) { size_t numTexCoords = texCoords.size(); vtkSmartPointer vtkTexCoords = vtkSmartPointer::New(); vtkTexCoords->SetNumberOfComponents(2); vtkTexCoords->SetNumberOfTuples(numTexCoords); for (size_t i = 0; i < numTexCoords; ++i) vtkTexCoords->SetTuple(i, texCoords[i].elems); polyData->GetPointData()->SetTCoords(vtkTexCoords); } Surface::Pointer surface = Surface::New(); surface->SetVtkPolyData(polyData); DataNode::Pointer dataNode = DataNode::New(); dataNode->SetName(visualModelImpl->name.getValue()); dataNode->SetData(surface); ApplyMaterial(dataNode, visualModelImpl->material.getValue()); DataNode::Pointer parentDataNode = GetSimulationDataNode(m_DataStorage, node->getRoot()); if (parentDataNode.IsNotNull()) surface->SetGeometry(parentDataNode->GetData()->GetGeometry()); m_DataStorage->Add(dataNode, parentDataNode); } diff --git a/Modules/Simulation/mitkExportMitkVisitor.h b/Modules/Simulation/mitkExportMitkVisitor.h index fb89e0ee35..75f4d73eb1 100644 --- a/Modules/Simulation/mitkExportMitkVisitor.h +++ b/Modules/Simulation/mitkExportMitkVisitor.h @@ -1,46 +1,47 @@ /*=================================================================== 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 mitkExportMitkVisitor_h #define mitkExportMitkVisitor_h #include #include #include namespace mitk { class MitkSimulation_EXPORT ExportMitkVisitor : public sofa::simulation::Visitor { public: explicit ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ~ExportMitkVisitor(); + using sofa::simulation::Visitor::processNodeTopDown; Result processNodeTopDown(sofa::simulation::Node* node); private: ExportMitkVisitor(const ExportMitkVisitor&); ExportMitkVisitor& operator=(const ExportMitkVisitor&); void processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel); DataStorage::Pointer m_DataStorage; std::string m_VisualModelName; }; } #endif diff --git a/Modules/Simulation/mitkPlaneIntersectionVisitor.h b/Modules/Simulation/mitkPlaneIntersectionVisitor.h index ddbc24cfdf..337fbdd80a 100644 --- a/Modules/Simulation/mitkPlaneIntersectionVisitor.h +++ b/Modules/Simulation/mitkPlaneIntersectionVisitor.h @@ -1,62 +1,63 @@ /*=================================================================== 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 mitkPlaneIntersectionVisitor_h #define mitkPlaneIntersectionVisitor_h #include #include #include #include namespace mitk { class MitkSimulation_EXPORT PlaneIntersectionVisitor : public sofa::simulation::Visitor { public: struct Edge { Point3D v0; Point3D v1; }; struct Intersection { float color[4]; std::vector edges; }; PlaneIntersectionVisitor(const Point3D& point, const Vector3D& normal, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ~PlaneIntersectionVisitor(); const std::vector& GetIntersections() const; + using sofa::simulation::Visitor::processNodeTopDown; Result processNodeTopDown(sofa::simulation::Node* node); private: PlaneIntersectionVisitor(const PlaneIntersectionVisitor&); PlaneIntersectionVisitor& operator=(const PlaneIntersectionVisitor&); void processVisualModel(sofa::simulation::Node*, sofa::core::visual::VisualModel* visualModel); Point3D m_Point; Vector3D m_Normal; std::vector m_Intersections; }; } #endif diff --git a/Modules/Simulation/mitkSetVtkRendererVisitor.h b/Modules/Simulation/mitkSetVtkRendererVisitor.h index 93ebc0d385..cc9bd00d55 100644 --- a/Modules/Simulation/mitkSetVtkRendererVisitor.h +++ b/Modules/Simulation/mitkSetVtkRendererVisitor.h @@ -1,45 +1,46 @@ /*=================================================================== 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 mitkSetVtkRendererVisitor_h #define mitkSetVtkRendererVisitor_h #include #include class vtkRenderer; namespace mitk { class MitkSimulation_EXPORT SetVtkRendererVisitor : public sofa::simulation::Visitor { public: explicit SetVtkRendererVisitor(vtkRenderer* renderer, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ~SetVtkRendererVisitor(); + using sofa::simulation::Visitor::processNodeTopDown; Result processNodeTopDown(sofa::simulation::Node* node); private: SetVtkRendererVisitor(const SetVtkRendererVisitor&); SetVtkRendererVisitor& operator=(const SetVtkRendererVisitor&); void processVisualModel(sofa::simulation::Node*, sofa::core::visual::VisualModel* visualModel); vtkRenderer* m_VtkRenderer; }; } #endif diff --git a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp index bb0013078c..51c7e3914b 100644 --- a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp +++ b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp @@ -1,164 +1,164 @@ /*=================================================================== 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 "mitkSetVtkRendererVisitor.h" #include "mitkSimulation.h" #include "mitkSimulationVtkMapper3D.h" #include "mitkVtkSimulationPolyDataMapper3D.h" #include #include mitk::SimulationVtkMapper3D::LocalStorage::LocalStorage() : m_Actor(vtkSmartPointer::New()) { } mitk::SimulationVtkMapper3D::LocalStorage::~LocalStorage() { } void mitk::SimulationVtkMapper3D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer, bool overwrite) { if (node != NULL) { 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() != sofa::core::visual::tristate::false_value), renderer, overwrite); } Superclass::SetDefaultProperties(node, renderer, overwrite); } } mitk::SimulationVtkMapper3D::SimulationVtkMapper3D() { } mitk::SimulationVtkMapper3D::~SimulationVtkMapper3D() { } void mitk::SimulationVtkMapper3D::ApplyColorAndOpacityProperties(BaseRenderer*, vtkActor*) { } void mitk::SimulationVtkMapper3D::ApplySimulationProperties(BaseRenderer* renderer) { 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); - Simulation* simulation = static_cast(this->GetData()); + Simulation* simulation = static_cast(node->GetData()); sofa::component::visualmodel::VisualStyle::SPtr visualStyle; simulation->GetRootNode()->get(visualStyle); sofa::core::visual::DisplayFlags* displayFlags = visualStyle->displayFlags.beginEdit(); displayFlags->setShowBehaviorModels(showBehaviorModels); displayFlags->setShowForceFields(showForceFields); displayFlags->setShowInteractionForceFields(showInteractionForceFields); displayFlags->setShowBoundingCollisionModels(showBoundingCollisionModels); displayFlags->setShowCollisionModels(showCollisionModels); displayFlags->setShowMechanicalMappings(showMechanicalMappings); displayFlags->setShowMappings(showMappings); displayFlags->setShowNormals(showNormals); displayFlags->setShowWireFrame(showWireFrame); displayFlags->setShowVisualModels(showVisualModels); visualStyle->displayFlags.endEdit(); } void mitk::SimulationVtkMapper3D::GenerateDataForRenderer(BaseRenderer* renderer) { DataNode* dataNode = this->GetDataNode(); if (dataNode == NULL) return; Simulation* simulation = dynamic_cast(dataNode->GetData()); if (simulation == NULL) return; LocalStorage* localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); if (localStorage->m_Mapper == NULL) { localStorage->m_Mapper = vtkSmartPointer::New(); localStorage->m_Mapper->SetSimulation(simulation); localStorage->m_Actor->SetMapper(localStorage->m_Mapper); SetVtkRendererVisitor setVtkRendererVisitor(renderer->GetVtkRenderer()); simulation->GetRootNode()->executeVisitor(&setVtkRendererVisitor); } this->ApplySimulationProperties(renderer); } vtkProp* mitk::SimulationVtkMapper3D::GetVtkProp(BaseRenderer* renderer) { return m_LocalStorageHandler.GetLocalStorage(renderer)->m_Actor; } diff --git a/Modules/Simulation/mitkVtkModel.cpp b/Modules/Simulation/mitkVtkModel.cpp index 2fe091b485..5dadba56c1 100644 --- a/Modules/Simulation/mitkVtkModel.cpp +++ b/Modules/Simulation/mitkVtkModel.cpp @@ -1,613 +1,633 @@ /*=================================================================== 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 "mitkVtkModel.h" #include #include #include #include #include #include #include #include #include #include #include +// Defined in mitkExportMitkVisitor.cpp +void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material& material); + static bool InitGLEW() { static bool isInitialized = false; // If no render window is shown, OpenGL is potentially not initialized, e.g., the // Display tab of the Workbench might be closed while loading a SOFA scene file. // In this case initialization is deferred (see mitk::VtkModel::internalDraw()). if (mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows().empty()) return false; if (!isInitialized) { GLenum error = glewInit(); if (error != GLEW_OK) { MITK_ERROR("glewInit") << glewGetErrorString(error); } else { isInitialized = true; } } return isInitialized; } mitk::VtkModel::VtkModel() : m_GlewIsInitialized(InitGLEW()), m_BuffersWereCreated(false), m_LastNumberOfVertices(0), m_LastNumberOfTriangles(0), m_LastNumberOfQuads(0), m_VertexBuffer(0), m_IndexBuffer(0), m_VtkRenderer(NULL), m_Mode(OpenGL) { } mitk::VtkModel::~VtkModel() { if (m_Mode == OpenGL && m_BuffersWereCreated) { glDeleteBuffers(1, &m_IndexBuffer); glDeleteBuffers(1, &m_VertexBuffer); } } void mitk::VtkModel::CreateIndexBuffer() { if (m_Mode == OpenGL) { glGenBuffers(1, &m_IndexBuffer); } else if (m_Mode == Surface) { m_Polys = vtkSmartPointer::New(); } this->InitIndexBuffer(); } void mitk::VtkModel::CreateVertexBuffer() { if (m_Mode == OpenGL) { glGenBuffers(1, &m_VertexBuffer); } else if (m_Mode == Surface) { m_Points = vtkSmartPointer::New(); m_Normals = vtkSmartPointer::New(); m_TexCoords = vtkSmartPointer::New(); } this->InitVertexBuffer(); } -void mitk::VtkModel::DrawGroup(int group, bool) +void mitk::VtkModel::DrawGroup(int group, bool transparent) +{ + if (m_Mode == OpenGL) + { + this->DrawOpenGLGroup(group, transparent); + } + else if (m_Mode == Surface) + { + this->DrawSurfaceGroup(group, transparent); + } +} + +void mitk::VtkModel::DrawOpenGLGroup(int group, bool) { using sofa::core::loader::Material; using sofa::defaulttype::ResizableExtVector; using sofa::defaulttype::Vec4f; - if (m_Mode == OpenGL) - { - const VecCoord& vertices = this->getVertices(); - const ResizableExtVector& normals = this->getVnormals(); - const ResizableExtVector& triangles = this->getTriangles(); - const ResizableExtVector& quads = this->getQuads(); + const VecCoord& vertices = this->getVertices(); + const ResizableExtVector& normals = this->getVnormals(); + const ResizableExtVector& triangles = this->getTriangles(); + const ResizableExtVector& quads = this->getQuads(); - FaceGroup faceGroup; + FaceGroup faceGroup; - if (group == -1) - { - faceGroup.nbt = triangles.size(); - faceGroup.nbq = quads.size(); - } - else - { - faceGroup = groups.getValue()[group]; - } + if (group == -1) + { + faceGroup.nbt = triangles.size(); + faceGroup.nbq = quads.size(); + } + else + { + faceGroup = groups.getValue()[group]; + } - Material material = faceGroup.materialId != -1 - ? materials.getValue()[faceGroup.materialId] - : this->material.getValue(); + Material material = faceGroup.materialId != -1 + ? materials.getValue()[faceGroup.materialId] + : this->material.getValue(); - if (material.useTexture && material.activated) - { - m_Textures[faceGroup.materialId]->Load(m_VtkRenderer); - - glEnable(GL_TEXTURE_2D); - glTexCoordPointer(2, GL_FLOAT, 0, reinterpret_cast(vertices.size() * sizeof(VecCoord::value_type) + normals.size() * sizeof(Deriv))); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + if (material.useTexture && material.activated) + { + m_Textures[faceGroup.materialId]->Load(m_VtkRenderer); - Vec4f ambient = material.useAmbient ? material.ambient : Vec4f(); - Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f(); - Vec4f specular = material.useSpecular ? material.specular : Vec4f(); - Vec4f emissive = material.useEmissive ? material.emissive : Vec4f(); - float shininess = material.useShininess ? std::min(material.shininess, 128.0f) : 45.0f; + glEnable(GL_TEXTURE_2D); + glTexCoordPointer(2, GL_FLOAT, 0, reinterpret_cast(vertices.size() * sizeof(VecCoord::value_type) + normals.size() * sizeof(Deriv))); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } - if (shininess == 0.0f) - { - specular.clear(); - shininess = 1.0f; - } + Vec4f ambient = material.useAmbient ? material.ambient : Vec4f(); + Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f(); + Vec4f specular = material.useSpecular ? material.specular : Vec4f(); + Vec4f emissive = material.useEmissive ? material.emissive : Vec4f(); + float shininess = material.useShininess ? std::min(material.shininess, 128.0f) : 45.0f; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr()); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); + if (shininess == 0.0f) + { + specular.clear(); + shininess = 1.0f; + } - if (faceGroup.nbt != 0) - glDrawElements(GL_TRIANGLES, faceGroup.nbt * 3, GL_UNSIGNED_INT, reinterpret_cast(faceGroup.tri0 * sizeof(Triangle))); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr()); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); - if (faceGroup.nbq != 0) - glDrawElements(GL_QUADS, faceGroup.nbq * 4, GL_UNSIGNED_INT, reinterpret_cast(triangles.size() * sizeof(Triangle) + faceGroup.quad0 * sizeof(Quad))); + if (faceGroup.nbt != 0) + glDrawElements(GL_TRIANGLES, faceGroup.nbt * 3, GL_UNSIGNED_INT, reinterpret_cast(faceGroup.tri0 * sizeof(Triangle))); - if (material.useTexture && material.activated) - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_TEXTURE_2D); + if (faceGroup.nbq != 0) + glDrawElements(GL_QUADS, faceGroup.nbq * 4, GL_UNSIGNED_INT, reinterpret_cast(triangles.size() * sizeof(Triangle) + faceGroup.quad0 * sizeof(Quad))); - m_Textures[faceGroup.materialId]->PostRender(m_VtkRenderer); - } - } - else if (m_Mode == Surface) + if (material.useTexture && material.activated) { - m_PolyData->SetPoints(m_Points); - m_PolyData->SetPolys(m_Polys); - m_PolyData->GetPointData()->SetNormals(m_Normals); - m_PolyData->GetPointData()->SetTCoords(m_TexCoords); - m_PolyData->Modified(); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + + m_Textures[faceGroup.materialId]->PostRender(m_VtkRenderer); } } +void mitk::VtkModel::DrawSurfaceGroup(int group, bool) +{ + m_PolyData->SetPoints(m_Points); + m_PolyData->SetPolys(m_Polys); + + vtkPointData* pointData = m_PolyData->GetPointData(); + + pointData->SetNormals(m_Normals->GetSize() != 0 + ? m_Normals + : NULL); + + pointData->SetTCoords(m_TexCoords->GetSize() != 0 + ? m_TexCoords + : NULL); + + m_PolyData->Modified(); +} + void mitk::VtkModel::DrawGroups(bool transparent) { using sofa::core::objectmodel::Data; using sofa::helper::ReadAccessor; using sofa::helper::vector; ReadAccessor > > groups = this->groups; if (groups.empty()) { this->DrawGroup(-1, transparent); } else { int numGroups = static_cast(groups.size()); for (int i = 0; i < numGroups; ++i) this->DrawGroup(i, transparent); } } void mitk::VtkModel::InitIndexBuffer() { using sofa::defaulttype::ResizableExtVector; const ResizableExtVector& triangles = this->getTriangles(); const ResizableExtVector& quads = this->getQuads(); if (m_Mode == OpenGL) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles.size() * sizeof(Triangle) + quads.size() * sizeof(Quad), NULL, GL_DYNAMIC_DRAW); } - else if (m_Mode == Surface) - { - m_Polys->Initialize(); - } this->UpdateIndexBuffer(); } void mitk::VtkModel::InitVertexBuffer() { using sofa::defaulttype::ResizableExtVector; const VecCoord& vertices = this->getVertices(); const ResizableExtVector normals = this->getVnormals(); const VecTexCoord& texCoords = this->getVtexcoords(); if (m_Mode == OpenGL) { glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(VecCoord::value_type) + normals.size() * sizeof(Deriv) + texCoords.size() * sizeof(VecTexCoord::value_type), NULL, GL_DYNAMIC_DRAW); } else if (m_Mode == Surface) { m_Points->SetNumberOfPoints(vertices.size()); m_Normals->SetNumberOfComponents(3); m_Normals->SetNumberOfTuples(normals.size()); m_TexCoords->SetNumberOfComponents(2); m_TexCoords->SetNumberOfTuples(texCoords.size()); } this->UpdateVertexBuffer(); } void mitk::VtkModel::internalDraw(const sofa::core::visual::VisualParams* vparams, bool transparent) { using sofa::core::visual::DisplayFlags; using sofa::defaulttype::ResizableExtVector; if (m_Mode == OpenGL && !m_GlewIsInitialized) { // Try lazy initialization since initialization potentially failed so far // due to missing render windows (see InitGLEW()). m_GlewIsInitialized = InitGLEW(); if (m_GlewIsInitialized) { this->updateBuffers(); } else { return; } } const DisplayFlags& displayFlags = vparams->displayFlags(); if (!displayFlags.getShowVisualModels()) return; if (m_BuffersWereCreated == false) return; if (m_Mode == OpenGL) { glEnable(GL_LIGHTING); glColor3f(1.0f, 1.0f, 1.0f); glPolygonMode(GL_FRONT_AND_BACK, displayFlags.getShowWireFrame() ? GL_LINE : GL_FILL); const VecCoord& vertices = this->getVertices(); glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer); this->ValidateBoundBuffers(); glVertexPointer(3, GL_FLOAT, 0, NULL); glNormalPointer(GL_FLOAT, 0, reinterpret_cast(vertices.size() * sizeof(VecCoord::value_type))); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); } this->DrawGroups(transparent); if (m_Mode == OpenGL) { glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); if (displayFlags.getShowWireFrame()) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_LIGHTING); } if (displayFlags.getShowNormals()) this->DrawNormals(); } void mitk::VtkModel::DrawNormals() { using sofa::defaulttype::ResizableExtVector; if (m_Mode == OpenGL) { const VecCoord& vertices = this->getVertices(); const ResizableExtVector& normals = this->getVnormals(); size_t numVertices = vertices.size(); Coord normal; glBegin(GL_LINES); for (size_t i = 0; i < numVertices; ++i) { glVertex3fv(vertices[i].ptr()); normal = vertices[i] + normals[i]; glVertex3fv(normal.ptr()); } glEnd(); } } bool mitk::VtkModel::loadTextures() { using sofa::helper::system::DataRepository; using sofa::helper::vector; using sofa::core::loader::Material; m_Textures.clear(); std::vector materialIndices; const vector& materials = this->materials.getValue(); unsigned int numMaterials = materials.size(); for (unsigned int i = 0; i < numMaterials; ++i) { const Material& material = materials[i]; if (material.useTexture && material.activated) materialIndices.push_back(i); } bool retValue = true; size_t numTextures = materialIndices.size(); for (size_t i = 0; i < numTextures; ++i) { std::string filename = materials[materialIndices[i]].textureFilename; if (!DataRepository.findFile(filename)) { MITK_ERROR("VtkModel") << "File \"" << filename << "\" not found!"; retValue = false; continue; } vtkSmartPointer imageReader = vtkSmartPointer::Take(vtkImageReader2Factory::CreateImageReader2(filename.c_str())); if (imageReader == NULL) { MITK_ERROR("VtkModel") << "File \"" << filename << "\" has unknown image format!"; retValue = false; continue; } imageReader->SetFileName(filename.c_str()); imageReader->UpdateWholeExtent(); vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInputConnection(imageReader->GetOutputPort()); texture->InterpolateOn(); m_Textures.insert(std::make_pair(materialIndices[i], texture)); } return retValue; } mitk::DataNode::Pointer mitk::VtkModel::GetDataNode() const { return m_DataNode; } mitk::VtkModel::Mode mitk::VtkModel::GetMode() const { return m_Mode; } void mitk::VtkModel::SetMode(Mode mode) { if (m_Mode == mode) return; if (mode == OpenGL) { m_DataNode = NULL; m_Surface = NULL; m_PolyData = NULL; m_TexCoords = NULL; m_Normals = NULL; m_Polys = NULL; m_Points = NULL; } else if (mode == Surface) { if (m_Mode == OpenGL && m_BuffersWereCreated) { glDeleteBuffers(1, &m_IndexBuffer); m_IndexBuffer = 0; glDeleteBuffers(1, &m_VertexBuffer); m_VertexBuffer = 0; } m_PolyData = vtkSmartPointer::New(); m_Surface = Surface::New(); m_Surface->SetVtkPolyData(m_PolyData); m_DataNode = DataNode::New(); m_DataNode->SetName(name.getValue()); m_DataNode->SetData(m_Surface); + + ApplyMaterial(m_DataNode, this->material.getValue()); } m_Mode = mode; m_BuffersWereCreated = false; this->updateBuffers(); } void mitk::VtkModel::SetVtkRenderer(vtkRenderer* renderer) { m_VtkRenderer = renderer; } void mitk::VtkModel::updateBuffers() { using sofa::defaulttype::ResizableExtVector; if (m_Mode == OpenGL && !m_GlewIsInitialized) return; const VecCoord& vertices = this->getVertices(); const ResizableExtVector& triangles = this->getTriangles(); const ResizableExtVector& quads = this->getQuads(); if (!m_BuffersWereCreated) { this->CreateVertexBuffer(); this->CreateIndexBuffer(); m_BuffersWereCreated = true; } else { if (m_LastNumberOfVertices != vertices.size()) this->InitVertexBuffer(); else this->UpdateVertexBuffer(); if (m_LastNumberOfTriangles != triangles.size() || m_LastNumberOfQuads != quads.size()) this->InitIndexBuffer(); else this->UpdateIndexBuffer(); } m_LastNumberOfVertices = vertices.size(); m_LastNumberOfTriangles = triangles.size(); m_LastNumberOfQuads = quads.size(); } void mitk::VtkModel::UpdateIndexBuffer() { using sofa::defaulttype::ResizableExtVector; const ResizableExtVector& triangles = this->getTriangles(); const ResizableExtVector& quads = this->getQuads(); GLsizeiptr sizeOfTriangleIndices = triangles.size() * sizeof(Triangle); GLsizeiptr sizeOfQuadIndices = quads.size() * sizeof(Quad); if (m_Mode == OpenGL) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeOfTriangleIndices, triangles.getData()); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sizeOfTriangleIndices, sizeOfQuadIndices, quads.getData()); } else if (m_Mode == Surface) { m_Polys->Initialize(); if (!triangles.empty()) { ResizableExtVector::const_iterator trianglesEnd = triangles.end(); for (ResizableExtVector::const_iterator it = triangles.begin(); it != trianglesEnd; ++it) { const Triangle& triangle = *it; m_Polys->InsertNextCell(3); m_Polys->InsertCellPoint(triangle[0]); m_Polys->InsertCellPoint(triangle[1]); m_Polys->InsertCellPoint(triangle[2]); } } if (!quads.empty()) { ResizableExtVector::const_iterator quadsEnd = quads.end(); for (ResizableExtVector::const_iterator it = quads.begin(); it != quadsEnd; ++it) { const Quad& quad = *it; m_Polys->InsertNextCell(4); m_Polys->InsertCellPoint(quad[0]); m_Polys->InsertCellPoint(quad[1]); m_Polys->InsertCellPoint(quad[2]); m_Polys->InsertCellPoint(quad[3]); } } } } void mitk::VtkModel::UpdateVertexBuffer() { using sofa::defaulttype::ResizableExtVector; const VecCoord& vertices = this->getVertices(); const ResizableExtVector normals = this->getVnormals(); const VecTexCoord& texCoords = this->getVtexcoords(); if (m_Mode == OpenGL) { GLsizeiptr sizeOfVertices = vertices.size() * sizeof(VecCoord::value_type); GLsizeiptr sizeOfNormals = normals.size() * sizeof(Deriv); glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeOfVertices, vertices.getData()); glBufferSubData(GL_ARRAY_BUFFER, sizeOfVertices, sizeOfNormals, normals.getData()); if (!m_Textures.empty()) { GLsizeiptr sizeOfTexCoords = texCoords.size() * sizeof(VecTexCoord::value_type); glBufferSubData(GL_ARRAY_BUFFER, sizeOfVertices + sizeOfNormals, sizeOfTexCoords, texCoords.getData()); } } else if (m_Mode == Surface) { size_t numPoints = vertices.size(); for (size_t i = 0; i < numPoints; ++i) m_Points->SetPoint(i, vertices[i].elems); if (!normals.empty()) { size_t numNormals = normals.size(); for (size_t i = 0; i < numNormals; ++i) m_Normals->SetTuple(i, normals[i].elems); } if (!texCoords.empty()) { size_t numTexCoords = texCoords.size(); for (size_t i = 0; i < numTexCoords; ++i) m_TexCoords->SetTuple(i, normals[i].elems); } } } void mitk::VtkModel::ValidateBoundBuffers() { if (m_Mode != OpenGL) return; GLint indexBufferSize; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &indexBufferSize); if (indexBufferSize == 0) { glDeleteBuffers(1, &m_IndexBuffer); this->CreateIndexBuffer(); glDeleteBuffers(1, &m_VertexBuffer); this->CreateVertexBuffer(); } } diff --git a/Modules/Simulation/mitkVtkModel.h b/Modules/Simulation/mitkVtkModel.h index f61d12029d..78c70ab6b6 100644 --- a/Modules/Simulation/mitkVtkModel.h +++ b/Modules/Simulation/mitkVtkModel.h @@ -1,97 +1,99 @@ /*=================================================================== 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 mitkVtkModel_h #define mitkVtkModel_h #include #include #include #include #include #include #include #include #include #include #include #include class vtkOpenGLTexture; class vtkRenderer; namespace mitk { class MitkSimulation_EXPORT VtkModel : public sofa::component::visualmodel::VisualModelImpl { public: enum Mode { OpenGL, Surface }; SOFA_CLASS(VtkModel, sofa::component::visualmodel::VisualModelImpl); void internalDraw(const sofa::core::visual::VisualParams* vparams, bool transparent); bool loadTextures(); void SetVtkRenderer(vtkRenderer* renderer); void updateBuffers(); DataNode::Pointer GetDataNode() const; Mode GetMode() const; void SetMode(Mode mode); private: VtkModel(); ~VtkModel(); VtkModel(MyType&); MyType& operator=(const MyType&); void CreateIndexBuffer(); void CreateVertexBuffer(); - void DrawGroup(int group, bool); + void DrawGroup(int group, bool transparent); + void DrawOpenGLGroup(int group, bool transparent); + void DrawSurfaceGroup(int group, bool transparent); void DrawGroups(bool transparent); void DrawNormals(); void InitIndexBuffer(); void InitVertexBuffer(); void UpdateIndexBuffer(); void UpdateVertexBuffer(); void ValidateBoundBuffers(); bool m_GlewIsInitialized; bool m_BuffersWereCreated; size_t m_LastNumberOfVertices; size_t m_LastNumberOfTriangles; size_t m_LastNumberOfQuads; GLuint m_VertexBuffer; GLuint m_IndexBuffer; std::map > m_Textures; vtkRenderer* m_VtkRenderer; Mode m_Mode; vtkSmartPointer m_Points; vtkSmartPointer m_Polys; vtkSmartPointer m_Normals; vtkSmartPointer m_TexCoords; vtkSmartPointer m_PolyData; Surface::Pointer m_Surface; DataNode::Pointer m_DataNode; }; } #endif diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper2D.cpp b/Modules/Simulation/mitkVtkSimulationPolyDataMapper2D.cpp index fe2fa687a5..773fdb9177 100644 --- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper2D.cpp +++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper2D.cpp @@ -1,139 +1,139 @@ /*=================================================================== 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 "mitkGetSimulationService.h" #include "mitkISimulationService.h" #include "mitkPlaneIntersectionVisitor.h" #include "mitkVtkSimulationPolyDataMapper2D.h" #include #include #include #include #include #include namespace mitk { vtkStandardNewMacro(vtkSimulationPolyDataMapper2D); } mitk::vtkSimulationPolyDataMapper2D::vtkSimulationPolyDataMapper2D() : m_SimulationService(GetSimulationService()) { } mitk::vtkSimulationPolyDataMapper2D::~vtkSimulationPolyDataMapper2D() { } -void mitk::vtkSimulationPolyDataMapper2D::Render(vtkRenderer* renderer, vtkActor* actor) +void mitk::vtkSimulationPolyDataMapper2D::Render(vtkRenderer* renderer, vtkActor*) { typedef PlaneIntersectionVisitor::Edge Edge; typedef PlaneIntersectionVisitor::Intersection Intersection; vtkRenderWindow* renderWindow = renderer->GetRenderWindow(); if (renderWindow->CheckAbortStatus() == 1) return; if (renderWindow->SupportsOpenGL() == 0) return; if (m_Simulation.IsNull()) return; if (!renderWindow->IsCurrent()) renderWindow->MakeCurrent(); BaseRenderer* mitkRenderer = BaseRenderer::GetInstance(renderer->GetRenderWindow()); if (mitkRenderer == NULL) return; SliceNavigationController* sliceNavigationController = mitkRenderer->GetSliceNavigationController(); if (sliceNavigationController == NULL) return; const PlaneGeometry* planeGeometry = sliceNavigationController->GetCurrentPlaneGeometry(); if (planeGeometry == NULL) return; renderer->GetRenderWindow()->MakeCurrent(); m_SimulationService->SetActiveSimulation(m_Simulation); PlaneIntersectionVisitor planeIntersectionVisitor(planeGeometry->GetOrigin(), planeGeometry->GetNormal()); m_Simulation->GetRootNode()->executeVisitor(&planeIntersectionVisitor); mitk::DisplayGeometry::Pointer displayGeometry = mitkRenderer->GetDisplayGeometry(); Point2D point2D; glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); const std::vector& intersections = planeIntersectionVisitor.GetIntersections(); std::vector::const_iterator intersectionsEnd = intersections.end(); for (std::vector::const_iterator intersectionIt = intersections.begin(); intersectionIt != intersectionsEnd; ++intersectionIt) { const std::vector& edges = intersectionIt->edges; std::vector::const_iterator edgesEnd = edges.end(); glColor4fv(intersectionIt->color); glBegin(GL_LINES); for (std::vector::const_iterator edgeIt = edges.begin(); edgeIt != edgesEnd; ++edgeIt) { glVertex3dv(edgeIt->v0.GetDataPointer()); glVertex3dv(edgeIt->v1.GetDataPointer()); } glEnd(); } glDisable(GL_COLOR_MATERIAL); } void mitk::vtkSimulationPolyDataMapper2D::RenderPiece(vtkRenderer*, vtkActor*) { } void mitk::vtkSimulationPolyDataMapper2D::SetSimulation(Simulation::Pointer simulation) { m_Simulation = simulation; } double* mitk::vtkSimulationPolyDataMapper2D::GetBounds() { if (m_Simulation.IsNull()) return Superclass::GetBounds(); sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode(); const sofa::defaulttype::BoundingBox& bbox = rootNode->f_bbox.getValue(); const sofa::defaulttype::Vector3& min = bbox.minBBox(); const sofa::defaulttype::Vector3& max = bbox.maxBBox(); Bounds[0] = min.x(); Bounds[1] = max.x(); Bounds[2] = min.y(); Bounds[3] = max.y(); Bounds[4] = min.z(); Bounds[5] = max.z(); return this->Bounds; } diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper3D.cpp b/Modules/Simulation/mitkVtkSimulationPolyDataMapper3D.cpp index 2d242e5e14..6d6e7c528b 100644 --- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper3D.cpp +++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper3D.cpp @@ -1,95 +1,95 @@ /*=================================================================== 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 "mitkGetSimulationService.h" #include "mitkISimulationService.h" #include "mitkVtkSimulationPolyDataMapper3D.h" #include #include #include #include namespace mitk { vtkStandardNewMacro(vtkSimulationPolyDataMapper3D); } mitk::vtkSimulationPolyDataMapper3D::vtkSimulationPolyDataMapper3D() : m_SimulationService(GetSimulationService()) { } mitk::vtkSimulationPolyDataMapper3D::~vtkSimulationPolyDataMapper3D() { } -void mitk::vtkSimulationPolyDataMapper3D::Render(vtkRenderer* renderer, vtkActor* actor) +void mitk::vtkSimulationPolyDataMapper3D::Render(vtkRenderer* renderer, vtkActor*) { vtkRenderWindow* renderWindow = renderer->GetRenderWindow(); if (renderWindow->CheckAbortStatus() == 1) return; if (renderWindow->SupportsOpenGL() == 0) return; if (m_Simulation.IsNull()) return; if (!renderWindow->IsCurrent()) renderWindow->MakeCurrent(); m_SimulationService->SetActiveSimulation(m_Simulation); sofa::core::visual::VisualParams* vParams = sofa::core::visual::VisualParams::defaultInstance(); sofa::simulation::Simulation::SPtr sofaSimulation = m_Simulation->GetSOFASimulation(); sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode(); sofaSimulation->updateVisual(rootNode.get()); sofaSimulation->draw(vParams, rootNode.get()); // SOFA potentially disables GL_BLEND but VTK relies on it. glEnable(GL_BLEND); } void mitk::vtkSimulationPolyDataMapper3D::RenderPiece(vtkRenderer*, vtkActor*) { } void mitk::vtkSimulationPolyDataMapper3D::SetSimulation(Simulation::Pointer simulation) { m_Simulation = simulation; } double* mitk::vtkSimulationPolyDataMapper3D::GetBounds() { if (m_Simulation.IsNull()) return Superclass::GetBounds(); sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode(); const sofa::defaulttype::BoundingBox& bbox = rootNode->f_bbox.getValue(); const sofa::defaulttype::Vector3& min = bbox.minBBox(); const sofa::defaulttype::Vector3& max = bbox.maxBBox(); Bounds[0] = min.x(); Bounds[1] = max.x(); Bounds[2] = min.y(); Bounds[3] = max.y(); Bounds[4] = min.z(); Bounds[5] = max.z(); return this->Bounds; } 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 bf35daf36b..0e6fd04853 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp @@ -1,343 +1,345 @@ /*=================================================================== 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 "org_mitk_gui_qt_simulation_Activator.h" #include "QmitkBaseItemDelegate.h" #include "QmitkNoEditItemDelegate.h" #include "QmitkSimulationView.h" #include #include #include #include #include #include #include template static T* GetService() { ctkPluginContext* context = mitk::org_mitk_gui_qt_simulation_Activator::GetContext(); if (context == NULL) return NULL; ctkServiceReference serviceReference = context->getServiceReference(); return serviceReference ? context->getService(serviceReference) : NULL; } static mitk::SimulationInteractor::Pointer CreateSimulationInteractor() { const us::Module* simulationModule = us::ModuleRegistry::GetModule("MitkSimulation"); mitk::SimulationInteractor::Pointer interactor = mitk::SimulationInteractor::New(); interactor->LoadStateMachine("Simulation.xml", simulationModule); interactor->SetEventConfig("SimulationConfig.xml", simulationModule); return interactor; } class Equals { public: explicit Equals(mitk::DataNode::Pointer dataNode) : m_DataNode(dataNode) { } bool operator()(const mitk::DataStorage::SetOfObjects::value_type& object) { return object == m_DataNode; } private: mitk::DataNode::Pointer m_DataNode; }; QmitkSimulationView::QmitkSimulationView() : m_SimulationService(GetService()), m_Interactor(CreateSimulationInteractor()), m_VtkModelContextMenu(NULL), m_Timer(this) { this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); } QmitkSimulationView::~QmitkSimulationView() { this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); } void QmitkSimulationView::CreateQtPartControl(QWidget* parent) { m_Ui.setupUi(parent); m_Ui.simulationComboBox->SetDataStorage(this->GetDataStorage()); m_Ui.simulationComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); QAction* vtkModelModeAction = new QAction(/*QIcon(":/Qmitk/Surface_48.png"),*/ "Render to Surface", m_VtkModelContextMenu); vtkModelModeAction->setCheckable(true); m_VtkModelContextMenu = new QMenu(m_Ui.sceneTreeWidget); m_VtkModelContextMenu->addAction(vtkModelModeAction); connect(m_Ui.simulationComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSimulationChanged(const mitk::DataNode*))); connect(m_Ui.animateButton, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool))); connect(m_Ui.stepButton, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked())); connect(m_Ui.resetButton, SIGNAL(clicked()), this, SLOT(OnResetButtonClicked())); connect(m_Ui.dtSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDtChanged(double))); connect(m_Ui.sceneTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(OnSelectedBaseChanged())); connect(m_Ui.sceneTreeWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnBaseContextMenuRequested(const QPoint&))); if (m_Ui.simulationComboBox->GetSelectedNode().IsNotNull()) { this->OnSelectedSimulationChanged(m_Ui.simulationComboBox->GetSelectedNode()); } else { this->SetSimulationControlsEnabled(false); } } void QmitkSimulationView::OnAnimateButtonToggled(bool toggled) { mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); if (toggled) { mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); simulation->SetAnimationFlag(true); scheduler->AddProcess(simulation); m_Ui.stepButton->setEnabled(false); } else if (m_Selection.IsNotNull()) { mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); scheduler->RemoveProcess(simulation); simulation->SetAnimationFlag(false); m_Ui.stepButton->setEnabled(true); } if (!scheduler->IsEmpty()) { if (!m_Timer.isActive()) m_Timer.start(0); } else { m_Timer.stop(); } } void QmitkSimulationView::OnBaseContextMenuRequested(const QPoint& point) { typedef mitk::DataStorage::SetOfObjects SetOfObjects; QTreeWidgetItem* item = m_Ui.sceneTreeWidget->itemAt(point); if (item == NULL) return; QmitkSceneTreeWidget::Base* base = m_Ui.sceneTreeWidget->GetBaseFromItem(item); if (base == NULL) return; mitk::VtkModel* vtkModel = dynamic_cast(base); if (vtkModel == NULL) return; + m_VtkModelContextMenu->actions().first()->setChecked(vtkModel->GetMode() == mitk::VtkModel::Surface); + QAction* action = m_VtkModelContextMenu->exec(m_Ui.sceneTreeWidget->mapToGlobal(point)); if (action == NULL) return; if (action->text() == "Render to Surface") { mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(); SetOfObjects::ConstPointer objects = dataStorage->GetSubset(NULL); if (action->isChecked()) { vtkModel->SetMode(mitk::VtkModel::Surface); mitk::DataNode::Pointer dataNode = vtkModel->GetDataNode(); if (std::find_if(objects->begin(), objects->end(), Equals(dataNode)) == objects->end()) dataStorage->Add(dataNode, m_Selection); } else { mitk::DataNode::Pointer dataNode = vtkModel->GetDataNode(); if (std::find_if(objects->begin(), objects->end(), Equals(dataNode)) != objects->end()) dataStorage->Remove(dataNode); vtkModel->SetMode(mitk::VtkModel::OpenGL); } } } void QmitkSimulationView::OnDtChanged(double dt) { if (m_Selection.IsNull()) return; mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); simulation->SetDt(std::max(0.0, dt)); } void QmitkSimulationView::OnNodeRemovedFromDataStorage(const mitk::DataNode* node) { mitk::Simulation::Pointer simulation = dynamic_cast(node->GetData()); if (simulation.IsNotNull()) { mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); scheduler->RemoveProcess(simulation); if (scheduler->IsEmpty() && m_Timer.isActive()) m_Timer.stop(); if (m_SimulationService->GetActiveSimulation() == simulation) m_SimulationService->SetActiveSimulation(NULL); } } void QmitkSimulationView::OnResetButtonClicked() { mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); m_SimulationService->SetActiveSimulation(simulation); m_Ui.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); simulation->Reset(); this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_ALL); } void QmitkSimulationView::OnSelectedSimulationChanged(const mitk::DataNode* node) { if (node != NULL) { m_Selection = m_Ui.simulationComboBox->GetSelectedNode(); mitk::Simulation* simulation = static_cast(m_Selection->GetData()); m_Ui.animateButton->setChecked(simulation->GetAnimationFlag()); m_Ui.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); this->SetSimulationControlsEnabled(true); } else { m_Selection = NULL; this->SetSimulationControlsEnabled(false); m_Ui.animateButton->setChecked(false); m_Ui.dtSpinBox->setValue(0.0); } m_Interactor->SetDataNode(m_Selection); this->ResetSceneTreeWidget(); } void QmitkSimulationView::OnSelectedBaseChanged() { QList selectedBaseItems = m_Ui.sceneTreeWidget->selectedItems(); m_Ui.baseTreeWidget->OnSelectedBaseChanged(!selectedBaseItems.isEmpty() ? m_Ui.sceneTreeWidget->GetBaseFromItem(selectedBaseItems[0]) : NULL); } void QmitkSimulationView::OnStep(bool renderWindowUpdate) { mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); mitk::Simulation::Pointer simulation = dynamic_cast(scheduler->GetNextProcess()); m_SimulationService->SetActiveSimulation(simulation); if (simulation.IsNotNull()) simulation->Animate(); if (renderWindowUpdate) this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_ALL); } void QmitkSimulationView::OnStepButtonClicked() { if (m_Selection.IsNull()) return; mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); m_SimulationService->SetActiveSimulation(simulation); simulation->Animate(); this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_ALL); } void QmitkSimulationView::OnTimeout() { QTime currentTime = QTime::currentTime(); if (currentTime.msecsTo(m_NextRenderWindowUpdate) > 0) { this->OnStep(false); } else { m_NextRenderWindowUpdate = currentTime.addMSecs(MSecsPerFrame); this->OnStep(true); } } void QmitkSimulationView::ResetSceneTreeWidget() { m_Ui.sceneTreeWidget->clear(); if (m_Selection.IsNull()) return; mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); m_Ui.sceneTreeWidget->addChild(NULL, simulation->GetRootNode().get()); m_Ui.sceneTreeWidget->expandItem(m_Ui.sceneTreeWidget->topLevelItem(0)); } void QmitkSimulationView::SetSimulationControlsEnabled(bool enabled) { m_Ui.animateButton->setEnabled(enabled); m_Ui.stepButton->setEnabled(enabled); m_Ui.resetButton->setEnabled(enabled); m_Ui.dtLabel->setEnabled(enabled); m_Ui.dtSpinBox->setEnabled(enabled); } void QmitkSimulationView::SetFocus() { m_Ui.animateButton->setFocus(); }