Skip to content

Commit

Permalink
ENH: Improve interaction options in Transforms SH plugin and module w…
Browse files Browse the repository at this point in the history
…idget

New SH actions for resetting the center of transformation for a transform:
  - Reset to local origin
  - Reset to world origin
  - Reset to center of bounds for all transformed nodes
  - Reset to center of bounds for a single transformed node

Transforms module widget:
  - New widget for live display and editing of center of transformation (in local or world coordinates)
  - New slider for changing scale of interaction widget
  - Transform rotation sliders now rotate around the center of transformation

Bug fixes:
  - Use correct scale for markups interaction handles
  - Fix both 2D and 3D visibility being controlled by GetEditorSliceIntersectionVisibility

Re #7570
  • Loading branch information
Sunderlandkyl committed Mar 18, 2024
1 parent afe4051 commit fd82ad4
Show file tree
Hide file tree
Showing 15 changed files with 687 additions and 205 deletions.
20 changes: 20 additions & 0 deletions Libs/MRML/Core/vtkMRMLTransformNode.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1724,3 +1724,23 @@ void vtkMRMLTransformNode::CreateDefaultSequenceDisplayNodes()
{
// don't create display nodes for transforms by default
}

//----------------------------------------------------------------------------
void vtkMRMLTransformNode::SetCenterOfTransformation(double x, double y, double z)
{
vtkDebugMacro(<< " setting CenterOfTransformation to (" << x << "," << y << "," << z << ")");
if ((this->CenterOfTransformation[0] != x) || (this->CenterOfTransformation[1] != y) || (this->CenterOfTransformation[2] != z))
{
this->CenterOfTransformation[0] = x;
this->CenterOfTransformation[1] = y;
this->CenterOfTransformation[2] = z;
this->Modified();
this->TransformModified();
}
}

//----------------------------------------------------------------------------
void vtkMRMLTransformNode::SetCenterOfTransformation(const double center[3])
{
this->SetCenterOfTransformation(center[0], center[1], center[2]);
}
3 changes: 2 additions & 1 deletion Libs/MRML/Core/vtkMRMLTransformNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ class VTK_MRML_EXPORT vtkMRMLTransformNode : public vtkMRMLDisplayableNode
static const char* GetFixedNodeReferenceRole() { return "spatialRegistrationFixed"; };

/// The transformation center (rotation/scaling) that is rotated/scaled around
vtkSetVector3Macro(CenterOfTransformation, double);
virtual void SetCenterOfTransformation(double x, double y, double z);
virtual void SetCenterOfTransformation(const double xyz[3]);
vtkGetVector3Macro(CenterOfTransformation, double);

protected:
Expand Down
29 changes: 28 additions & 1 deletion Libs/MRML/Widgets/qMRMLLinearTransformSlider.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,29 @@ void qMRMLLinearTransformSlider::applyTransformation(double _sliderPosition)
qMRMLUtils::getTransformInCoordinateSystem(d->MRMLTransformNode,
d->CoordinateReference == qMRMLLinearTransformSlider::GLOBAL, transform.GetPointer());

double centerOfTransformation[3] = { 0.0, 0.0, 0.0 };
d->MRMLTransformNode->GetCenterOfTransformation(centerOfTransformation);

if (this->typeOfTransform() == ROTATION_LR
|| this->typeOfTransform() == ROTATION_PA
|| this->typeOfTransform() == ROTATION_IS)
{
// We only need to translate the center of the transformation to the origin when we are rotating
if (d->CoordinateReference == qMRMLLinearTransformSlider::GLOBAL)
{
// Transform the center of transformation to the parent coordinate system
transform->TransformPoint(centerOfTransformation, centerOfTransformation);
vtkMath::MultiplyScalar(centerOfTransformation, -1.0);
}
transform->Translate(centerOfTransformation);
}

vtkMatrix4x4 * matrix = transform->GetMatrix();
Q_ASSERT(matrix);
if (!matrix) { return; }
if (!matrix)
{
return;
}

bool transformChanged = false;
const double rotationChangeTolerance = 0.00001;
Expand Down Expand Up @@ -336,6 +356,13 @@ void qMRMLLinearTransformSlider::applyTransformation(double _sliderPosition)
}
d->OldPosition = _sliderPosition;

if (this->typeOfTransform() == ROTATION_LR
|| this->typeOfTransform() == ROTATION_PA
|| this->typeOfTransform() == ROTATION_IS)
{
transform->Translate(-centerOfTransformation[0], -centerOfTransformation[1], -centerOfTransformation[2]);
}

