diff --git a/Modules/Simulation/files.cmake b/Modules/Simulation/files.cmake index 7f49b08378..c8d5eae9a9 100644 --- a/Modules/Simulation/files.cmake +++ b/Modules/Simulation/files.cmake @@ -1,30 +1,31 @@ set(CPP_FILES mitkGetSimulationService.cpp mitkExportMitkVisitor.cpp mitkIndexROI.cpp mitkISimulationService.cpp mitkRoundRobinSchedulingAlgorithm.cpp mitkSetVtkRendererVisitor.cpp mitkSchedulableProcess.cpp mitkScheduler.cpp mitkSchedulingAlgorithmBase.cpp mitkSimulation.cpp mitkSimulationActivator.cpp + mitkSimulationGLMapper2D.cpp mitkSimulationInteractor.cpp mitkSimulationIOFactory.cpp mitkSimulationObjectFactory.cpp mitkSimulationReader.cpp mitkSimulationSerializer.cpp mitkSimulationService.cpp mitkSimulationVtkMapper3D.cpp mitkSimulationWriter.cpp mitkSimulationWriterFactory.cpp mitkVtkModel.cpp mitkVtkSimulationPolyDataMapper.cpp mitkWeightedRoundRobinSchedulingAlgorithm.cpp ) set(RESOURCE_FILES Interactions/Simulation.xml Interactions/SimulationConfig.xml ) diff --git a/Modules/Simulation/mitkSetVtkRendererVisitor.cpp b/Modules/Simulation/mitkSetVtkRendererVisitor.cpp index 4bb04053ca..5b16630a27 100644 --- a/Modules/Simulation/mitkSetVtkRendererVisitor.cpp +++ b/Modules/Simulation/mitkSetVtkRendererVisitor.cpp @@ -1,42 +1,58 @@ /*=================================================================== 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 "mitkVtkModel.h" mitk::SetVtkRendererVisitor::SetVtkRendererVisitor(vtkRenderer* renderer, const sofa::core::ExecParams* params) : Visitor(params), - m_VtkRenderer(renderer) + m_VtkRenderer(renderer), + m_RenderingMode(VtkModel::Default) +{ +} + +mitk::SetVtkRendererVisitor::SetVtkRendererVisitor(vtkRenderer* renderer, const Point3D& planePoint, const Vector3D& planeNormal, ScalarType planeThickness, const sofa::core::ExecParams* params) + : Visitor(params), + m_RenderingMode(VtkModel::ClippingPlanes), + m_PlanePoint(planePoint), + m_PlaneNormal(planeNormal), + m_PlaneThickness(planeThickness) { } mitk::SetVtkRendererVisitor::~SetVtkRendererVisitor() { } sofa::simulation::Visitor::Result mitk::SetVtkRendererVisitor::processNodeTopDown(sofa::simulation::Node* node) { for_each(this, node, node->visualModel, &SetVtkRendererVisitor::processVisualModel); return RESULT_CONTINUE; } void mitk::SetVtkRendererVisitor::processVisualModel(sofa::simulation::Node*, sofa::core::visual::VisualModel* visualModel) { VtkModel* vtkModel = dynamic_cast(visualModel); if (vtkModel != NULL) + { vtkModel->SetVtkRenderer(m_VtkRenderer); + vtkModel->SetRenderingMode(m_RenderingMode); + + if (m_RenderingMode == VtkModel::ClippingPlanes) + vtkModel->SetPlane(m_PlanePoint, m_PlaneNormal, m_PlaneThickness); + } } diff --git a/Modules/Simulation/mitkSetVtkRendererVisitor.h b/Modules/Simulation/mitkSetVtkRendererVisitor.h index 93ebc0d385..89ef566879 100644 --- a/Modules/Simulation/mitkSetVtkRendererVisitor.h +++ b/Modules/Simulation/mitkSetVtkRendererVisitor.h @@ -1,45 +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. ===================================================================*/ #ifndef mitkSetVtkRendererVisitor_h #define mitkSetVtkRendererVisitor_h +#include #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(vtkRenderer* renderer, const Point3D& planePoint, const Vector3D& planeNormal, ScalarType planeThickness = 1.0, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ~SetVtkRendererVisitor(); 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; + VtkModel::RenderingMode m_RenderingMode; + Point3D m_PlanePoint; + Vector3D m_PlaneNormal; + ScalarType m_PlaneThickness; }; } #endif diff --git a/Modules/Simulation/mitkSimulationGLMapper2D.cpp b/Modules/Simulation/mitkSimulationGLMapper2D.cpp new file mode 100644 index 0000000000..7b93d3e4b2 --- /dev/null +++ b/Modules/Simulation/mitkSimulationGLMapper2D.cpp @@ -0,0 +1,81 @@ +/*=================================================================== + +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 "mitkSetVtkRendererVisitor.h" +#include "mitkSimulation.h" +#include "mitkSimulationGLMapper2D.h" +#include + +void mitk::SimulationGLMapper2D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer, bool overwrite) +{ + if (node != NULL) + { + Superclass::SetDefaultProperties(node, renderer, overwrite); + } +} + +mitk::SimulationGLMapper2D::SimulationGLMapper2D() + : m_SimulationService(GetSimulationService()) +{ +} + +mitk::SimulationGLMapper2D::~SimulationGLMapper2D() +{ +} + +void mitk::SimulationGLMapper2D::ApplyColorAndOpacityProperties(BaseRenderer*, vtkActor*) +{ +} + +void mitk::SimulationGLMapper2D::Paint(BaseRenderer* renderer) +{ + if (renderer == NULL) + return; + + SliceNavigationController* sliceNavigationController = renderer->GetSliceNavigationController(); + + if (sliceNavigationController == NULL) + return; + + const PlaneGeometry* planeGeometry = sliceNavigationController->GetCurrentPlaneGeometry(); + + if (planeGeometry == NULL) + return; + + DataNode* dataNode = this->GetDataNode(); + + if (dataNode == NULL) + return; + + Simulation* simulation = static_cast(dataNode->GetData()); + + if (simulation == NULL) + return; + + SetVtkRendererVisitor setVtkRendererVisitor(renderer->GetVtkRenderer(), planeGeometry->GetOrigin(), planeGeometry->GetNormal()); + simulation->GetRootNode()->executeVisitor(&setVtkRendererVisitor); + + m_SimulationService->SetActiveSimulation(simulation); + + sofa::core::visual::VisualParams* vParams = sofa::core::visual::VisualParams::defaultInstance(); + sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSOFASimulation(); + sofa::simulation::Node::SPtr rootNode = simulation->GetRootNode(); + + sofaSimulation->updateVisual(rootNode.get()); // TODO: Check if this is happening only once per time step. + sofaSimulation->draw(vParams, rootNode.get()); +} diff --git a/Modules/Simulation/mitkSimulationGLMapper2D.h b/Modules/Simulation/mitkSimulationGLMapper2D.h new file mode 100644 index 0000000000..21c53c87be --- /dev/null +++ b/Modules/Simulation/mitkSimulationGLMapper2D.h @@ -0,0 +1,50 @@ +/*=================================================================== + +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 mitkSimulationGLMapper2D_h +#define mitkSimulationGLMapper2D_h + +#include +#include + +namespace mitk +{ + class ISimulationService; + + class MitkSimulation_EXPORT SimulationGLMapper2D : public GLMapper + { + public: + static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); + + mitkClassMacro(SimulationGLMapper2D, GLMapper); + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + void ApplyColorAndOpacityProperties(BaseRenderer* renderer, vtkActor* actor = NULL); + void Paint(BaseRenderer* renderer); + + private: + SimulationGLMapper2D(); + ~SimulationGLMapper2D(); + + SimulationGLMapper2D(const Self&); + Self& operator=(const Self&); + + ISimulationService* m_SimulationService; + }; +} + +#endif diff --git a/Modules/Simulation/mitkSimulationObjectFactory.cpp b/Modules/Simulation/mitkSimulationObjectFactory.cpp index 320009f7bc..0304cd92f6 100644 --- a/Modules/Simulation/mitkSimulationObjectFactory.cpp +++ b/Modules/Simulation/mitkSimulationObjectFactory.cpp @@ -1,143 +1,153 @@ /*=================================================================== 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 "mitkIndexROI.h" #include "mitkSimulation.h" +#include "mitkSimulationGLMapper2D.h" #include "mitkSimulationObjectFactory.h" #include "mitkSimulationVtkMapper3D.h" #include "mitkSimulationWriter.h" #include "mitkVtkModel.h" #include #include #include #include #include #include static void InitializeSofa() { int argc = 0; glutInit(&argc, NULL); sofa::component::init(); sofa::simulation::xml::initXml(); sofa::core::visual::VisualParams::defaultInstance()->setSupported(sofa::core::visual::API_OpenGL); } static void RegisterSofaClasses() { using sofa::core::ObjectFactory; using sofa::core::RegisterObject; int IndexROIClass = RegisterObject("").add(); int VtkModelClass = RegisterObject("").add(); ObjectFactory::AddAlias("VisualModel", "VtkModel", true); ObjectFactory::AddAlias("OglModel", "VtkModel", true); } mitk::SimulationObjectFactory::SimulationObjectFactory() : m_SimulationIOFactory(SimulationIOFactory::New()), m_SimulationWriterFactory(SimulationWriterFactory::New()) { itk::ObjectFactoryBase::RegisterFactory(m_SimulationIOFactory); itk::ObjectFactoryBase::RegisterFactory(m_SimulationWriterFactory); m_FileWriters.push_back(SimulationWriter::New().GetPointer()); std::string description = "SOFA Scene Files"; m_FileExtensionsMap.insert(std::pair("*.scn", description)); InitializeSofa(); RegisterSofaClasses(); } mitk::SimulationObjectFactory::~SimulationObjectFactory() { itk::ObjectFactoryBase::UnRegisterFactory(m_SimulationWriterFactory); itk::ObjectFactoryBase::UnRegisterFactory(m_SimulationIOFactory); } mitk::Mapper::Pointer mitk::SimulationObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId slotId) { Mapper::Pointer mapper; if (dynamic_cast(node->GetData()) != NULL) { - if (slotId == BaseRenderer::Standard3D) - mapper = mitk::SimulationVtkMapper3D::New(); + if (slotId == BaseRenderer::Standard2D) + { + mapper = SimulationGLMapper2D::New(); + } + else if (slotId == BaseRenderer::Standard3D) + { + mapper = SimulationVtkMapper3D::New(); + } if (mapper.IsNotNull()) mapper->SetDataNode(node); } return mapper; } const char* mitk::SimulationObjectFactory::GetDescription() const { return "Simulation Object Factory"; } const char* mitk::SimulationObjectFactory::GetFileExtensions() { std::string fileExtensions; this->CreateFileExtensions(m_FileExtensionsMap, fileExtensions); return fileExtensions.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::SimulationObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } const char* mitk::SimulationObjectFactory::GetITKSourceVersion() const { return ITK_SOURCE_VERSION; } const char* mitk::SimulationObjectFactory::GetSaveFileExtensions() { std::string saveFileExtensions; this->CreateFileExtensions(m_FileExtensionsMap, saveFileExtensions); return saveFileExtensions.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::SimulationObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } void mitk::SimulationObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if (node == NULL) return; if (dynamic_cast(node->GetData()) != NULL) + { + SimulationGLMapper2D::SetDefaultProperties(node); SimulationVtkMapper3D::SetDefaultProperties(node); + } } void mitk::RegisterSimulationObjectFactory() { static bool alreadyRegistered = false; if (!alreadyRegistered) { - mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(mitk::SimulationObjectFactory::New()); + CoreObjectFactory::GetInstance()->RegisterExtraFactory(SimulationObjectFactory::New()); alreadyRegistered = true; } } diff --git a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp index 718e58a7ba..6276f50e63 100644 --- a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp +++ b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp @@ -1,159 +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 "mitkVtkSimulationPolyDataMapper.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(vtkActor*, BaseRenderer*) { } 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()); 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) { - Simulation* simulation = static_cast(this->GetData()); + DataNode* dataNode = this->GetDataNode(); - if (simulation != NULL) - { - LocalStorage* localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); + if (dataNode == NULL) + return; - if (localStorage->m_Mapper == NULL) - { - localStorage->m_Mapper = vtkSmartPointer::New(); - localStorage->m_Mapper->SetSimulation(simulation); + Simulation* simulation = static_cast(dataNode->GetData()); - localStorage->m_Actor->SetMapper(localStorage->m_Mapper); + if (simulation == NULL) + return; - SetVtkRendererVisitor initVisitor(renderer->GetVtkRenderer()); - simulation->GetRootNode()->executeVisitor(&initVisitor); - } + LocalStorage* localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); - this->ApplySimulationProperties(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 83e493433e..54c929625b 100644 --- a/Modules/Simulation/mitkVtkModel.cpp +++ b/Modules/Simulation/mitkVtkModel.cpp @@ -1,390 +1,430 @@ /*=================================================================== 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 bool mitk::VtkModel::IsGlewInitialized = false; mitk::VtkModel::VtkModel() : m_BuffersCreated(false), m_LastNumberOfVertices(0), m_LastNumberOfTriangles(0), m_LastNumberOfQuads(0), m_VertexBuffer(0), m_IndexBuffer(0), - m_VtkRenderer(NULL) + m_VtkRenderer(NULL), + m_RenderingMode(Default) { if (!IsGlewInitialized) { GLenum error = glewInit(); if (error != GLEW_OK) MITK_ERROR("glewInit") << glewGetErrorString(error); else IsGlewInitialized = true; } } mitk::VtkModel::~VtkModel() { /*if (m_BuffersCreated) { glDeleteBuffers(1, &m_IndexBuffer); glDeleteBuffers(1, &m_VertexBuffer); }*/ } void mitk::VtkModel::CreateIndexBuffer() { glGenBuffers(1, &m_IndexBuffer); this->InitIndexBuffer(); } void mitk::VtkModel::CreateVertexBuffer() { glGenBuffers(1, &m_VertexBuffer); this->InitVertexBuffer(); } void mitk::VtkModel::DrawGroup(int group, bool) { using sofa::core::loader::Material; using sofa::defaulttype::ResizableExtVector; using sofa::defaulttype::Vec4f; const VecCoord& vertices = this->getVertices(); const ResizableExtVector& normals = this->getVnormals(); const ResizableExtVector& triangles = this->getTriangles(); const ResizableExtVector& quads = this->getQuads(); FaceGroup faceGroup; 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(); 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); } 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; if (shininess == 0.0f) { specular.clear(); shininess = 1.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 (faceGroup.nbt != 0) glDrawElements(GL_TRIANGLES, faceGroup.nbt * 3, GL_UNSIGNED_INT, reinterpret_cast(faceGroup.tri0 * sizeof(Triangle))); if (faceGroup.nbq != 0) glDrawElements(GL_QUADS, faceGroup.nbq * 4, GL_UNSIGNED_INT, reinterpret_cast(triangles.size() * sizeof(Triangle) + faceGroup.quad0 * sizeof(Quad))); if (material.useTexture && material.activated) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); m_Textures[faceGroup.materialId]->PostRender(m_VtkRenderer); } } 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(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles.size() * sizeof(Triangle) + quads.size() * sizeof(Quad), NULL, GL_DYNAMIC_DRAW); 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(); GLsizeiptr sizeOfVertices = vertices.size() * sizeof(VecCoord::value_type); GLsizeiptr sizeOfNormals = normals.size() * sizeof(Deriv); GLsizeiptr sizeOfTexCoords = texCoords.size() * sizeof(VecTexCoord::value_type); glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeOfVertices + sizeOfNormals + sizeOfTexCoords, NULL, GL_DYNAMIC_DRAW); this->UpdateVertexBuffer(); } void mitk::VtkModel::internalDraw(const sofa::core::visual::VisualParams* vparams, bool transparent) { using sofa::core::visual::DisplayFlags; using sofa::defaulttype::ResizableExtVector; if (!IsGlewInitialized) return; const DisplayFlags& displayFlags = vparams->displayFlags(); if (!displayFlags.getShowVisualModels()) return; + if (m_RenderingMode == ClippingPlanes) + { + glClipPlane(GL_CLIP_PLANE0, m_ClippingPlaneEquation0); + glEnable(GL_CLIP_PLANE0); + + glClipPlane(GL_CLIP_PLANE1, m_ClippingPlaneEquation1); + glEnable(GL_CLIP_PLANE1); + } + 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(); const ResizableExtVector& normals = this->getVnormals(); const VecTexCoord& texCoords = this->getVtexcoords(); glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer); 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); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); if (displayFlags.getShowWireFrame()) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_LIGHTING); if (displayFlags.getShowNormals()) this->DrawNormals(); + + if (m_RenderingMode == ClippingPlanes) + { + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE0); + } } void mitk::VtkModel::DrawNormals() { using sofa::defaulttype::ResizableExtVector; 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; } +void mitk::VtkModel::SetPlane(const Point3D& point, const Vector3D& normal, ScalarType thickness) +{ + Point3D point0 = point - normal * (thickness * 0.5); + Point3D point1 = point + normal * (thickness * 0.5); + + // Plane equation: A*x + B*x + C*x + D = 0 + // A, B, and C are the plane normal components and D is the plane distance from origin + + m_ClippingPlaneEquation0[0] = normal[0]; + m_ClippingPlaneEquation0[1] = normal[1]; + m_ClippingPlaneEquation0[2] = normal[2]; + m_ClippingPlaneEquation0[3] = -(normal[0] * point0[0] + normal[1] * point0[1] + normal[2] * point0[2]); + + m_ClippingPlaneEquation1[0] = -normal[0]; + m_ClippingPlaneEquation1[1] = -normal[1]; + m_ClippingPlaneEquation1[2] = -normal[2]; + m_ClippingPlaneEquation1[3] = normal[0] * point1[0] + normal[1] * point1[1] + normal[2] * point1[2]; +} + +void mitk::VtkModel::SetRenderingMode(RenderingMode renderingMode) +{ + m_RenderingMode = renderingMode; +} + void mitk::VtkModel::SetVtkRenderer(vtkRenderer* renderer) { m_VtkRenderer = renderer; } void mitk::VtkModel::updateBuffers() { using sofa::defaulttype::ResizableExtVector; const VecCoord& vertices = this->getVertices(); const ResizableExtVector& triangles = this->getTriangles(); const ResizableExtVector& quads = this->getQuads(); if (!IsGlewInitialized) return; if (!m_BuffersCreated) { this->CreateVertexBuffer(); this->CreateIndexBuffer(); m_BuffersCreated = 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); 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()); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void mitk::VtkModel::UpdateVertexBuffer() { using sofa::defaulttype::ResizableExtVector; const VecCoord& vertices = this->getVertices(); const ResizableExtVector normals = this->getVnormals(); const VecTexCoord& texCoords = this->getVtexcoords(); 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()); } glBindBuffer(GL_ARRAY_BUFFER, 0); } diff --git a/Modules/Simulation/mitkVtkModel.h b/Modules/Simulation/mitkVtkModel.h index 277602e9af..3cd3b13c7c 100644 --- a/Modules/Simulation/mitkVtkModel.h +++ b/Modules/Simulation/mitkVtkModel.h @@ -1,70 +1,83 @@ /*=================================================================== 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 class vtkOpenGLTexture; class vtkRenderer; namespace mitk { class MitkSimulation_EXPORT VtkModel : public sofa::component::visualmodel::VisualModelImpl { public: SOFA_CLASS(VtkModel, sofa::component::visualmodel::VisualModelImpl); + enum RenderingMode + { + Default, + ClippingPlanes + }; + void internalDraw(const sofa::core::visual::VisualParams* vparams, bool transparent); bool loadTextures(); + void SetRenderingMode(RenderingMode renderingMode); + void SetPlane(const Point3D& point, const Vector3D& normal, ScalarType thickness = 1.0); void SetVtkRenderer(vtkRenderer* renderer); void updateBuffers(); private: static bool IsGlewInitialized; VtkModel(); ~VtkModel(); VtkModel(MyType&); MyType& operator=(const MyType&); void CreateIndexBuffer(); void CreateVertexBuffer(); void DrawGroup(int group, bool); void DrawGroups(bool transparent); void DrawNormals(); void InitIndexBuffer(); void InitVertexBuffer(); void UpdateIndexBuffer(); void UpdateVertexBuffer(); bool m_BuffersCreated; 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; + RenderingMode m_RenderingMode; + GLdouble m_ClippingPlaneEquation0[4]; + GLdouble m_ClippingPlaneEquation1[4]; }; } #endif