diff --git a/Modules/Simulation/mitkSimulation.cpp b/Modules/Simulation/mitkSimulation.cpp index f77f00cc96..1cc4e05103 100644 --- a/Modules/Simulation/mitkSimulation.cpp +++ b/Modules/Simulation/mitkSimulation.cpp @@ -1,255 +1,243 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimulation.h" #include "mitkSimulationPropAssemblyVisitor.h" #include #include #include -#include -#include #include #include #include #include #include #include #include #include #include const float mitk::Simulation::ScaleFactor = 1.0f; // 1000.0f -static sofa::simulation::Simulation::SPtr CreateSimulation(mitk::Simulation::SimulationType type = mitk::Simulation::Tree) +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); - switch (type) - { - case mitk::Simulation::DAG: - return sofa::core::objectmodel::New(); - - case mitk::Simulation::Bgl: - return sofa::core::objectmodel::New(); - - default: - return sofa::core::objectmodel::New(); - } + return sofa::core::objectmodel::New(); } void mitk::Simulation::SetActiveSimulation(mitk::Simulation* simulation) { if (simulation == NULL) { sofa::simulation::setSimulation(NULL); sofa::core::visual::VisualParams::defaultInstance()->drawTool() = NULL; } else { sofa::simulation::Simulation* sofaSimulation = simulation->m_Simulation.get(); if (sofa::simulation::getSimulation() != sofaSimulation) { sofa::simulation::setSimulation(sofaSimulation); sofa::core::visual::VisualParams::defaultInstance()->drawTool() = &simulation->m_DrawTool; } } } mitk::Simulation::Simulation() : m_Simulation(CreateSimulation()), m_DefaultDT(0.0) { } mitk::Simulation::~Simulation() { if (m_Simulation != NULL) { if (m_RootNode != NULL) m_Simulation->unload(m_RootNode); if (sofa::simulation::getSimulation() == m_Simulation.get()) SetActiveSimulation(NULL); } } bool mitk::Simulation::AppendSnapshot(mitk::Surface::Pointer surface) const { if (surface.IsNotNull()) { vtkSmartPointer snapshot = this->CreateSnapshot(); if (snapshot != NULL) { unsigned int timeStep = surface->GetSizeOfPolyDataSeries(); if (timeStep != 0 && surface->GetVtkPolyData(timeStep - 1) == NULL) --timeStep; surface->SetVtkPolyData(snapshot, timeStep); return true; } } return false; } vtkSmartPointer mitk::Simulation::CreateSnapshot() const { if (m_RootNode == NULL) return NULL; vtkSmartPointer propAssembly = vtkSmartPointer::New(); SimulationPropAssemblyVisitor propAssemblyVisitor(propAssembly); m_RootNode->executeVisitor(&propAssemblyVisitor); vtkSmartPointer appendFilter = vtkSmartPointer::New(); vtkPropCollection* propCollection = propAssembly->GetParts(); vtkProp* prop = NULL; if (propCollection->GetNumberOfItems() == 0) return NULL; for (propCollection->InitTraversal(); (prop = propCollection->GetNextProp()) != NULL; ) { vtkActor* actor = vtkActor::SafeDownCast(prop); vtkPolyData* polyData = vtkPolyData::SafeDownCast(actor->GetMapper()->GetInput()); appendFilter->AddInput(polyData); } vtkSmartPointer scaleTransform = vtkSmartPointer::New(); scaleTransform->Scale(ScaleFactor, ScaleFactor, ScaleFactor); vtkSmartPointer transformFilter = vtkSmartPointer::New(); transformFilter->SetInputConnection(appendFilter->GetOutputPort()); transformFilter->SetTransform(scaleTransform); transformFilter->Update(); vtkSmartPointer snapshot = vtkSmartPointer::New(); snapshot->ShallowCopy(transformFilter->GetOutputDataObject(0)); return snapshot; } double mitk::Simulation::GetDefaultDT() const { return m_DefaultDT; } mitk::SimulationDrawTool* mitk::Simulation::GetDrawTool() { return &m_DrawTool; } sofa::simulation::Node::SPtr mitk::Simulation::GetRootNode() const { return m_RootNode; } sofa::simulation::Simulation::SPtr mitk::Simulation::GetSimulation() const { return m_Simulation; } bool mitk::Simulation::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } void mitk::Simulation::SetAsActiveSimulation() { SetActiveSimulation(this); } void mitk::Simulation::SetDefaultDT(double dt) { m_DefaultDT = std::max(0.0, dt); } void mitk::Simulation::SetRequestedRegion(const itk::DataObject*) { } void mitk::Simulation::SetRequestedRegionToLargestPossibleRegion() { } void mitk::Simulation::SetRootNode(sofa::simulation::Node* rootNode) { m_RootNode.reset(rootNode); } mitk::Surface::Pointer mitk::Simulation::TakeSnapshot() const { vtkSmartPointer snapshot = this->CreateSnapshot(); if (snapshot == NULL) return NULL; Surface::Pointer surface = Surface::New(); surface->SetVtkPolyData(snapshot); return surface; } void mitk::Simulation::UpdateOutputInformation() { if (this->GetSource().IsNotNull()) this->GetSource()->UpdateOutputInformation(); if (m_RootNode != NULL) { const sofa::defaulttype::BoundingBox& boundingBox = m_RootNode->f_bbox.getValue(); const sofa::defaulttype::Vector3& min = boundingBox.minBBox(); const sofa::defaulttype::Vector3& max = boundingBox.maxBBox(); mitk::Geometry3D::BoundsArrayType bounds; bounds[0] = static_cast(min.x() * ScaleFactor); bounds[1] = static_cast(max.x() * ScaleFactor); bounds[2] = static_cast(min.y() * ScaleFactor); bounds[3] = static_cast(max.y() * ScaleFactor); bounds[4] = static_cast(min.z() * ScaleFactor); bounds[5] = static_cast(max.z() * ScaleFactor); if(this->GetGeometry() != NULL) { this->GetGeometry()->SetBounds(bounds); } else { Geometry3D::Pointer geometry = Geometry3D::New(); geometry->SetBounds(bounds); this->SetGeometry(geometry); } } this->GetTimeSlicedGeometry()->UpdateInformation(); } bool mitk::Simulation::VerifyRequestedRegion() { return true; } diff --git a/Modules/Simulation/mitkSimulation.h b/Modules/Simulation/mitkSimulation.h index 5857ffed71..9d8d0ffb07 100644 --- a/Modules/Simulation/mitkSimulation.h +++ b/Modules/Simulation/mitkSimulation.h @@ -1,168 +1,161 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkSimulation_h #define mitkSimulation_h #include "mitkSimulationDrawTool.h" #include #include #include #include #include namespace mitk { /** \brief Encapsulates a SOFA simulation. * * Call GetSimulation() to access the initially default constructed SOFA simulation. * Directly after loading a scene into the SOFA simulation you must set its root node by calling SetRootNode(). * You should set the simulation scene's default time step as well by calling SetDefaultDT(). * Make sure to manually initilalize the SOFA simulation. * * SOFA can conceptionally handle only one simulation at a time, however, MITK %Simulation allows to load several simulation scenes in parallel. - * Therfore it is necessary and important to set a simulation as active simulation when using it. + * Therefore it is necessary to set a simulation as active simulation when using it. * You can do this either by calling SetAsActiveSimulation() or by calling the static SetActiveSimulation() method. * * You can take snapshots of simulations represented as 3D surfaces by calling TakeSnapshot() or easily record simulations as 3D+t surfaces by calling AppendSnapshot(). */ class Simulation_EXPORT Simulation : public BaseData { public: - enum SimulationType - { - Tree, - DAG, - Bgl - }; - mitkClassMacro(Simulation, BaseData); itkNewMacro(Self); /** \brief %Set the active simulation. * * \param[in] simulation The new active simulation or NULL. * \sa SetAsActiveSimulation() */ static void SetActiveSimulation(Self* simulation); /** \brief Scale factor by which all objects in a simulation scene are scaled for visualization. */ static const float ScaleFactor; /** \brief Append snapshot of scene at current simulation time to given Surface. * * \param[in] surface Surface to which the current scene is appended as 3D surface. * \return Returns true if a snapshot was successfully appended to the surface. * \sa TakeSnapshot() */ bool AppendSnapshot(Surface::Pointer surface) const; /** \brief Get default time step of simulation scene. * * You need to manually set the default time step by calling SetDefaultDT(). * * \return The default time step of the simulation scene if available or 0.0 otherwise. */ double GetDefaultDT() const; /** \brief Get simulation draw tool. * * Usually called only by the corresponding mapper or to reset the draw tool manually. * * \return The simulation draw tool. */ SimulationDrawTool* GetDrawTool(); /** \brief Get root node of simulation scene. * * You must manually set the root node by calling SetRootNode() first. * This is usually done directly after setting/loading a simulation scene. * * \return The root node of the encapsulated SOFA simulation scene. */ sofa::simulation::Node::SPtr GetRootNode() const; /** \brief Get SOFA simulation. * * The encapsulated SOFA simulation is default constructed during construction. * Use this method to gain access to it or to initially load a scene into the simulation. * Make sure to also call SetRootNode() and SetDefaultDT() in the latter case. * * \return The encapsulated SOFA simulation. */ sofa::simulation::Simulation::SPtr GetSimulation() const; bool RequestedRegionIsOutsideOfTheBufferedRegion(); /** \brief %Set this simulation as active simulation. * * You must set a simulation as active simulation prior to use it. * * \sa SetActiveSimulation() */ void SetAsActiveSimulation(); /** \brief %Set default simulation scene time step. * * You should call this method after you loaded a scene into the encapsulated SOFA simulation and set the root node. * * \param[in] dt Default time step of encapsulated simulation scene. * \sa GetSimulation(), SetRootNode() */ void SetDefaultDT(double dt); void SetRequestedRegion(const itk::DataObject* data); void SetRequestedRegionToLargestPossibleRegion(); /** \brief %Set the simulation scene root node of the encapsulated simulation. * * This is usually the first method you call after you accessed the encapsulated simulation by calling GetSimulation() to set or load the simulation scene. * * \param[in] rootNode Root Node of the simulation scene corresponding to the encapsulated SOFA simulation. */ void SetRootNode(sofa::simulation::Node* rootNode); /** \brief Take a snapshot of the encapsulated simulation scene at current simulation time. * * Snapshots cannot be created if the simulation scene contains no visual models or only hidden visual models. * * \return Snapshot represented as 3D surface or NULL. */ Surface::Pointer TakeSnapshot() const; void UpdateOutputInformation(); bool VerifyRequestedRegion(); private: Simulation(); ~Simulation(); Simulation(Self&); Self& operator=(const Self&); vtkSmartPointer CreateSnapshot() const; sofa::simulation::Simulation::SPtr m_Simulation; sofa::simulation::Node::SPtr m_RootNode; SimulationDrawTool m_DrawTool; double m_DefaultDT; }; } #endif diff --git a/Modules/Simulation/mitkSimulationPropAssemblyVisitor.h b/Modules/Simulation/mitkSimulationPropAssemblyVisitor.h index 5bb8be8294..5183584802 100644 --- a/Modules/Simulation/mitkSimulationPropAssemblyVisitor.h +++ b/Modules/Simulation/mitkSimulationPropAssemblyVisitor.h @@ -1,43 +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 mitkSimulationPropAssemblyVisitor_h #define mitkSimulationPropAssemblyVisitor_h #include #include class vtkPropAssembly; namespace mitk { + /** \brief Collects all VTK actors of all simulation models (mitk::SimulationModel) present in a simulation scene. + */ class Simulation_EXPORT SimulationPropAssemblyVisitor : public sofa::simulation::Visitor { public: + /** \brief Sole public constructor. + * + * \param[in] propAssembly VTK prop assembly to which all found VTK actors will be appended as parts. + */ explicit SimulationPropAssemblyVisitor(vtkPropAssembly* propAssembly, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ~SimulationPropAssemblyVisitor(); Result processNodeTopDown(sofa::simulation::Node* node); private: SimulationPropAssemblyVisitor(const SimulationPropAssemblyVisitor&); SimulationPropAssemblyVisitor& operator=(const SimulationPropAssemblyVisitor&); vtkPropAssembly* m_PropAssembly; }; } #endif diff --git a/Modules/Simulation/mitkSimulationTemplate.h b/Modules/Simulation/mitkSimulationTemplate.h index 3b40c5f803..bf3e461782 100644 --- a/Modules/Simulation/mitkSimulationTemplate.h +++ b/Modules/Simulation/mitkSimulationTemplate.h @@ -1,57 +1,102 @@ /*=================================================================== 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 mitkSimulationTemplate_h #define mitkSimulationTemplate_h #include #include #include #include #include #include +#include namespace mitk { + /** \brief %Simulation templates are extended simulation scenes which can contain variables. + * + * These variables are mapped to properties (mitk::BaseProperty) to be easily adjustable. + * A simulation template is an intermediate format and cannot be loaded by SOFA as simulation scene. + * However, a simulation scene based on a simulation template can be created easily. + * + * For information on the syntax of simulation templates, see \ref org_mitk_gui_qt_simulationSimulationTemplates. + * + * Call Parse() to initialize the class by parsing a simulation scene template. + * Parsed templates are represented by properties which you must set manually for the corresponding data node (mitk::DataNode) by calling SetProperties(). + * To create a simulation scene based on the simulation template call CreateSimulation(). + */ class Simulation_EXPORT SimulationTemplate : public BaseData { public: mitkClassMacro(SimulationTemplate, BaseData); itkNewMacro(Self); + /** \brief Create simulation scene based on parsed simulation scene template. + * + * You must parse a simulation scene template before calling this method. + * In case of error this method writes a message to MITK_DEBUG and returns an empty string. + * + * \return %Simulation scene as string or empty string in case of error. + * \sa Parse() + */ std::string CreateSimulation() const; + + /** \brief Initialize class by parsing a simulation scene template. + * + * For more information on the syntax of simulation templates, see \ref org_mitk_gui_qt_simulationSimulationTemplates. + * An mitk::Exception with a meaningful description is thrown for any possible error related to parsing. + * + * \param[in] contents %Simulation scene template. + * \exception mitk::Exception An error occurred during parsing. + * \return False if class is already initialized. + */ bool Parse(const std::string& contents); + bool RequestedRegionIsOutsideOfTheBufferedRegion(); + + /** \brief Add properties which represent simulation template variables to given data node. + * + * You must parse a simulation scene template before calling this method. + * In case of error this method writes a message to MITK_DEBUG and returns false. + * + * \return False if class is not initialized, data node is null, or data node doesn't own this simulatiom template. + * \sa Parse() + */ bool SetProperties(DataNode::Pointer dataNode) const; + void SetRequestedRegion(const itk::DataObject* data); + void SetRequestedRegionToLargestPossibleRegion(); + void UpdateOutputInformation(); + bool VerifyRequestedRegion(); private: SimulationTemplate(); ~SimulationTemplate(); SimulationTemplate(Self&); Self& operator=(const Self&); bool m_IsInitialized; std::vector m_StaticContents; std::vector > m_VariableContents; }; } #endif