if (transformChanged)
{
d->MRMLTransformNode->SetMatrixTransformToParent(transform->GetMatrix());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ void vtkSlicerMarkupsInteractionWidgetRepresentation::UpdateHandleToWorldTransfo
//----------------------------------------------------------------------
double vtkSlicerMarkupsInteractionWidgetRepresentation::GetInteractionScalePercent()
{
return this->GetDisplayNode()->GetGlyphScale() * 5.0;
return this->GetDisplayNode()->GetInteractionHandleScale() * 5.0;
}

//----------------------------------------------------------------------
Expand Down Expand Up @@ -594,22 +594,7 @@ bool vtkSlicerMarkupsInteractionWidgetRepresentation::GetHandleVisibility(int ty
return false;
}

bool handleVisibility[4] = { false, false, false, false };
if (markupsComponentType == vtkMRMLMarkupsDisplayNode::ComponentRotationHandle)
{
this->GetDisplayNode()->GetRotationHandleComponentVisibility(handleVisibility);
}
else if (markupsComponentType == vtkMRMLMarkupsDisplayNode::ComponentScaleHandle)
{
this->GetDisplayNode()->GetScaleHandleComponentVisibility(handleVisibility);
}
else if (markupsComponentType == vtkMRMLMarkupsDisplayNode::ComponentTranslationHandle)
{
this->GetDisplayNode()->GetTranslationHandleComponentVisibility(handleVisibility);
}

int visibilityIndex = index;
bool visibility = true;
if (type == InteractionScaleHandle && vtkMRMLMarkupsROINode::SafeDownCast(this->GetMarkupsNode()))
{
switch (index)
Expand Down Expand Up @@ -649,12 +634,27 @@ bool vtkSlicerMarkupsInteractionWidgetRepresentation::GetHandleVisibility(int ty
}
}

if (visibilityIndex >= 0 || visibilityIndex <= 3)
if (visibilityIndex < 0 || visibilityIndex > 3)
{
visibility = handleVisibility[visibilityIndex];
// Index out of range.
return false;
}

bool handleVisibility[4] = { false, false, false, false };
if (markupsComponentType == vtkMRMLMarkupsDisplayNode::ComponentRotationHandle)
{
this->GetDisplayNode()->GetRotationHandleComponentVisibility(handleVisibility);
}
else if (markupsComponentType == vtkMRMLMarkupsDisplayNode::ComponentScaleHandle)
{
this->GetDisplayNode()->GetScaleHandleComponentVisibility(handleVisibility);
}
else if (markupsComponentType == vtkMRMLMarkupsDisplayNode::ComponentTranslationHandle)
{
this->GetDisplayNode()->GetTranslationHandleComponentVisibility(handleVisibility);
}

return visibility && Superclass::GetHandleVisibility(type, index);
return handleVisibility[visibilityIndex] && Superclass::GetHandleVisibility(type, index);
}

//----------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,10 @@ void qMRMLSubjectHierarchyTreeViewPrivate::init()
// Transform
this->TransformMenu = new QMenu(q);

