diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/FirstSteps/NewDataType.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/FirstSteps/NewDataType.dox index e30e8f3e7d..6bfdac56cf 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/FirstSteps/NewDataType.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/FirstSteps/NewDataType.dox @@ -1,52 +1,52 @@ /** \page NewDataTypePage How to create a new custom data type \tableofcontents \section NewDataTypePagePrerequisites Prerequisites and further reading We will use some concepts during this tutorial which we assume you are aware of, as well as taking advantage of infrastructure which needs to be set up. The following is a list of prerequisites which should be present to effectively use this tutorial. Some concepts will only be briefly touched upon in this tutorial, for a more concise presentation of these concepts please refer to the following further reading. \section NewDataTypePageCreatingANewDataType Creating a new data type A new data type needs to derive from mitk::BaseData in order to be handled by the mitk::DataStorage via mitk::DataNode. An example of a very simple data type is provided in the example module. This type encapsulates a string. \include mitkExampleDataStructure.h Overloading mitk::Equal to work with your data type will enable you to write simpler, standardized tests. \section NewDataTypePageAddingReadersAndWriters Adding readers and writers In order for your data type to be read from and written to disk, you need to implement readers and writers. In order for your readers/writers to be registered and available even if your module has not been loaded (usually after just starting the application), it is advisable to implement them separately in a autoload module. The default location for this is "YourModuleName/autoload/IO". More information regarding implementing IO and MimeTypes is available at \ref ReaderWriterPage. An example MimeType is implemented for the example data structure. \include mitkExampleIOMimeTypes.h \note{ You do not need to create your own class to manage your MimeTypes. Instead they can be defined within the Reader/Writer. } -\section NewDataTypePageAddingReadersAndWriters Adding a mapper +\section NewDataTypePageAddingMappers Adding a mapper If your data type needs a special way to render its data for the user, you need to implement a new mapper. More information can be found at \ref QVTKRendering.

If you meet any difficulties during this How-To, don't hesitate to ask on the MITK mailing list mitk-users@lists.sourceforge.net! People there are kind and will try to help you. If you notice that there is an error, or that the code has changed so the way shown here is no longer correct, please open a bug report a http://bugs.mitk.org .

*/ diff --git a/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/GeometryMigration.dox b/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/GeometryMigration.dox index bd9146de8b..b16c6ce5f9 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/GeometryMigration.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/GeometryMigration.dox @@ -1,148 +1,148 @@ /** \page GeometryMigration Migration Guide to new Geometry Concept \tableofcontents -\section GeneralChanges General Changes +\section GeometryGeneralChanges General Changes \subsection OldClasses Old class diagram Until now, all geometry classes inherited from Geometry3D. This inheritance didn't make sense. For example, there is no reason, why we need a Geometry2D and a PlaneGeometry as both describe the same thing. Also, why does a two-dimensional class need to inherit from a three-dimensional class? \imageMacro{oldClasses.png,"Old class diagram.",12.70} \subsection NewClasses New class diagram Therefore, we inserted an abstract BaseGeometry class, from which all other geometry classes should inherit. The classes Geometry2D and PlaneGeometry are combined in the new PlaneGeometry class. Also, the LandmarkBasedCurvedGeometry is included in LandmarkProjectorBasedCurvedGeometry. \imageMacro{currentClasses.png,"New class diagram.",15.32} -\section Howto How to adapt your code +\section GeometryHowto How to adapt your code Most content of the BaseGeometry class consists of functions and variables of the former Geometry3D. Here are some guidelines, how to change your code to the new geometry scheme. \subsection privateVariables Variables are private. All variables of BaseGeometry (former in Geometry3D) are private now. Hence, use the Set and Get methods to access the variables. \subsection geo2d Always use PlaneGeometry instead of Geometry2D. The class Geometry2D does not exist any more. In most cases, you can just replace the Geometry2D by PlaneGeometry. Please pay attention if you use the function "IsAbove(Point3D point)". There were two different implementations in Geometry2D and PlaneGeometry. The default behavior is implemented according to the former function of PlaneGeometry. If you want to use the implementation of the former Geometry2D, please call "IsAbove(point,true)".\n Here are the different implementations: \code bool PlaneGeometry::IsAbove( const Point3D &pt3d_mm , bool considerBoundingBox = false) const { if(considerBoundingBox) { //This is the implementation of former Geometry2D Point3D pt3d_units; BaseGeometry::WorldToIndex(pt3d_mm, pt3d_units); return (pt3d_units[2] > this->GetBoundingBox()->GetBounds()[4]); } else { //This is the implementation of former PlaneGeometry and the default behavior. return SignedDistanceFromPlane(pt3d_mm) > 0; } } \endcode \subsection geo2ddata Rename Geometry2D... classes. All ...Geometry2D... classes and functions are renamed to ...PlaneGeometry... . The new names are for example PlaneGeometryData instead of Geometry2DData. An example for functions is GetGeometry2D, which is now called GetPlaneGeometry. A simple search & replace of Geometry2D should work in most cases.\n\n List of all names changed (excluding variables): \subsection geo3d In some cases, use BaseGeometry instead of Geometry3D. As there are no classes any more, which inherit from Geometry3D, you cannot insert other classes (i.e. SlicedGeometry3D) for a Geometry3D. If you have trouble, e.g. calling a function which expects a Geometry3D parameter, try one of the following steps: \subsection clone Clones of BaseGeometry. The BaseGeometry class is an abstract class. You cannot create an object of BaseGeometry. If you need a clone of BaseGeometry to call a function, use the following code: \code itk::LightObject::Pointer lopointer = geometry.Clone(); Initialize(dynamic_cast(lopointer.GetPointer())); \endcode instead of: \code Geometry3D::Pointer geometry3D = geometry.Clone(); Initialize(geometry3D.GetPointer()); \endcode \subsection object Create an object of BaseGeometry. Again, you cannot create an object of BaseGeometry. However, there are cases, where we need a flexible Variable which can contain objects of any other geometry class later on. This might be the case for member variables, etc. In this case, try: \code mitk::Geometry3D::Pointer geo3D = Geometry3D::New(); mitk::BaseGeometry::Pointer m_geometry = dynamic_cast(geo3D.GetPointer()); \endcode instead of \code mitk::Geometry3D::Pointer m_geometry = mitk::Geometry3D::New(); \endcode \subsection virtual Virtual functions. To ensure a reliable behavior of functions, most functions are not virtual any more. However, if a function needs a different behavior in subclasses, there are virtual Pre- and Post- functions, which allow for additional code. The pre-functions are called at the very beginning of a function, the post-functions at the end. In the BaseGeometry, all pre- and post-functions are empty.\n An example:\n The function "SetIndexToWorldTransform" is not virtual any more. For a PlaneGeometry, we need a perpendicular normal before the transformation is set. Afterwards, we need to apply the transformation to the scaling factors.\n Code of the BaseGeometry class: \code void SetIndexToWorldTransform(mitk::AffineTransform3D* transform) { PreSetIndexToWorldTransform(transform); if(m_IndexToWorldTransform.GetPointer() != transform) { m_IndexToWorldTransform = transform; CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin); TransferItkToVtkTransform(); Modified(); } PostSetIndexToWorldTransform(transform); } virtual void PreSetIndexToWorldTransform(mitk::AffineTransform3D* transform){}; virtual void PostSetIndexToWorldTransform(mitk::AffineTransform3D* transform){}; \endcode Code of PlaneGeometry: \code void PlaneGeometry::PreSetIndexToWorldTransform(mitk::AffineTransform3D *transform) { EnsurePerpendicularNormal(transform); } void PlaneGeometry::PostSetIndexToWorldTransform(mitk::AffineTransform3D* transform) { m_ScaleFactorMMPerUnitX=GetExtentInMM(0)/GetExtent(0); m_ScaleFactorMMPerUnitY=GetExtentInMM(1)/GetExtent(1); } \endcode \subsection parametric Parametric functions are not part of BaseGeometry. In Geometry3D, there were several "Parametric" functions (e.g. GetParametricExtent, GetParametricTransform), which only called the non-parametric function (e.g. GetExtent, GetIndexToWorldTransform). These functions are removed, please use the non-parametric implementation instead. However, in the AbstractTransformGeometry (and all subclasses), these parametric functions behave different and are still available. \subsection floatspacing There is no float spacing any more. Use GetSpacing instead of GetFloatSpacing. \subsection LandmarkBased Always use LandmarkProjectorBasedCurvedGeometry instead of LandmarkBasedCurvedGeometry. The class LandmarkBasedCurvedGeometry does not exist any more. Please use LandmarkProjectorBasedCurvedGeometry. */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/InteractionMigration.dox b/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/InteractionMigration.dox index 59911213a6..a8b2240d01 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/InteractionMigration.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/InteractionMigration.dox @@ -1,154 +1,154 @@ /** \page InteractionMigration Migration Guide to new Interaction Concept \tableofcontents -\section GeneralChanges General Changes +\section InteractionGeneralChanges General Changes \subsection StatemachineDefinitions Previously the statemachine pattern along with the event description has been stored in a single file (StateMachine.xml). Now the pattern and the events are separated from each other. The statemachine pattern describes the workflow and the configuration file describes which specific event triggers an action in the workflow. Every pattern is now put into a single file (for inclusion refer to \ref IncludeFiles ). The pattern description has to be completely rewritten, but is pretty straight forward based on the old one, how to do this is explained here \ref HowToStateMachine . Here an example is shown for a simple state containing a transition and a parameter. \code \endcode Example snippet (old) \code \endcode Example snippet (new) Changes: Event_class describes the class of the event (see \ref EventClassSection ) - the event_variant provides a name that is used in the configuration file to give an explicit description of the event (or the globalConfig.xml is loaded as configuration file and standard values are used). Configuration files for state machines are described here: \ref ConfigFileDescriptionSection . \subsection InteractorStruture Structure of an Interactor Actions are now directly connected to functions in the DataInteractors, so the classic switch statement becomes obsolete: \code bool mitk::SomeInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent) { switch (action->GetActionId()) { case Action1: ... case Action2: ... } } \endcode changes to \code void mitk::ExampleInteractor::ConnectActionsAndFunctions() { CONNECT_FUNCTION("stringOfActionFromXmlFile", Action1); CONNECT_FUNCTION("stringOfActionFromXmlFile2", Action2); ... } void Action1(StateMachineAction* , InteractionEvent*) { ... } ... \endcode where each action is implemented as a function. See \ref HowToDataInteractor . \subsection GuardStates Guard States / Conditions Formerly there where so called guard states, which cause a transition only if certain conditions are met. These states have been removed, as a replacement serve the InternalEvents which can be triggered from within a data interactor. An example showing how to use them is given in \ref ExampleInternalEvent . In most cases, guard states can be eliminated by using transition conditions. \subsection IncludeFiles Register statemachine patterns and configuration w/o the build system There are different ways to load a statemachine pattern or configuration objects from files. If you are working in a module you can use the resources to easily load patterns and configurations. To use this place your XML file in the 'Resources/Interactions' folder of the respective module, and add the file path to the corresponding files.cmake in the resource section like this: \code set(RESOURCE_FILES Interactions/dummyStatemachine.xml ) \endcode Loading the statemachine pattern can then be done by simply calling \code #include "mitkModule.h" #include Module* module = GetModuleContext()->GetModule(); mitk::PointSetDataInteractor::m_CurrentInteractor = mitk::PointSetDataInteractor::New(); m_CurrentInteractor->LoadStateMachine("dummyStatemachine.xml", module); \endcode here module is optional, if none is provided the core module is assumed. The third possibility is to build up a configuration by vector of mitk::PropertyLists, where each item describes an event configuration. In the following example a configuration is build which defines two event variants using basic properties, for a full list of usable properties see mitkInteractionEventConst.h \code #include "mitkPropertyList.h" #include "mitkEventConfig.h" // First event mitk::PropertyList::Pointer propertyList1 = mitk::PropertyList::New(); // Setting the EventClass property to 'MousePressEvent' propertyList1->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventClass.c_str(), "MousePressEvent"); // Setting the Event variant value to 'MousePressEventVariantÄ propertyList1->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventVariant.c_str(), "MousePressEventVariant"); // set control and alt buttons as modifiers propertyList1->SetStringProperty("Modifiers","CTRL,ALT"); // Second event mitk::PropertyList::Pointer propertyList2 = mitk::PropertyList::New(); propertyList2->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventClass.c_str(), "MouseReleaseEvent"); propertyList2->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventVariant.c_str(), "MouseReleaseEventVariant"); propertyList2->SetStringProperty("Modifiers","SHIFT"); // putting both descriptions in a vector std::vector* configDescription = new std::vector(); configDescription->push_back(propertyList1); configDescription->push_back(propertyList2); // create the config object mitk::EventConfig newConfig(configDescription); \endcode */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/OverlayMigration.dox b/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/OverlayMigration.dox index 2f3abc81bd..cd0b5df391 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/OverlayMigration.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Toolkit/ModuleManuals/OverlayMigration.dox @@ -1,37 +1,37 @@ /** \page OverlayMigration Migration Guide from Overlays to the new Annotation concept \tableofcontents -\section Howto How to adapt your code +\section OverlayHowto How to adapt your code All classes have been renamed from "Overlay" to "Annotation", e.g. the mitk::TextOverlay2D is now mitk::TextAnnotation2D. Most of the interface of mitk::Overlay remains unchanged in mitk::Annotation, but it is no longer registered at the mitk::OverlayManager. Instead, mitk::ManualPlacementAnnotationRenderer and mitk::LayoutAnnotationRenderer are used the register an annotation. \code // Old Overlay registration: overlayManager->AddOverlay(textOverlay3D.GetPointer(), renderer); \endcode \code // New Annotation registration: mitk::ManualPlacementAnnotationRenderer::AddAnnotation(textAnnotation3D, renderer); \endcode A single mitk::Annotation is no longer automatically registered in all available RenderWindows. Each mitk::Annotation is shown only once. The user is also responsible for the memory management. When a created mitk::Annotation has no more SmartPointer references, it disappears. The Layouter concept was implemented in the mitk::LayoutAnnotationRenderer: \code // Old way to layout an mitk::Overlay: verlayManager->AddOverlay(textOverlay.GetPointer()); overlayManager->AddLayouter( mitk::Overlay2DLayouter::CreateLayouter(mitk::Overlay2DLayouter::STANDARD_2D_TOPLEFT(), renderer2D).GetPointer()); overlayManager->SetLayouter(textOverlay.GetPointer(), mitk::Overlay2DLayouter::STANDARD_2D_TOPLEFT(), renderer2D); \endcode \code // New way to layout an mitk::Annotation: mitk::LayoutAnnotationRenderer::AddAnnotation(textAnnotation, rendererID, mitk::LayoutAnnotationRenderer::TopLeft, 5, 5, 1); // The layouter gets parameters for margins and the priority for the placement in the RenderWindow corners. \endcode */