TransformationManager manages frames of reference and transformations for a CamiTK Application. More...
#include <TransformationManager.h>
Collaboration diagram for camitk::TransformationManager:Static Public Member Functions | |
| static void | fromVariant (const QVariant &) |
| Load Frame and Transformation data from a QVariant. | |
| static Transformation * | getInverseTransformation (const Transformation *tr) |
| static QVector< Transformation * > | getSources (const Transformation *) |
| Get the list of sources used to compute the provided Transformation. | |
| static bool | hasSources (const Transformation *) |
| Was this Transformation computed from others or not? | |
| static bool | isCompositeTransformation (const Transformation *tr) |
| Is this transformation composed of two or more transformations ? | |
| static bool | isInverseTransformation (const Transformation *) |
| static QString | toString () |
| get current state as a QString | |
| static QVariant | toVariant () |
| Save Frame and Transformation data to a QVariant. | |
| static std::shared_ptr< FrameOfReference > | getFrameOfReferenceOwnership (const QUuid &uuid) |
| FrameOfReference Management. | |
| static std::shared_ptr< FrameOfReference > | getFrameOfReferenceOwnership (const FrameOfReference *) |
| Get the shared_ptr that owns the given FrameOfReference. | |
| static std::shared_ptr< FrameOfReference > | addFrameOfReference (QString name, QString description="") |
| Add a FrameOfReference with a name and description This is the standard way to create a new FrameOfReference. | |
| static std::shared_ptr< FrameOfReference > | addFrameOfReference (const FrameOfReference &) |
| Add a copy of the provided FrameOfReference (with a different UUID) | |
| static QVector< FrameOfReference * > | getFramesOfReference () |
| Get a list of all stored FrameOfReference. | |
| static bool | hasPath (const FrameOfReference *from, const FrameOfReference *to) |
| Transformation Management. | |
| static bool | isDefaultIdentityToWorld (const Transformation *) |
| Is the transformation a default one ? This means that it was created as Identity by default and might be replaced it another Transformation is set It is usually a Transformation which destination is worldFrame. | |
| static Transformation * | getTransformation (const FrameOfReference *from, const FrameOfReference *to) |
| Get a transformation if it exists or compute it if a path exists between the frames. | |
| static std::shared_ptr< Transformation > | getTransformationOwnership (const Transformation *) |
| Get the shared_ptr that owns the given Transformation. | |
| static std::shared_ptr< Transformation > | getTransformationOwnership (const QUuid &uuid) |
| Get the shared_ptr that owns the Transformation with given UUID. | |
| static std::shared_ptr< Transformation > | getTransformationOwnership (const FrameOfReference *from, const FrameOfReference *to) |
| Get the shared_ptr that owns the given Transformation between from and to. | |
| static void | ensurePathToWorld (const FrameOfReference *frame) |
| Make sure there is a Transformation from the given Frame to the world Frame. | |
| static bool | preferredDefaultIdentityToWorldLink (const FrameOfReference *frame) |
| Call this method when you prefer (for visualization purpose only) to have a direct link to world from the given frame instead of any other path. | |
| static const FrameOfReference * | getWorldFrame () |
| Get the WorldFrame. | |
| static QVector< Transformation * > | getDirectTransformations () |
| Returns the list of direct transformations, that is the transformations that are independent of any other. | |
| static QVector< Transformation * > | getTransformations () |
| Returns the list of all transformations managed in the system, independents or not. | |
| static std::shared_ptr< Transformation > | addTransformation (const QVariant &) |
| Create and register a new Transformation from a QVariant (usually from a JSON representation in a .camitk file) if there is no corresponding transformation (uuid and from/to path) | |
| static std::shared_ptr< Transformation > | addTransformation (const FrameOfReference *from, const FrameOfReference *to) |
| Create and register a new identity Transformation between two frames if there is no existing transformation between those frames. | |
| static std::shared_ptr< Transformation > | addTransformation (const std::shared_ptr< FrameOfReference > &from, const std::shared_ptr< FrameOfReference > &to) |
| Create and register a new identity Transformation between two frames if there is no existing transformation between those frames. | |
| static std::shared_ptr< Transformation > | addTransformation (const FrameOfReference *from, const FrameOfReference *to, vtkSmartPointer< vtkTransform > vtkTr) |
| Create and register a new Transformation between two frames and sets the transformation to the provided transform if there is no existing transformation between those frames. | |
| static std::shared_ptr< Transformation > | addTransformation (const std::shared_ptr< FrameOfReference > &from, const std::shared_ptr< FrameOfReference > &to, vtkSmartPointer< vtkTransform > vtkTr) |
| Create and register a new Transformation between two frames and sets the transformation to the provided transform if there is no existing transformation between those frames. | |
| static std::shared_ptr< Transformation > | addTransformation (const FrameOfReference *from, const FrameOfReference *to, const vtkMatrix4x4 *matrix) |
| Create and register a new Transformation between two frames, copying the content of the provided matrix if there is no existing transformation between those frames. | |
| static std::shared_ptr< Transformation > | addTransformation (const std::shared_ptr< FrameOfReference > &from, const std::shared_ptr< FrameOfReference > &to, const vtkMatrix4x4 *matrix) |
| Create and register a new Transformation between two frames, copying the content of the provided matrix if there is no existing transformation between those frames. | |
| static void | cleanupFramesAndTransformations () |
| Remove transformations and frames that are unused (i.e. | |
| static bool | removeTransformation (std::shared_ptr< Transformation > &tr) |
| Remove an existing transformation between the two frames. | |
| static bool | removeTransformation (const FrameOfReference *from, const FrameOfReference *to) |
| Remove an existing transformation between the two frames. | |
updateTransformation | |
Updating a Transformation work only for Transformations created by addTransformation() It will fail if the transformation was computed from others (e.g. inverse of another Transformation, or a composition) If there is already path, but some Transformation are default identity Transformation, you should be using addTransformation. If there is already a valid path using non-default Transformations you must break the path before using addTransformation.
| |
| static bool | updateTransformation (const FrameOfReference *from, const FrameOfReference *to, vtkSmartPointer< vtkTransform > vtkTr) |
| Modify the Transformation between the two frames by setting its vtkTransform. | |
| static bool | updateTransformation (const FrameOfReference *from, const FrameOfReference *to, vtkMatrix4x4 *matrix) |
| Modify the Transformation between the two frames by setting its vtkMatrix. | |
| static bool | updateTransformation (Transformation *tr, vtkSmartPointer< vtkTransform > vtkTr) |
| Modify the Transformation by setting its vtkTransform. | |
| static bool | updateTransformation (Transformation *tr, vtkMatrix4x4 *matrix) |
| Modify the Transformation by setting its matrix. | |
TransformationManager manages frames of reference and transformations for a CamiTK Application.
This class is the entry point to using FrameOfReference and Transformation system.
Every Component that is displayable contains data which are located in space using coordinates. But two Components may not use the same origin in space, or the same axes.
To manage that, the notion of Frame specifies an origin and axes, this is modeled by camitk::FrameOfReference. Each component has a FrameOfReference accessed by Component::getFrame()
Two Components may share a common Frame, for example two meshes of two organs computed from the same image. In this case both components' getFrame() should return the same FrameOfReference.
TransformationManager stores and manages all the FrameOfReference objects used in a CamiTK Application.
When you need to display two Components, or to apply an Action that uses multiple Components, it is necessary to be able to transform the coordinates of one Component's data to another.
These geometrical transformations are stored in the camitk::Transformation class. A Transformation stores the frame of origin, the frame of destination and the geometrical transformation itself. Currently it supports linear transformations (represented in a 4x4 homogeneous matrices).
All Transformation objects are also stored and managed in the TransformationManager. The TransformationManager provides and manages a specific and unique "world frame". This is the frame used by VTK and the default for 3D viewers. Having a world frame simplifies the usage of frames.
Alongside Component, Viewers also have a FrameOfReference, which determines the "point of view" they are using for the visualization. More precisely, it is used to set the camera and orient the vtkActors. The default frame of the 2D and 3D viewers is the world frame.
Their is only one TransformationManager (all public methods are static).
Transformation and Frames can be manipulated locally using their raw pointer. Use the shared pointer only if you need to own the object as well, that if the Transformation or Frame is part of your class members and need to be kept alive for your code to work. Using a shared pointer ensures that the Frame or Transformation won't be removed from the system by the TransformationManager. If you only need to access or modify information on a frame or transformation, only use the raw pointer.
The TransformationManager provides the following utilities:
Two methods are provided for the manipulation of world frame:
A Transformation can either be:
Information about a Transformation t can be obtained from the TransformationManager using:
There is three cases where TransformationManager will automatically create a transformation:
Note that TransformationManager always generates an inverse transformation for any existing linear transformation if it does not exist already.
The lists of Transformation sources are managed by the TransformationManager. Sources are the transformations that are used (composed) to compute a Transformation t. If any of the sources are modified, t is guaranteed to reflect this update, i.e., it is recomputed from its sources. If t has only one source, this means t is the inverse of this source.
A FrameOfReference represents a specific system of coordinates in which component data's coordinates are expressed.
It can have a name, a description, and anatomical labels associated to its axes: for example, the X axis may have label L on the lower values, and R on the higher values (for Left/Right anatomical orientation). You can add new Frames of reference using addFrameOfReference methods when creating a new Component (even though Component constructor creates a default one for you), or if you need to manage multiple frames in your component (e.g. for an articulated robot).
If you need to get ownership of a specific FrameOfReference (e.g. you want your Component to store the same Frame as another Component), use getFrameOfReferenceOwnership()
To edit anatomical information, name or description, refer to FrameOfReference class.
When you need a Transformation from one Frame to another, the method to call is getTransformation()
This method first looks if a Transformation was added using addTransformation between those Frames, then if there is already a cached composite Transformation linking both Frames, and finally, it checks whether there is a path in the graph of Frames and Transformations linking those Frames using intermediary Frames.
Private methods hasPath() and getPath() are used to search the graph for a suitable path. If there is one, a new cached composite Transformation is stored (it combines the path of Transformations into one). If there is no path, these methods return nullptr.
When the user wants to ensure that a specific Frame has a Transformation to the WorldFrame, she/he should call ensurePathToWorld(). This will create a default identity Transformation to the WorldFrame if there is no existing path between the Frame and the WorldFrame.
All default identity Transformations are marked, so that if a new Transformation is added using addTransformation, these Transformations can be automatically removed. This is needed to avoid creation of multiple path between Frames (there will therefore never be any cycle in the Frame/Transformation graph).
As FrameOfReference and Transformation constructors are private, all Frames and Transformations must be created through the TransformationManager.
Internally, Transformation and FrameOfReference objects are stored using std::shared_ptr
This means that ownership of these objects is shared between the TransformationManager and custom objects used in CamiTK such as Component (which owns its FrameOfReference), ImageComponent (which also owns its internal Transformation from raw to main).
Most methods of this class return or use raw pointers, meaning they do not return or get ownership of the FrameOfReference or Transformation object. The raw pointers are meant to be used for immediate processing (e.g. getting the name of a Frame, transforming the coordinates of a point using a Transformation) but not to store the pointer. If you need to store the object, you must use getFrameOfReferenceOwnership() and getTransformationOwnership() This makes explicit who is owning Transformations and Frames.
Note that you may not get ownership of a composite Transformation (computed from others) or a default Transformation, as those must be removable at all times.
TransformationManager may delete any Transformation that is not owned outside its internal data structure (which mean they are not used anymore apart from internally).
To determine whether a Transformation or Frame is owned outside the TransformationManager, std::shared_ptr usage counter is used.
Most common use cases for CamiTK extension developers:
out->setFrameFrom(in)outMesh->setFrame(TransformationManager::getFrameOfReferenceOwnership(inImage->getDataFrame())); as the mesh is computed from the image data, the mesh is defined in the image component data frameIn the case of an articulated robot, each part may have its own FrameOfReference, and each articulation its own Transformation. You can use methods addFrameOfReference, addTransformation, updateTransformation to create and update frames and transformations in your Action and Component extensions.
|
static |
Add a copy of the provided FrameOfReference (with a different UUID)
|
static |
Add a FrameOfReference with a name and description This is the standard way to create a new FrameOfReference.
References description.
Referenced by camitk::ArbitrarySingleImageComponent::ArbitrarySingleImageComponent(), fromVariant(), transformations_and_frames::process(), camitk::Component::resetFrame(), camitk::ImageComponent::resetFrame(), and camitk::ArbitrarySingleImageComponent::setFrame().
Here is the caller graph for this function:
|
static |
Create and register a new identity Transformation between two frames if there is no existing transformation between those frames.
|
static |
Create and register a new Transformation between two frames, copying the content of the provided matrix if there is no existing transformation between those frames.
A deep copy of the given matrix is used to initialize the new Transformation
|
static |
Create and register a new Transformation between two frames and sets the transformation to the provided transform if there is no existing transformation between those frames.
| vtkTr | The vtkTransform pointer that will be stored in the Transformation. |
|
static |
Create and register a new Transformation from a QVariant (usually from a JSON representation in a .camitk file) if there is no corresponding transformation (uuid and from/to path)
References CAMITK_WARNING_ALT, camitk::Transformation::fromVariant(), camitk::Transformation::getFrom(), camitk::Transformation::getTo(), camitk::Transformation::getTransform(), and camitk::Transformation::getUuid().
Referenced by fromVariant(), transformations_and_frames::process(), camitk::ImageComponent::resetFrame(), camitk::ImageComponent::setFrame(), and camitk::ImageComponent::setImageData().
Here is the call graph for this function:
Here is the caller graph for this function:
|
static |
Create and register a new identity Transformation between two frames if there is no existing transformation between those frames.
|
static |
Create and register a new Transformation between two frames, copying the content of the provided matrix if there is no existing transformation between those frames.
A deep copy of the given matrix is used to initialize the new Transformation
|
static |
Create and register a new Transformation between two frames and sets the transformation to the provided transform if there is no existing transformation between those frames.
| vtkTr | The vtkTransform pointer that will be stored in the Transformation. |
References CAMITK_WARNING_ALT.
|
static |
Remove transformations and frames that are unused (i.e.
only present in the TransformationManager)
Referenced by CloseAllAction::apply(), camitk::Application::close(), camitk::Application::loadWorkspace(), camitk::Application::open(), camitk::Application::openDirectory(), and camitk::Action::refreshApplication().
Here is the caller graph for this function:
|
static |
Make sure there is a Transformation from the given Frame to the world Frame.
This will create an identity (default) transformation if no path to world already exists.
Referenced by camitk::InteractiveViewer::addActor(), and camitk::InteractiveViewer::setFrame().
Here is the caller graph for this function:
|
static |
Load Frame and Transformation data from a QVariant.
This reads "frames" and "transformations" from the provided QVariantMap to add Frame and Transformation objects in the TransformationManager
References addFrameOfReference(), and addTransformation().
Here is the call graph for this function:
|
static |
Returns the list of direct transformations, that is the transformations that are independent of any other.
The inverse transformations (which have one source) and composite transformations (which have 2 or more sources) are not included.
Referenced by TransformationExplorer::refresh(), and toVariant().
Here is the caller graph for this function:
|
static |
Get the shared_ptr that owns the given FrameOfReference.
This should only be used to take shared ownership of the given FrameOfReference.
|
static |
FrameOfReference Management.
Get a FrameOfReference from its UUID
Referenced by ImageReconstructionAction::apply(), MergeMeshes::apply(), camitk::ArbitrarySingleImageComponent::ArbitrarySingleImageComponent(), DicomComponent::DicomComponent(), camitk::InteractiveViewer::eventFilter(), camitk::Component::fromVariant(), camitk::ImageComponent::fromVariant(), TransformationExplorer::getWidget(), camitk::InteractiveViewer::init(), camitk::InteractiveViewer::refresh(), camitk::Component::setFrameFrom(), and camitk::SingleImageComponent::SingleImageComponent().
Here is the caller graph for this function:
|
static |
Get a list of all stored FrameOfReference.
Referenced by camitk::InteractiveViewer::eventFilter(), TransformationExplorer::refresh(), transformations_and_frames::targetDefined(), and toString().
Here is the caller graph for this function:
|
static |
References camitk::Transformation::getFrom(), camitk::Transformation::getTo(), and getTransformation().
Here is the call graph for this function:
|
static |
Get the list of sources used to compute the provided Transformation.
|
static |
Get a transformation if it exists or compute it if a path exists between the frames.
Referenced by camitk::InteractiveViewer::addActor(), MergeMeshes::apply(), camitk::ArbitrarySingleImageComponent::get3DCursor(), getInverseTransformation(), camitk::ImageComponent::getLastPointPickedWorldFrame(), and camitk::InteractiveViewer::picked().
Here is the caller graph for this function:
|
static |
Get the shared_ptr that owns the given Transformation between from and to.
This should only be used to take shared ownership of the given Transformation.
|
static |
Get the shared_ptr that owns the Transformation with given UUID.
This should only be used to take shared ownership of the given Transformation.
|
static |
Get the shared_ptr that owns the given Transformation.
This should only be used to take shared ownership of the given Transformation.
Referenced by camitk::ImageComponent::fromVariant(), TransformationExplorer::getWidget(), camitk::ImageComponent::setFrame(), and camitk::ImageComponent::setImageData().
Here is the caller graph for this function:
|
static |
Returns the list of all transformations managed in the system, independents or not.
Referenced by TransformationExplorer::refresh(), and toString().
Here is the caller graph for this function:
|
static |
Get the WorldFrame.
This is the Frame that links all Frames so that there is a common space If a Component's frame is not linked by a Transformation to any other Frame, a default identity Transformation should be created between it and this worldFrame
This is done by calling ensurePathToWorld
Referenced by MergeMeshes::apply(), camitk::ImageComponent::getLastPointPickedWorldFrame(), camitk::InteractiveViewer::init(), transformations_and_frames::process(), and camitk::InteractiveViewer::refresh().
Here is the caller graph for this function:
|
static |
Transformation Management.
returns true if there a path of transformations between two frames of reference 'from' and 'to' or if from equals to.
This will search for a path in the graph of frames/transformations.
|
static |
Was this Transformation computed from others or not?
|
static |
Is this transformation composed of two or more transformations ?
|
static |
Is the transformation a default one ? This means that it was created as Identity by default and might be replaced it another Transformation is set It is usually a Transformation which destination is worldFrame.
Referenced by MergeMeshes::apply(), and toVariant().
Here is the caller graph for this function:
|
static |
|
static |
Call this method when you prefer (for visualization purpose only) to have a direct link to world from the given frame instead of any other path.
If another path to world exists from the frame and include a default identity transformation to world, it will be delete in favor of a new default identity transformation that directly links the given frame to world.
|
static |
Remove an existing transformation between the two frames.
|
static |
Remove an existing transformation between the two frames.
This method checks that the given shared_ptr<Transformation> has no other owner than the caller (i.e., only the caller of this method has ownership of the given shared_ptr). If this is true, then the shared_ptr will be set to nullptr, which will result in the deletion of the Transformation.
If there is another owner, the shared_ptr is not modified, and the Transformation will not be removed.
If the given shared_ptr is equal to nullptr (for instance when calling removeTransformation(getTransformationOwnership(t)) with t being a composite transformation), this method returns false.
Referenced by transformations_and_frames::process().
Here is the caller graph for this function:
|
static |
get current state as a QString
References getFramesOfReference(), and getTransformations().
Referenced by camitk::InteractiveViewer::keyPressEvent().
Here is the call graph for this function:
Here is the caller graph for this function:
|
static |
Save Frame and Transformation data to a QVariant.
This creates a QVariantMap with the keys "frames" and "transformations" for saving the state of the TransformationManager
References getDirectTransformations(), and isDefaultIdentityToWorld().
Here is the call graph for this function:
|
static |
Modify the Transformation between the two frames by setting its vtkMatrix.
|
static |
Modify the Transformation between the two frames by setting its vtkTransform.
Referenced by transformations_and_frames::process(), camitk::ArbitrarySingleImageComponent::setFrame(), camitk::ImageComponent::setImageData(), camitk::ArbitrarySingleImageComponent::setSlice(), and camitk::ImageComponent::updateMainTransformation().
Here is the caller graph for this function:
|
static |
Modify the Transformation by setting its matrix.
References CAMITK_WARNING_ALT, camitk::Transformation::getFrom(), camitk::Transformation::getName(), and camitk::Transformation::getTo().
Here is the call graph for this function:
|
static |
Modify the Transformation by setting its vtkTransform.