this->TransformInteractionInViewAction = new QAction(qMRMLSubjectHierarchyTreeView::tr("Interaction in 3D view"), this->TransformMenu);
this->TransformInteractionInViewAction = new QAction(qMRMLSubjectHierarchyTreeView::tr("Interaction"), this->TransformMenu);
this->TransformInteractionInViewAction->setCheckable(true);
this->TransformInteractionInViewAction->setToolTip(qMRMLSubjectHierarchyTreeView::tr("Allow interactively modify the transform in 3D views"));
this->TransformInteractionInViewAction->setToolTip(
qMRMLSubjectHierarchyTreeView::tr("Allow the transform to be modified interactively in the 2D and 3D views"));
this->TransformMenu->addAction(this->TransformInteractionInViewAction);
QObject::connect(this->TransformInteractionInViewAction, SIGNAL(toggled(bool)), q, SLOT(onTransformInteractionInViewToggled(bool)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ bool vtkMRMLLinearTransformsDisplayableManager::vtkInternal::UseDisplayNode(vtkM
{
return displayNode
&& displayNode->GetScene()
&& displayNode->GetEditorVisibility() && displayNode->GetEditorSliceIntersectionVisibility()
&& displayNode->GetEditorVisibility()
&& (this->GetAbstractViewNode()->IsA("vtkMRMLSliceNode") ? displayNode->GetEditorSliceIntersectionVisibility() : displayNode->GetEditorVisibility3D())
&& displayNode->IsDisplayableInView(this->GetAbstractViewNode()->GetID());
}

Expand Down Expand Up @@ -479,7 +480,7 @@ void vtkMRMLLinearTransformsDisplayableManager::vtkInternal::SetupRenderer()
vtkRenderer* renderer = this->External->GetRenderer();
if (renderer == nullptr)
{
vtkErrorWithObjectMacro(this->External, "vtkMRMLLinearTransformsDisplayableManager3D::vtkInternal::SetupRenderer() failed: renderer is invalid");
vtkErrorWithObjectMacro(this->External, "vtkMRMLLinearTransformsDisplayableManager::vtkInternal::SetupRenderer() failed: renderer is invalid");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>391</width>
<width>514</width>
<height>1223</height>
</rect>
</property>
Expand All @@ -24,7 +24,16 @@
<normaloff>:/Icons/Transforms.png</normaloff>:/Icons/Transforms.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
Expand Down Expand Up @@ -70,9 +79,6 @@
<property name="collapsedHeight">
<number>14</number>
</property>
<property name="contentsFrameShape">
<enum>QFrame::NoFrame</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="qMRMLTransformInfoWidget" name="TransformInfoWidget"/>
Expand Down Expand Up @@ -267,6 +273,62 @@
</item>
</layout>
</item>
<item>
<widget class="ctkCollapsibleGroupBox" name="CenterOfTransformationGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Center of transformation</string>
</property>
<property name="collapsed">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QComboBox" name="CenterOfTransformationCoordinatesComboBox">
<item>
<property name="text">
<string>World</string>
</property>
</item>
<item>
<property name="text">
<string>Local</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Coordinates:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="ResetCenterOfTransformationButton">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="qMRMLCoordinatesWidget" name="CenterOfTransformationCoordinatesWidget">
<property name="quantity">
<string notr="true">length</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -302,12 +364,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="text">
<string>Apply transform</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
Expand Down Expand Up @@ -441,9 +503,6 @@
<property name="checked">
<bool>false</bool>
</property>
<property name="contentsFrameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
Expand Down Expand Up @@ -574,6 +633,33 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ctkCollapsibleButton</class>
<extends>QWidget</extends>
<header>ctkCollapsibleButton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ctkCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>ctkCollapsibleGroupBox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ctkCoordinatesWidget</class>
<extends>QWidget</extends>
<header>ctkCoordinatesWidget.h</header>
</customwidget>
<customwidget>
<class>ctkMatrixWidget</class>
<extends>QWidget</extends>
<header>ctkMatrixWidget.h</header>
</customwidget>
<customwidget>
<class>qMRMLCoordinatesWidget</class>
<extends>ctkCoordinatesWidget</extends>
<header>qMRMLCoordinatesWidget.h</header>
</customwidget>
<customwidget>
<class>qMRMLMatrixWidget</class>
<extends>ctkMatrixWidget</extends>
Expand Down Expand Up @@ -618,23 +704,6 @@
<extends>qMRMLWidget</extends>
<header>qMRMLTransformInfoWidget.h</header>
</customwidget>
<customwidget>
<class>ctkCollapsibleButton</class>
<extends>QWidget</extends>
<header>ctkCollapsibleButton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ctkCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>ctkCollapsibleGroupBox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ctkMatrixWidget</class>
<extends>QWidget</extends>
<header>ctkMatrixWidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../qSlicerTransformsModule.qrc"/>
Expand Down Expand Up @@ -977,5 +1046,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>qSlicerTransformsModuleWidget</sender>
<signal>mrmlSceneChanged(vtkMRMLScene*)</signal>
<receiver>CenterOfTransformationCoordinatesWidget</receiver>
<slot>setMRMLScene(vtkMRMLScene*)</slot>
<hints>
<hint type="sourcelabel">
<x>256</x>
<y>611</y>
</hint>
<hint type="destinationlabel">
<x>256</x>
<y>724</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set(${KIT}_INCLUDE_DIRECTORIES
${MRMLCore_INCLUDE_DIRS}
${MRMLLogic_INCLUDE_DIRS}
${qMRMLWidgets_INCLUDE_DIRS}
${vtkSlicer${MODULE_NAME}ModuleLogic_INCLUDE_DIRS}
)

set(${KIT}_SRCS
Expand All @@ -36,6 +37,7 @@ set(${KIT}_TARGET_LIBRARIES
MRMLLogic
qMRMLWidgets
${QT_LIBRARIES}
vtkSlicer${MODULE_NAME}ModuleLogic
)

#-----------------------------------------------------------------------------
Expand Down

0 comments on commit fd82ad4

Please sign in to comment.