diff --git a/Modules/Simulation/Resources/Interactions/Simulation.xml b/Modules/Simulation/Resources/Interactions/Simulation.xml new file mode 100644 index 0000000000..2018c2c7ef --- /dev/null +++ b/Modules/Simulation/Resources/Interactions/Simulation.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/Simulation/Resources/Interactions/SimulationConfig.xml b/Modules/Simulation/Resources/Interactions/SimulationConfig.xml new file mode 100644 index 0000000000..4be2b1b2de --- /dev/null +++ b/Modules/Simulation/Resources/Interactions/SimulationConfig.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/Simulation/files.cmake b/Modules/Simulation/files.cmake index 5f1af8292c..7f49b08378 100644 --- a/Modules/Simulation/files.cmake +++ b/Modules/Simulation/files.cmake @@ -1,24 +1,30 @@ 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 + 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/mitkSimulation.cpp b/Modules/Simulation/mitkSimulation.cpp index a42c8594b9..99f7518c1c 100644 --- a/Modules/Simulation/mitkSimulation.cpp +++ b/Modules/Simulation/mitkSimulation.cpp @@ -1,167 +1,169 @@ /*=================================================================== 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 #include "mitkGeometry3D.h" static sofa::simulation::Simulation::SPtr CreateSimulation() { const std::string key = "MultiMappingObject"; if (sofa::simulation::xml::BaseElement::NodeFactory::HasKey(key)) sofa::simulation::xml::BaseElement::NodeFactory::ResetEntry(key); return sofa::core::objectmodel::New(); } mitk::Simulation::Simulation() : m_SOFASimulation(CreateSimulation()) { } mitk::Simulation::~Simulation() { if (m_RootNode) { if (m_SOFASimulation) m_SOFASimulation->unload(m_RootNode); } } void mitk::Simulation::Animate() { if (!m_RootNode || !m_SOFASimulation) return; boost::chrono::high_resolution_clock::time_point t0 = boost::chrono::high_resolution_clock::now(); m_SOFASimulation->animate(m_RootNode.get(), m_RootNode->getDt()); this->SetElapsedTime(boost::chrono::high_resolution_clock::now() - t0); + + this->UpdateOutputInformation(); } sofa::core::visual::DrawTool* mitk::Simulation::GetDrawTool() { return &m_DrawTool; } sofa::simulation::Node::SPtr mitk::Simulation::GetRootNode() const { return m_RootNode; } sofa::simulation::Simulation::SPtr mitk::Simulation::GetSOFASimulation() const { return m_SOFASimulation; } void mitk::Simulation::Reset() { if (!m_RootNode || !m_SOFASimulation) return; m_SOFASimulation->reset(m_RootNode.get()); m_RootNode->setTime(0.0); m_SOFASimulation->updateContext(m_RootNode.get()); } bool mitk::Simulation::GetAnimationFlag() const { return m_RootNode ? m_RootNode->getContext()->getAnimate() : false; } void mitk::Simulation::SetAnimationFlag(bool animate) { if (m_RootNode) m_RootNode->getContext()->setAnimate(animate); } void mitk::Simulation::SetDt(double dt) { if (m_RootNode) m_RootNode->setDt(dt); } void mitk::Simulation::SetRootNode(sofa::simulation::Node::SPtr rootNode) { m_RootNode = rootNode; } bool mitk::Simulation::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } void mitk::Simulation::SetRequestedRegion(const itk::DataObject*) { } void mitk::Simulation::SetRequestedRegionToLargestPossibleRegion() { } void mitk::Simulation::UpdateOutputInformation() { using sofa::defaulttype::BoundingBox; using sofa::defaulttype::Vector3; if (this->GetSource().IsNotNull()) this->GetSource()->UpdateOutputInformation(); if (m_RootNode) { const BoundingBox& boundingBox = m_RootNode->f_bbox.getValue(); mitk::Geometry3D::BoundsArrayType bounds; if (boundingBox.isValid()) { const Vector3& min = boundingBox.minBBox(); const Vector3& max = boundingBox.maxBBox(); bounds[0] = static_cast(min.x()); bounds[1] = static_cast(max.x()); bounds[2] = static_cast(min.y()); bounds[3] = static_cast(max.y()); bounds[4] = static_cast(min.z()); bounds[5] = static_cast(max.z()); } else { bounds.Fill(0.0f); } mitk::BaseGeometry::Pointer geometry = this->GetGeometry(); if (geometry.IsNull()) { geometry = Geometry3D::New(); geometry->SetBounds(bounds); this->SetGeometry(geometry); } else { geometry->SetBounds(bounds); } } this->GetTimeGeometry()->Update(); } bool mitk::Simulation::VerifyRequestedRegion() { return true; } diff --git a/Modules/Simulation/mitkSimulationInteractor.cpp b/Modules/Simulation/mitkSimulationInteractor.cpp new file mode 100644 index 0000000000..307ebd03b8 --- /dev/null +++ b/Modules/Simulation/mitkSimulationInteractor.cpp @@ -0,0 +1,510 @@ +/*=================================================================== + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mitkSimulation.h" +#include "mitkSimulationInteractor.h" + +using sofa::component::collision::BaseRayContact; +using sofa::component::collision::BodyPicked; +using sofa::component::collision::ComponentMouseInteraction; +using sofa::component::collision::FixParticlePerformerConfiguration; +using sofa::component::collision::InteractionPerformer; +using sofa::component::collision::Ray; +using sofa::component::collision::RayModel; +using sofa::component::container::MechanicalObject; +using sofa::core::behavior::BaseMechanicalState; +using sofa::core::collision::DetectionOutput; +using sofa::core::collision::Pipeline; +using sofa::core::objectmodel::BaseContext; +using sofa::core::CollisionElementIterator; +using sofa::core::ExecParams; +using sofa::core::MechanicalParams; +using sofa::core::VecCoordId; +using sofa::defaulttype::dot; +using sofa::defaulttype::Vec3d; +using sofa::defaulttype::Vec3Types; +using sofa::helper::vector; +using sofa::simulation::CollisionVisitor; +using sofa::simulation::DeleteVisitor; +using sofa::simulation::MechanicalPickParticlesVisitor; +using sofa::simulation::MechanicalPropagatePositionVisitor; +using sofa::simulation::Node; + +namespace mitk +{ + class SimulationInteractor::Impl + { + public: + Impl(); + ~Impl(); + + void Initialize(Node::SPtr rootNode); + void Uninitialize(); + void AttachMouseNode(); + void DetachMouseNode(); + bool IsMouseNodeAttached() const; + void UpdatePickRay(const InteractionPositionEvent* event); + void FindCollision(); + void AttachCompatibleInteraction(); + void DetachInteraction(bool setNull); + void StartInteraction(); + void ExecuteInteraction(); + void StopInteraction(); + + private: + Impl(const Impl&); + Impl& operator=(const Impl&); + + BodyPicked FindCollisionUsingPipeline(); + BodyPicked FindCollisionUsingBruteForce(); + void ConfigureInteractionPerformer(); + + Node::SPtr m_RootNode; + Node::SPtr m_MouseNode; + MechanicalObject::SPtr m_PickRayContainer; + RayModel::SPtr m_PickRayModel; + std::vector m_InteractionComponents; + ComponentMouseInteraction* m_Interaction; + std::auto_ptr m_InteractionPerformer; + bool m_IsMouseNodeAttached; + bool m_UseCollisionPipeline; + BodyPicked m_LastBodyPicked; + }; +} + +mitk::SimulationInteractor::Impl::Impl() + : m_Interaction(NULL), + m_IsMouseNodeAttached(false), + m_UseCollisionPipeline(true) +{ +} + +mitk::SimulationInteractor::Impl::~Impl() +{ + this->Uninitialize(); +} + +void mitk::SimulationInteractor::Impl::Initialize(const Node::SPtr rootNode) +{ + this->Uninitialize(); + + m_RootNode = rootNode; + + m_PickRayContainer = sofa::core::objectmodel::New >(); + m_PickRayContainer->setName("MousePosition"); + m_PickRayContainer->resize(1); + + m_PickRayModel = sofa::core::objectmodel::New(); + m_PickRayModel->setName("MouseCollisionModel"); + m_PickRayModel->setNbRay(1); + + m_MouseNode = rootNode->createChild("Mouse"); + m_MouseNode->addObject(m_PickRayContainer); + m_MouseNode->addObject(m_PickRayModel); + + m_MouseNode->init(ExecParams::defaultInstance()); + m_PickRayContainer->init(); + m_PickRayModel->init(); + + typedef ComponentMouseInteraction::ComponentMouseInteractionFactory Factory; + const Factory* factory = Factory::getInstance(); + + for (Factory::const_iterator it = factory->begin(); it != factory->end(); ++it) + m_InteractionComponents.push_back(it->second->createInstance(NULL)); + + m_MouseNode->detachFromGraph(); + + Pipeline* collisionPipeline; + rootNode->getContext()->get(collisionPipeline, BaseContext::SearchRoot); + + m_UseCollisionPipeline = collisionPipeline != NULL; +} + +void mitk::SimulationInteractor::Impl::Uninitialize() +{ + this->DetachMouseNode(); + + if (!m_InteractionComponents.empty()) + { + for (std::vector::iterator it = m_InteractionComponents.begin(); it != m_InteractionComponents.end(); ++it) + delete *it; + + m_InteractionComponents.clear(); + m_Interaction = NULL; + } + + if (m_MouseNode) + { + m_MouseNode->execute(ExecParams::defaultInstance()); + + m_PickRayModel.reset(); + m_PickRayContainer.reset(); + m_MouseNode.reset(); + m_RootNode.reset(); + } +} + +void mitk::SimulationInteractor::Impl::AttachMouseNode() +{ + if (!m_IsMouseNodeAttached) + { + m_RootNode->addChild(m_MouseNode); + m_IsMouseNodeAttached = true; + } +} + +void mitk::SimulationInteractor::Impl::DetachMouseNode() +{ + if (m_IsMouseNodeAttached) + { + this->DetachInteraction(false); + m_MouseNode->detachFromGraph(); + m_IsMouseNodeAttached = false; + } +} + +bool mitk::SimulationInteractor::Impl::IsMouseNodeAttached() const +{ + return m_IsMouseNodeAttached; +} + +void mitk::SimulationInteractor::Impl::UpdatePickRay(const InteractionPositionEvent* event) +{ + if (!m_IsMouseNodeAttached) + return; + + vtkCamera* camera = event->GetSender()->GetVtkRenderer()->GetActiveCamera(); + + Vec3d cameraOrigin(camera->GetPosition()); + Vec3d pickedPosition(event->GetPositionInWorld().GetDataPointer()); + Vec3d pickRayDirection(pickedPosition - cameraOrigin); + Vec3d focalPoint(camera->GetFocalPoint()); + + Vec3d cameraDirection(focalPoint - cameraOrigin); + cameraDirection.normalize(); + + std::pair clippingRange; + camera->GetClippingRange(clippingRange.first, clippingRange.second); + + double dotProduct = dot(cameraDirection, pickRayDirection); + double norm = pickRayDirection.norm(); + + clippingRange.first = clippingRange.first / dotProduct * norm; + clippingRange.second = clippingRange.second / dotProduct * norm; + + pickRayDirection.normalize(); + + Ray pickRay = m_PickRayModel->getRay(0); + pickRay.setOrigin(cameraOrigin + pickRayDirection * clippingRange.first); + pickRay.setDirection(pickRayDirection); + pickRay.setL(clippingRange.second - clippingRange.first); + + MechanicalPropagatePositionVisitor(MechanicalParams::defaultInstance(), 0, VecCoordId::position(), true) + .execute(m_PickRayModel->getContext()); + + MechanicalPropagatePositionVisitor(MechanicalParams::defaultInstance(), 0, VecCoordId::freePosition(), true) + .execute(m_PickRayModel->getContext()); +} + +void mitk::SimulationInteractor::Impl::FindCollision() +{ + CollisionVisitor(ExecParams::defaultInstance()).execute(m_RootNode->getContext()); + + if (m_UseCollisionPipeline) + { + MITK_INFO << "FindCollisionUsingPipeline()"; + m_LastBodyPicked = this->FindCollisionUsingPipeline(); + + if (m_LastBodyPicked.body != NULL) + return; + } + + MITK_INFO << "FindCollisionUsingBruteForce()"; + m_LastBodyPicked = this->FindCollisionUsingBruteForce(); + + if (m_LastBodyPicked.body == NULL && m_LastBodyPicked.mstate == NULL) + MITK_WARN << "No body picked!"; +} + +BodyPicked mitk::SimulationInteractor::Impl::FindCollisionUsingPipeline() +{ + BodyPicked bodyPicked; + + Ray ray = m_PickRayModel->getRay(0); + const Vec3d& origin = ray.origin(); + const Vec3d& direction = ray.direction(); + const double length = ray.l(); + + const std::set& contacts = m_PickRayModel->getContacts(); + + if (contacts.empty()) + MITK_WARN << "No picking contacts!"; + + for (std::set::const_iterator contact = contacts.begin(); contact != contacts.end(); ++contact) + { + const vector& detectionOutputs = (*contact)->getDetectionOutputs(); + + for (vector::const_iterator detectionOutput = detectionOutputs.begin(); detectionOutput != detectionOutputs.end(); ++detectionOutput) + { + CollisionElementIterator collisionElement; + int pointIndex; + + if ((*detectionOutput)->elem.first.getCollisionModel() == m_PickRayModel) + { + collisionElement = (*detectionOutput)->elem.second; + pointIndex = 1; + } + else if ((*detectionOutput)->elem.second.getCollisionModel() == m_PickRayModel) + { + collisionElement = (*detectionOutput)->elem.first; + pointIndex = 0; + } + else + { + continue; + } + + if (!collisionElement.getCollisionModel()->isSimulated()) + continue; + + const double t = ((*detectionOutput)->point[pointIndex] - origin) * direction; + + if (t < 0.0 || t > length) + continue; + + if (bodyPicked.body == NULL || t < bodyPicked.rayLength) + { + bodyPicked.body = collisionElement.getCollisionModel(); + bodyPicked.indexCollisionElement = collisionElement.getIndex(); + bodyPicked.point = (*detectionOutput)->point[pointIndex]; + bodyPicked.dist = ((*detectionOutput)->point[1] - (*detectionOutput)->point[0]).norm(); + bodyPicked.rayLength = t; + } + } + } + + return bodyPicked; +} + +BodyPicked mitk::SimulationInteractor::Impl::FindCollisionUsingBruteForce() +{ + BodyPicked bodyPicked; + + Ray ray = m_PickRayModel->getRay(0); + const Vec3d& origin = ray.origin(); + const Vec3d& direction = ray.direction(); + const double length = ray.l(); + + MechanicalPickParticlesVisitor pickVisitor(ExecParams::defaultInstance(), origin, direction, length); + pickVisitor.execute(m_RootNode->getContext()); + + if (!pickVisitor.particles.empty()) + { + bodyPicked.mstate = pickVisitor.particles.begin()->second.first; + bodyPicked.indexCollisionElement = pickVisitor.particles.begin()->second.second; + bodyPicked.point[0] = bodyPicked.mstate->getPX(bodyPicked.indexCollisionElement); + bodyPicked.point[1] = bodyPicked.mstate->getPY(bodyPicked.indexCollisionElement); + bodyPicked.point[2] = bodyPicked.mstate->getPZ(bodyPicked.indexCollisionElement); + bodyPicked.dist = 0; + bodyPicked.rayLength = (bodyPicked.point - origin) * direction; + } + else + { + MITK_WARN << "No particles picked!"; + } + + return bodyPicked; +} + +void mitk::SimulationInteractor::Impl::AttachCompatibleInteraction() +{ + BaseContext* context; + + if (m_LastBodyPicked.body == NULL) + { + context = m_LastBodyPicked.mstate != NULL + ? m_LastBodyPicked.mstate->getContext() + : NULL; + } + else + { + context = m_LastBodyPicked.body->getContext(); + } + + if (context != NULL) + { + if (m_Interaction == NULL || !m_Interaction->isCompatible(context)) + { + bool foundCompatibleInteractor = false; + + for (std::vector::const_iterator it = m_InteractionComponents.begin(); it != m_InteractionComponents.end(); ++it) + { + if (*it != m_Interaction && (*it)->isCompatible(context)) + { + this->DetachInteraction(false); + m_Interaction = *it; + m_Interaction->attach(m_MouseNode.get()); + + foundCompatibleInteractor = true; + break; + } + } + + if (!foundCompatibleInteractor) + this->DetachInteraction(true); + } + } + else + { + this->DetachInteraction(true); + } + + if (m_Interaction != NULL) + { + m_Interaction->mouseInteractor->setMouseRayModel(m_PickRayModel.get()); + m_Interaction->mouseInteractor->setBodyPicked(m_LastBodyPicked); + } +} + +void mitk::SimulationInteractor::Impl::DetachInteraction(bool setNull) +{ + if (m_Interaction != NULL) + { + m_Interaction->detach(); + + if (setNull) + m_Interaction = NULL; + } +} + +void mitk::SimulationInteractor::Impl::StartInteraction() +{ + if (m_Interaction == NULL) + return; + + InteractionPerformer::InteractionPerformerFactory* factory = InteractionPerformer::InteractionPerformerFactory::getInstance(); + m_InteractionPerformer.reset(factory->createObject("FixParticle", m_Interaction->mouseInteractor.get())); + + if (m_InteractionPerformer.get() != NULL) + { + this->ConfigureInteractionPerformer(); + m_Interaction->mouseInteractor->addInteractionPerformer(m_InteractionPerformer.get()); + m_InteractionPerformer->start(); + } +} + +void mitk::SimulationInteractor::Impl::ConfigureInteractionPerformer() +{ + FixParticlePerformerConfiguration* configuration = dynamic_cast(m_InteractionPerformer.get()); + + if (configuration != NULL) + configuration->setStiffness(10000); +} + +void mitk::SimulationInteractor::Impl::ExecuteInteraction() +{ + if (m_InteractionPerformer.get() == NULL) + return; + + m_InteractionPerformer->execute(); +} + +void mitk::SimulationInteractor::Impl::StopInteraction() +{ + if (m_InteractionPerformer.get() == NULL) + return; + + m_Interaction->mouseInteractor->removeInteractionPerformer(m_InteractionPerformer.get()); + m_InteractionPerformer.release(); +} + +mitk::SimulationInteractor::SimulationInteractor() + : m_Impl(new Impl) +{ +} + +mitk::SimulationInteractor::~SimulationInteractor() +{ +} + +void mitk::SimulationInteractor::ConnectActionsAndFunctions() +{ + CONNECT_FUNCTION("attachMouseNode", AttachMouseNode); + CONNECT_FUNCTION("detachMouseNode", DetachMouseNode); + CONNECT_FUNCTION("moveMouse", MoveMouse); + CONNECT_CONDITION("isMouseNodeAttached", IsMouseNodeAttached); +} + +void mitk::SimulationInteractor::DataNodeChanged() +{ + this->ResetToStartState(); + + NodeType dataNode = this->GetDataNode(); + + if (dataNode.IsNotNull()) + { + Simulation::Pointer simulation = dynamic_cast(dataNode->GetData()); + + if (simulation.IsNotNull()) + { + m_Impl->Initialize(simulation->GetRootNode()); + return; + } + } + + m_Impl->Uninitialize(); +} + +bool mitk::SimulationInteractor::AttachMouseNode(StateMachineAction*, InteractionEvent* event) +{ + m_Impl->AttachMouseNode(); + m_Impl->UpdatePickRay(dynamic_cast(event)); + m_Impl->FindCollision(); + m_Impl->AttachCompatibleInteraction(); + m_Impl->StartInteraction(); + + return true; +} + +bool mitk::SimulationInteractor::DetachMouseNode(StateMachineAction*, InteractionEvent*) +{ + m_Impl->StopInteraction(); + m_Impl->DetachMouseNode(); + return true; +} + +bool mitk::SimulationInteractor::MoveMouse(StateMachineAction*, InteractionEvent* event) +{ + m_Impl->UpdatePickRay(dynamic_cast(event)); + m_Impl->ExecuteInteraction(); + return true; +} + +bool mitk::SimulationInteractor::IsMouseNodeAttached(const InteractionEvent*) +{ + return m_Impl->IsMouseNodeAttached(); +} diff --git a/Modules/Simulation/mitkSimulationInteractor.h b/Modules/Simulation/mitkSimulationInteractor.h new file mode 100644 index 0000000000..55757c3c89 --- /dev/null +++ b/Modules/Simulation/mitkSimulationInteractor.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 mitkSimulationInteractor_h +#define mitkSimulationInteractor_h + +#include +#include + +namespace mitk +{ + class MitkSimulation_EXPORT SimulationInteractor : public DataInteractor + { + public: + mitkClassMacro(SimulationInteractor, DataInteractor); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + protected: + void ConnectActionsAndFunctions(); + void DataNodeChanged(); + + private: + SimulationInteractor(); + ~SimulationInteractor(); + + bool AttachMouseNode(StateMachineAction* action, InteractionEvent* event); + bool DetachMouseNode(StateMachineAction* action, InteractionEvent* event); + bool MoveMouse(StateMachineAction* action, InteractionEvent* event); + bool IsMouseNodeAttached(const InteractionEvent* event); + + class Impl; + std::auto_ptr m_Impl; + }; +} + +#endif diff --git a/Modules/Simulation/mitkSimulationObjectFactory.cpp b/Modules/Simulation/mitkSimulationObjectFactory.cpp index 572949610d..320009f7bc 100644 --- a/Modules/Simulation/mitkSimulationObjectFactory.cpp +++ b/Modules/Simulation/mitkSimulationObjectFactory.cpp @@ -1,140 +1,143 @@ /*=================================================================== 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 "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 (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) SimulationVtkMapper3D::SetDefaultProperties(node); } void mitk::RegisterSimulationObjectFactory() { static bool alreadyRegistered = false; if (!alreadyRegistered) { mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(mitk::SimulationObjectFactory::New()); alreadyRegistered = true; } } diff --git a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp index ceb433bfec..718e58a7ba 100644 --- a/Modules/Simulation/mitkSimulationVtkMapper3D.cpp +++ b/Modules/Simulation/mitkSimulationVtkMapper3D.cpp @@ -1,160 +1,159 @@ /*=================================================================== 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()); if (simulation != NULL) { 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 initVisitor(renderer->GetVtkRenderer()); simulation->GetRootNode()->executeVisitor(&initVisitor); } this->ApplySimulationProperties(renderer); } } vtkProp* mitk::SimulationVtkMapper3D::GetVtkProp(BaseRenderer* renderer) { return m_LocalStorageHandler.GetLocalStorage(renderer)->m_Actor; } diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp index 242b0f6221..27fdb4cd97 100644 --- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp +++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp @@ -1,66 +1,86 @@ /*=================================================================== 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 "mitkVtkSimulationPolyDataMapper.h" #include #include #include #include namespace mitk { vtkStandardNewMacro(vtkSimulationPolyDataMapper); } mitk::vtkSimulationPolyDataMapper::vtkSimulationPolyDataMapper() : m_SimulationService(GetSimulationService()) { } mitk::vtkSimulationPolyDataMapper::~vtkSimulationPolyDataMapper() { } void mitk::vtkSimulationPolyDataMapper::Render(vtkRenderer* renderer, vtkActor* actor) { if (renderer->GetRenderWindow()->CheckAbortStatus()) return; if (m_Simulation.IsNull()) return; renderer->GetRenderWindow()->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()); } void mitk::vtkSimulationPolyDataMapper::RenderPiece(vtkRenderer*, vtkActor*) { } void mitk::vtkSimulationPolyDataMapper::SetSimulation(Simulation::Pointer simulation) { m_Simulation = simulation; } + +double* mitk::vtkSimulationPolyDataMapper::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/mitkVtkSimulationPolyDataMapper.h b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h index fbfa866325..1590536318 100644 --- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h +++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h @@ -1,47 +1,48 @@ /*=================================================================== 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 mitkVtkSimulationPolyDataMapper_h #define mitkVtkSimulationPolyDataMapper_h #include #include #include namespace mitk { class ISimulationService; class MitkSimulation_EXPORT vtkSimulationPolyDataMapper : public vtkPolyDataMapper { public: static vtkSimulationPolyDataMapper* New(); vtkTypeMacro(vtkSimulationPolyDataMapper, vtkPolyDataMapper); + double* GetBounds(); void Render(vtkRenderer* renderer, vtkActor* actor); void RenderPiece(vtkRenderer*, vtkActor*); void SetSimulation(mitk::Simulation::Pointer simulation); private: vtkSimulationPolyDataMapper(); ~vtkSimulationPolyDataMapper(); Simulation::Pointer m_Simulation; ISimulationService* m_SimulationService; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/files.cmake b/Plugins/org.mitk.gui.qt.simulation/files.cmake index 73c35280fd..744bd1618c 100644 --- a/Plugins/org.mitk.gui.qt.simulation/files.cmake +++ b/Plugins/org.mitk.gui.qt.simulation/files.cmake @@ -1,41 +1,47 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_simulation_Activator.cpp + QmitkBaseItemDelegate.cpp + QmitkBaseTreeWidget.cpp + QmitkNoEditItemDelegate.cpp + QmitkSceneTreeWidget.cpp QmitkSimulationPreferencePage.cpp - QmitkSimulationSceneTreeWidget.cpp QmitkSimulationView.cpp ) set(UI_FILES src/internal/QmitkSimulationPreferencePageControls.ui src/internal/QmitkSimulationViewControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_simulation_Activator.h + src/internal/QmitkBaseItemDelegate.h + src/internal/QmitkBaseTreeWidget.h + src/internal/QmitkNoEditItemDelegate.h + src/internal/QmitkSceneTreeWidget.h src/internal/QmitkSimulationPreferencePage.h - src/internal/QmitkSimulationSceneTreeWidget.h src/internal/QmitkSimulationView.h ) set(CACHED_RESOURCE_FILES resources/SOFAIcon.png plugin.xml ) set(QRC_FILES resources/Simulation.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach() foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach() diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp new file mode 100644 index 0000000000..dfc589a25d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp @@ -0,0 +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. + +===================================================================*/ + +#include "QmitkBaseItemDelegate.h" +#include + +using namespace sofa::defaulttype; +using namespace sofa::core::objectmodel; + +static inline BaseData* GetBaseData(const QModelIndex& index) +{ + return index.data(Qt::UserRole).value(); +} + +QmitkBaseItemDelegate::QmitkBaseItemDelegate(QObject* parent) + : QStyledItemDelegate(parent) +{ +} + +QmitkBaseItemDelegate::~QmitkBaseItemDelegate() +{ +} + +QWidget* QmitkBaseItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + BaseData* baseData = GetBaseData(index); + const AbstractTypeInfo* typeInfo = baseData->getValueTypeInfo(); + + if (typeInfo->name() == "bool") + { + assert(false && "Bool type is directly handled by QmitkBaseTreeWidget!"); + } + else if (typeInfo->size() == 1) + { + if (typeInfo->Integer() || typeInfo->Scalar() || typeInfo->Text()) + { + // TODO: TagSet + return QStyledItemDelegate::createEditor(parent, option, index); + } + + // TODO + } + else + { + // TODO + } + + return NULL; +} + +void QmitkBaseItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QStyledItemDelegate::paint(painter, option, index); +} + +void QmitkBaseItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + QStyledItemDelegate::setEditorData(editor, index); +} + +void QmitkBaseItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +{ + QStyledItemDelegate::setModelData(editor, model, index); +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h new file mode 100644 index 0000000000..01a009a16d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 QmitkBaseItemDelegate_h +#define QmitkBaseItemDelegate_h + +#include + +namespace sofa +{ + namespace core + { + namespace objectmodel + { + class BaseData; + } + } +} + +class QmitkBaseItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit QmitkBaseItemDelegate(QObject* parent = NULL); + ~QmitkBaseItemDelegate(); + + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void setEditorData(QWidget* editor, const QModelIndex& index) const; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; +}; + +Q_DECLARE_METATYPE(sofa::core::objectmodel::BaseData*) + +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp new file mode 100644 index 0000000000..60fa449d06 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp @@ -0,0 +1,115 @@ +/*=================================================================== + +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 +#include "QmitkBaseTreeWidget.h" +#include "QmitkBaseItemDelegate.h" +#include "QmitkNoEditItemDelegate.h" +#include "QmitkSceneTreeWidget.h" + +QmitkBaseTreeWidget::QmitkBaseTreeWidget(QWidget* parent) + : QTreeWidget(parent), + m_Base(NULL) +{ + this->setItemDelegateForColumn(0, new QmitkNoEditItemDelegate); + this->setItemDelegateForColumn(1, new QmitkBaseItemDelegate); + + this->setSortingEnabled(true); + this->header()->setSortIndicator(0, Qt::AscendingOrder); +} + +QmitkBaseTreeWidget::~QmitkBaseTreeWidget() +{ +} + +void QmitkBaseTreeWidget::clear() +{ + m_Base = NULL; + m_GroupItemMap.clear(); + + QTreeWidget::clear(); +} + +void QmitkBaseTreeWidget::OnSelectedBaseChanged(Base* base) +{ + this->clear(); + + m_Base = base; + + if (base != NULL) + this->FillTreeWidget(); +} + +void QmitkBaseTreeWidget::FillTreeWidget() +{ + const Base::VecData& dataFields = m_Base->getDataFields(); + + for (Base::VecData::const_iterator dataField = dataFields.begin(); dataField != dataFields.end(); ++dataField) + { + if (!(*dataField)->isDisplayed()) + continue; + + QString name = QString::fromStdString((*dataField)->getName()); + + if (name.isEmpty()) + continue; + + QString group = (*dataField)->getGroup(); + + if (!group.isEmpty() && !m_GroupItemMap.contains(group)) + m_GroupItemMap.insert(group, new QTreeWidgetItem(this, QStringList() << group)); + + QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() << name); + item->setToolTip(0, (*dataField)->getHelp()); + + item->setFlags(!(*dataField)->isReadOnly() + ? item->flags() | Qt::ItemIsEditable + : Qt::ItemIsSelectable); + + QString type = QString::fromStdString((*dataField)->getValueTypeString()); + + if (type == "bool") + { + item->setFlags((item->flags() & ~Qt::EditRole) | Qt::ItemIsUserCheckable); + item->setCheckState(1, (*dataField)->getValueString() == "1" ? Qt::Checked : Qt::Unchecked); + } + else + { + if (type == "double" || type == "float" || type == "int" || type == "string" || type == "unsigned int") + { + item->setData(1, Qt::DisplayRole, QVariant::fromValue(QString::fromStdString((*dataField)->getValueString()))); + } + else + { + item->setData(1, Qt::DisplayRole, QVariant::fromValue("[" + type + "]")); + } + + item->setData(1, Qt::UserRole, QVariant::fromValue(*dataField)); + } + + if (group.isEmpty()) + { + this->addTopLevelItem(item); + } + else + { + m_GroupItemMap[group]->addChild(item); + } + } + + this->setRootIsDecorated(!m_GroupItemMap.isEmpty()); + this->expandAll(); +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h new file mode 100644 index 0000000000..0aed7ef6c6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h @@ -0,0 +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 QmitkBaseTreeWidget_h +#define QmitkBaseTreeWidget_h + +#include +#include + +namespace sofa +{ + namespace core + { + namespace objectmodel + { + class Base; + } + } +} + +class QmitkSceneTreeWidget; + +class QmitkBaseTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + typedef sofa::core::objectmodel::Base Base; + + explicit QmitkBaseTreeWidget(QWidget* parent = NULL); + ~QmitkBaseTreeWidget(); + + // QTreeWidget, QTreeView, and QAbstractItemView Interfaces ///////////////// + void clear(); + ///////////////////////////////////////////////////////////////////////////// + +public slots: + void OnSelectedBaseChanged(Base* base); + +private: + void FillTreeWidget(); + + Base* m_Base; + QMap m_GroupItemMap; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp new file mode 100644 index 0000000000..7d2d6733ed --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp @@ -0,0 +1,31 @@ +/*=================================================================== + +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 "QmitkNoEditItemDelegate.h" + +QmitkNoEditItemDelegate::QmitkNoEditItemDelegate(QObject* parent) + : QStyledItemDelegate(parent) +{ +} + +QmitkNoEditItemDelegate::~QmitkNoEditItemDelegate() +{ +} + +QWidget* QmitkNoEditItemDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const +{ + return NULL; +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h new file mode 100644 index 0000000000..e1d2477073 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h @@ -0,0 +1,33 @@ +/*=================================================================== + +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 QmitkNoEditItemDelegate_h +#define QmitkNoEditItemDelegate_h + +#include + +class QmitkNoEditItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit QmitkNoEditItemDelegate(QObject* parent = NULL); + ~QmitkNoEditItemDelegate(); + + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp similarity index 78% rename from Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.cpp rename to Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp index ea3f61ed25..f6938c7ed0 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp @@ -1,381 +1,384 @@ /*=================================================================== 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 "QmitkSimulationSceneTreeWidget.h" +#include "QmitkSceneTreeWidget.h" #include #include #include #include template -static inline T* as(QmitkSimulationSceneTreeWidget::Base* base) +static inline T* as(QmitkSceneTreeWidget::Base* base) { return dynamic_cast(base); } template -static inline bool is(QmitkSimulationSceneTreeWidget::Base* base) +static inline bool is(QmitkSceneTreeWidget::Base* base) { return dynamic_cast(base) != NULL; } template -static inline bool is(QmitkSimulationSceneTreeWidget::Base* base) +static inline bool is(QmitkSceneTreeWidget::Base* base) { return is(base) || is(base); } template -static inline bool is(QmitkSimulationSceneTreeWidget::Base* base) +static inline bool is(QmitkSceneTreeWidget::Base* base) { return is(base) || is(base) || is(base); } -static inline bool isBaseInteractionForceField(QmitkSimulationSceneTreeWidget::Base* base) +static inline bool isBaseInteractionForceField(QmitkSceneTreeWidget::Base* base) { sofa::core::behavior::BaseInteractionForceField* iff = dynamic_cast(base); return iff != NULL && iff->getMechModel1() != iff->getMechModel2(); } -static inline bool isMechanicalMapping(QmitkSimulationSceneTreeWidget::Base* base) +static inline bool isMechanicalMapping(QmitkSceneTreeWidget::Base* base) { sofa::core::BaseMapping* mm = dynamic_cast(base); return mm != NULL && mm->isMechanical(); } -static QRgb GetColor(QmitkSimulationSceneTreeWidget::Base* base) +static QRgb GetColor(QmitkSceneTreeWidget::Base* base) { using namespace sofa::core; using namespace sofa::core::behavior; using namespace sofa::core::collision; using namespace sofa::core::loader; using namespace sofa::core::objectmodel; using namespace sofa::core::topology; using namespace sofa::core::visual; using namespace sofa::simulation::Colors; QString hexColor; if (is(base)) { hexColor = COLOR[NODE]; } else if (is(base)) { if (is(base)) hexColor = COLOR[sofa::simulation::Colors::CONTEXT]; else if (is(base)) hexColor = COLOR[BMODEL]; else if (is(base)) hexColor = COLOR[CMODEL]; else if (is(base)) hexColor = COLOR[MMODEL]; else if (is(base)) hexColor = COLOR[PROJECTIVECONSTRAINTSET]; else if (is(base)) hexColor = COLOR[CONSTRAINTSET]; else if (is(base)) hexColor = COLOR[MASS]; else if (isBaseInteractionForceField(base)) hexColor = COLOR[IFFIELD]; else if (is(base)) hexColor = COLOR[FFIELD]; else if (is(base)) hexColor = COLOR[SOLVER]; else if (is(base)) hexColor = COLOR[COLLISION]; else if (isMechanicalMapping(base)) hexColor = COLOR[MMAPPING]; else if (is(base)) hexColor = COLOR[MAPPING]; else if (is(base)) hexColor = COLOR[TOPOLOGY]; else if (is(base)) hexColor = COLOR[LOADER]; else if (is(base)) hexColor = COLOR[CONFIGURATIONSETTING]; else if (is(base)) hexColor = COLOR[VMODEL]; else hexColor = COLOR[OBJECT]; } else { hexColor = "#000"; } QColor color; color.setNamedColor(hexColor); return color.rgb(); } static QPixmap ReplaceColor(const QPixmap& pixmap, QRgb from, QRgb to) { QImage image = pixmap.toImage(); const int width = image.width(); const int height = image.height(); int x, y; for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { if (image.pixel(x, y) == from) image.setPixel(x, y, to); } } return QPixmap::fromImage(image); } -static inline QIcon CreateObjectIcon(QmitkSimulationSceneTreeWidget::Base* base) +static inline QIcon CreateObjectIcon(QmitkSceneTreeWidget::Base* base) { return QIcon(ReplaceColor(QPixmap(":/Simulation/Object"), 0xff00ff00, GetColor(base))); } -static inline QIcon CreateNodeIcon(QmitkSimulationSceneTreeWidget::BaseNode* node) +static inline QIcon CreateNodeIcon(QmitkSceneTreeWidget::BaseNode* node) { return QIcon(ReplaceColor(QPixmap(":/Simulation/Node"), 0xff00ff00, GetColor(node))); } -static inline QIcon CreateSlaveIcon(QmitkSimulationSceneTreeWidget::Base* base) +static inline QIcon CreateSlaveIcon(QmitkSceneTreeWidget::Base* base) { return QIcon(ReplaceColor(QPixmap(":/Simulation/Slave"), 0xff00ff00, GetColor(base))); } -static inline QString GetName(QmitkSimulationSceneTreeWidget::Base* base) +static inline QString GetName(QmitkSceneTreeWidget::Base* base) { return QString::fromStdString(base->getName()); } -static inline QString GetClassName(QmitkSimulationSceneTreeWidget::Base* base) +static inline QString GetClassName(QmitkSceneTreeWidget::Base* base) { return QString::fromStdString(base->getClassName()); } -QmitkSimulationSceneTreeWidget::QmitkSimulationSceneTreeWidget(QWidget* parent) +QmitkSceneTreeWidget::QmitkSceneTreeWidget(QWidget* parent) : QTreeWidget(parent) { } -QmitkSimulationSceneTreeWidget::~QmitkSimulationSceneTreeWidget() +QmitkSceneTreeWidget::~QmitkSceneTreeWidget() { } -void QmitkSimulationSceneTreeWidget::clear() +void QmitkSceneTreeWidget::clear() { QTreeWidgetItem* rootItem = this->topLevelItem(0); if (rootItem != NULL) this->removeChild(NULL, as(m_ItemBaseMap[rootItem])); this->ClearMaps(); QTreeWidget::clear(); } -void QmitkSimulationSceneTreeWidget::addChild(Node* parent, Node* child) +void QmitkSceneTreeWidget::addChild(Node* parent, Node* child) { assert(child != NULL && "Child node is NULL!"); assert(!m_BaseItemMap.contains(child) && "TODO: Support nodes with multiple parents!"); QTreeWidgetItem* item; if (parent == NULL) { item = new QTreeWidgetItem(QStringList() << GetName(child)); this->addTopLevelItem(item); } else { assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(child)); } item->setIcon(0, CreateNodeIcon(child)); this->InsertIntoMaps(child, item); MutationListener::addChild(parent, child); } -void QmitkSimulationSceneTreeWidget::removeChild(Node* parent, Node* child) +void QmitkSceneTreeWidget::removeChild(Node* parent, Node* child) { assert(child != NULL && "Child node is NULL!"); assert(m_BaseItemMap.contains(child) && "Child node has already been removed!"); MutationListener::removeChild(parent, child); if (parent == NULL) { delete m_BaseItemMap[child]; } else { assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); m_BaseItemMap[parent]->removeChild(m_BaseItemMap[child]); } this->RemoveFromMaps(child); } -void QmitkSimulationSceneTreeWidget::moveChild(Node* previous, Node* parent, Node* child) +void QmitkSceneTreeWidget::moveChild(Node* previous, Node* parent, Node* child) { if (previous == NULL) { this->addChild(parent, child); } else if (parent == NULL) { this->removeChild(previous, child); } else { assert(child != NULL && "Child node is NULL!"); assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!"); assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); assert(m_BaseItemMap.contains(child) && "Unknown child node!"); QTreeWidgetItem* previousItem = m_BaseItemMap[previous]; m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[child]))); } } -void QmitkSimulationSceneTreeWidget::addObject(Node* parent, BaseObject* object) +void QmitkSceneTreeWidget::addObject(Node* parent, BaseObject* object) { assert(parent != NULL && "Parent node is NULL!"); assert(object != NULL && "Object is NULL!"); assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); - assert(!m_BaseItemMap.contains(object) && "Object has already been added!"); + // assert(!m_BaseItemMap.contains(object) && "Object has already been added!"); - QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(object)); - item->setToolTip(0, GetClassName(object)); - item->setIcon(0, CreateObjectIcon(object)); - this->InsertIntoMaps(object, item); + if (!m_BaseItemMap.contains(object)) + { + QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(object)); + item->setToolTip(0, GetClassName(object)); + item->setIcon(0, CreateObjectIcon(object)); + this->InsertIntoMaps(object, item); + } MutationListener::addObject(parent, object); } -void QmitkSimulationSceneTreeWidget::removeObject(Node* parent, BaseObject* object) +void QmitkSceneTreeWidget::removeObject(Node* parent, BaseObject* object) { assert(parent != NULL && "Parent node is NULL!"); assert(object != NULL && "Object is NULL!"); assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); assert(m_BaseItemMap.contains(object) && "Object has already been removed!"); MutationListener::removeObject(parent, object); m_BaseItemMap[parent]->removeChild(m_BaseItemMap[object]); this->RemoveFromMaps(object); } -void QmitkSimulationSceneTreeWidget::moveObject(Node* previous, Node* parent, BaseObject* object) +void QmitkSceneTreeWidget::moveObject(Node* previous, Node* parent, BaseObject* object) { if (previous == NULL) { this->addObject(parent, object); } else if (parent == NULL) { this->removeObject(previous, object); } else { assert(object != NULL && "Object is NULL!"); assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!"); assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); assert(m_BaseItemMap.contains(object) && "Unknown object!"); QTreeWidgetItem* previousItem = m_BaseItemMap[previous]; m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[object]))); } } -void QmitkSimulationSceneTreeWidget::addSlave(BaseObject* master, BaseObject* slave) +void QmitkSceneTreeWidget::addSlave(BaseObject* master, BaseObject* slave) { assert(master != NULL && "Master object is NULL!"); assert(slave != NULL && "Slave object is NULL!"); assert(m_BaseItemMap.contains(master) && "Unknown master object!"); assert(!m_BaseItemMap.contains(slave) && "Slave object has already been added!"); QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[master], QStringList() << GetName(slave)); item->setToolTip(0, GetClassName(slave)); item->setIcon(0, CreateSlaveIcon(slave)); this->InsertIntoMaps(slave, item); MutationListener::addSlave(master, slave); } -void QmitkSimulationSceneTreeWidget::removeSlave(BaseObject* master, BaseObject* slave) +void QmitkSceneTreeWidget::removeSlave(BaseObject* master, BaseObject* slave) { assert(master != NULL && "Master object is NULL!"); assert(slave != NULL && "Slave object is NULL!"); assert(m_BaseItemMap.contains(master) && "Unknown master object!"); assert(m_BaseItemMap.contains(slave) && "Slave object has already been removed!"); MutationListener::removeSlave(master, slave); m_BaseItemMap[master]->removeChild(m_BaseItemMap[slave]); this->RemoveFromMaps(slave); } -void QmitkSimulationSceneTreeWidget::moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave) +void QmitkSceneTreeWidget::moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave) { if (previousMaster == NULL) { this->addSlave(master, slave); } else if (master == NULL) { this->removeSlave(previousMaster, slave); } else { assert(slave != NULL && "Slave object is NULL!"); assert(m_BaseItemMap.contains(previousMaster) && "Unknown previous master object!"); assert(m_BaseItemMap.contains(master) && "Unknown master object!"); assert(m_BaseItemMap.contains(slave) && "Unknown slave object!"); QTreeWidgetItem* previousMasterItem = m_BaseItemMap[previousMaster]; m_BaseItemMap[master]->addChild(previousMasterItem->takeChild(previousMasterItem->indexOfChild(m_BaseItemMap[slave]))); } } -QmitkSimulationSceneTreeWidget::Base* QmitkSimulationSceneTreeWidget::GetBaseFromItem(QTreeWidgetItem* item) const +QmitkSceneTreeWidget::Base* QmitkSceneTreeWidget::GetBaseFromItem(QTreeWidgetItem* item) const { return m_ItemBaseMap.contains(item) ? m_ItemBaseMap[item] : NULL; } -void QmitkSimulationSceneTreeWidget::ClearMaps() +void QmitkSceneTreeWidget::ClearMaps() { m_BaseItemMap.clear(); m_ItemBaseMap.clear(); } -void QmitkSimulationSceneTreeWidget::InsertIntoMaps(Base* base, QTreeWidgetItem* item) +void QmitkSceneTreeWidget::InsertIntoMaps(Base* base, QTreeWidgetItem* item) { m_BaseItemMap.insert(base, item); m_ItemBaseMap.insert(item, base); } -void QmitkSimulationSceneTreeWidget::RemoveFromMaps(Base* base) +void QmitkSceneTreeWidget::RemoveFromMaps(Base* base) { m_ItemBaseMap.remove(m_BaseItemMap[base]); m_BaseItemMap.remove(base); } diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h similarity index 84% rename from Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.h rename to Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h index f870f2f4d2..ae104ced87 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h @@ -1,82 +1,82 @@ /*=================================================================== 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 QmitkSimulationSceneTreeWidget_h -#define QmitkSimulationSceneTreeWidget_h +#ifndef QmitkSceneTreeWidget_h +#define QmitkSceneTreeWidget_h #include #include #include namespace sofa { namespace core { namespace objectmodel { class Base; class BaseNode; class BaseObject; } } namespace simulation { class Node; } } -class QmitkSimulationSceneTreeWidget : public QTreeWidget, public sofa::simulation::MutationListener +class QmitkSceneTreeWidget : public QTreeWidget, public sofa::simulation::MutationListener { Q_OBJECT public: typedef sofa::core::objectmodel::Base Base; typedef sofa::core::objectmodel::BaseNode BaseNode; typedef sofa::core::objectmodel::BaseObject BaseObject; typedef sofa::simulation::Node Node; - explicit QmitkSimulationSceneTreeWidget(QWidget* parent = NULL); - ~QmitkSimulationSceneTreeWidget(); + explicit QmitkSceneTreeWidget(QWidget* parent = NULL); + ~QmitkSceneTreeWidget(); Base* GetBaseFromItem(QTreeWidgetItem* item) const; - // QTreeWidget, QTreeView, and QAbstractItemView Interfaces ////////////////////// + // QTreeWidget, QTreeView, and QAbstractItemView Interfaces ///////////////// void clear(); - ////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// - // MutationListener Interface //////////////////////////////////////////////////// + // MutationListener Interface /////////////////////////////////////////////// void addChild(Node* parent, Node* child); void removeChild(Node* parent, Node* child); void moveChild(Node* previous, Node* parent, Node* child); void addObject(Node* parent, BaseObject* object); void removeObject(Node* parent, BaseObject* object); void moveObject(Node* previous, Node* parent, BaseObject* object); void addSlave(BaseObject* master, BaseObject* slave); void removeSlave(BaseObject* master, BaseObject* slave); void moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave); - ////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// private: void ClearMaps(); void InsertIntoMaps(Base* base, QTreeWidgetItem* item); void RemoveFromMaps(Base* base); QMap m_BaseItemMap; QMap m_ItemBaseMap; }; #endif 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 d4a0ce1761..07b79e9e8b 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp @@ -1,240 +1,301 @@ /*=================================================================== 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 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; +} + QmitkSimulationView::QmitkSimulationView() : m_SimulationService(GetService()), + m_Interactor(CreateSimulationInteractor()), 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_Controls.setupUi(parent); m_Controls.simulationComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.simulationComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); connect(m_Controls.simulationComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSimulationChanged(const mitk::DataNode*))); connect(m_Controls.animateButton, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool))); connect(m_Controls.stepButton, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked())); connect(m_Controls.resetButton, SIGNAL(clicked()), this, SLOT(OnResetButtonClicked())); connect(m_Controls.dtSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDtChanged(double))); + connect(m_Controls.sceneTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(OnSelectedBaseChanged())); + connect(m_Controls.pushButton, SIGNAL(clicked()), this, SLOT(OnButtonClicked())); if (m_Controls.simulationComboBox->GetSelectedNode().IsNotNull()) { this->OnSelectedSimulationChanged(m_Controls.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_Controls.stepButton->setEnabled(false); } else if (m_Selection.IsNotNull()) { mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); scheduler->RemoveProcess(simulation); simulation->SetAnimationFlag(false); m_Controls.stepButton->setEnabled(true); } if (!scheduler->IsEmpty()) { if (!m_Timer.isActive()) m_Timer.start(0); } else { m_Timer.stop(); } } 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_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); simulation->Reset(); this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnSelectedSimulationChanged(const mitk::DataNode* node) { if (node != NULL) { m_Selection = m_Controls.simulationComboBox->GetSelectedNode(); mitk::Simulation* simulation = static_cast(m_Selection->GetData()); m_Controls.animateButton->setChecked(simulation->GetAnimationFlag()); m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); this->SetSimulationControlsEnabled(true); } else { m_Selection = NULL; this->SetSimulationControlsEnabled(false); m_Controls.animateButton->setChecked(false); m_Controls.dtSpinBox->setValue(0.0); } - this->ResetSimulationSceneTreeWidget(); + m_Interactor->SetDataNode(m_Selection); + + this->ResetSceneTreeWidget(); +} + +void QmitkSimulationView::OnSelectedBaseChanged() +{ + QList selectedBaseItems = m_Controls.sceneTreeWidget->selectedItems(); + + m_Controls.baseTreeWidget->OnSelectedBaseChanged(!selectedBaseItems.isEmpty() + ? m_Controls.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_3DWINDOWS); } 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_3DWINDOWS); } 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::ResetSimulationSceneTreeWidget() +void QmitkSimulationView::ResetSceneTreeWidget() { - m_Controls.simulationSceneTreeWidget->clear(); + m_Controls.sceneTreeWidget->clear(); if (m_Selection.IsNull()) return; mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); - m_Controls.simulationSceneTreeWidget->addChild(NULL, simulation->GetRootNode().get()); - m_Controls.simulationSceneTreeWidget->expandItem(m_Controls.simulationSceneTreeWidget->topLevelItem(0)); + m_Controls.sceneTreeWidget->addChild(NULL, simulation->GetRootNode().get()); + m_Controls.sceneTreeWidget->expandItem(m_Controls.sceneTreeWidget->topLevelItem(0)); } void QmitkSimulationView::SetSimulationControlsEnabled(bool enabled) { m_Controls.animateButton->setEnabled(enabled); m_Controls.stepButton->setEnabled(enabled); m_Controls.resetButton->setEnabled(enabled); m_Controls.dtLabel->setEnabled(enabled); m_Controls.dtSpinBox->setEnabled(enabled); } void QmitkSimulationView::SetFocus() { m_Controls.animateButton->setFocus(); } + +void QmitkSimulationView::OnButtonClicked() +{ +} + +/*#include +#include +#include +#include +#include + +void QmitkSimulationView::OnButtonClicked() +{ + vtkRenderWindow* renderWindow = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetVtkRenderWindow(); + + vtkSmartPointer windowToImageFilter = vtkSmartPointer::New(); + + windowToImageFilter->SetInput(renderWindow); + windowToImageFilter->SetInputBufferTypeToZBuffer(); + + vtkSmartPointer imageShiftScaleFilter = vtkSmartPointer::New(); + + imageShiftScaleFilter->SetInputConnection(windowToImageFilter->GetOutputPort()); + imageShiftScaleFilter->SetOutputScalarTypeToUnsignedChar(); + imageShiftScaleFilter->SetShift(0); + imageShiftScaleFilter->SetScale(-255); + + vtkSmartPointer pngWriter = vtkSmartPointer::New(); + + pngWriter->SetInputConnection(imageShiftScaleFilter->GetOutputPort()); + pngWriter->SetFileName("C:\\Users\\Stefan\\Desktop\\DepthBuffer.png"); + pngWriter->Write(); +}*/ 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 f96483c7c2..3eb8d7c803 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h @@ -1,64 +1,68 @@ /*=================================================================== 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 #include namespace mitk { class ISimulationService; } class QmitkSimulationView : public QmitkAbstractView { Q_OBJECT public: QmitkSimulationView(); ~QmitkSimulationView(); void CreateQtPartControl(QWidget* parent); void SetFocus(); private slots: void OnAnimateButtonToggled(bool toggled); void OnDtChanged(double dt); void OnResetButtonClicked(); void OnSelectedSimulationChanged(const mitk::DataNode* node); + void OnSelectedBaseChanged(); void OnStep(bool renderWindowUpdate); void OnStepButtonClicked(); void OnTimeout(); + void OnButtonClicked(); private: void OnNodeRemovedFromDataStorage(const mitk::DataNode* node); - void ResetSimulationSceneTreeWidget(); + void ResetSceneTreeWidget(); void SetSimulationControlsEnabled(bool enabled); static const int MSecsPerFrame = 17; Ui::QmitkSimulationViewControls m_Controls; mitk::ISimulationService* m_SimulationService; mitk::DataNode::Pointer m_Selection; + mitk::SimulationInteractor::Pointer m_Interactor; QTimer m_Timer; QTime m_NextRenderWindowUpdate; }; #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 f17287a356..0ece535e84 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui @@ -1,151 +1,186 @@ QmitkSimulationViewControls true 0 0 - 274 + 248 751 Simulation 0 0 0 0 Animate true false 0 0 Step 0 0 Reset 0 0 dt 0 0 s 3 0.010000000000000 - - - QAbstractItemView::NoEditTriggers + + + Qt::Vertical - - true - - - false - - - 1 - - - false - - - - Name + + + QAbstractItemView::NoEditTriggers + + + true + + + false - + + 1 + + + false + + + + Name + + + + + + true + + + 120 + + + + Property + + + + + Value + + + + + + + + + + QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
- QmitkSimulationSceneTreeWidget + QmitkSceneTreeWidget + QTreeWidget +
QmitkSceneTreeWidget.h
+
+ + QmitkBaseTreeWidget QTreeWidget -
QmitkSimulationSceneTreeWidget.h
+
QmitkBaseTreeWidget.h