From 65e23dca4412c52b060000ce8969c5740f4e7583 Mon Sep 17 00:00:00 2001 From: 0Huitzil Date: Fri, 16 Jan 2026 13:25:53 +1300 Subject: [PATCH 1/5] Added auto align button to UI --- .../qt/scaffoldsettingswidget.ui | 63 +++++++++++++++---- .../view/ui_scaffoldsettingswidget.py | 41 ++++++++---- 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/mapclientplugins/scaffoldcreator/qt/scaffoldsettingswidget.ui b/mapclientplugins/scaffoldcreator/qt/scaffoldsettingswidget.ui index e1f1dae..50657af 100644 --- a/mapclientplugins/scaffoldcreator/qt/scaffoldsettingswidget.ui +++ b/mapclientplugins/scaffoldcreator/qt/scaffoldsettingswidget.ui @@ -6,7 +6,7 @@ 0 0 - 556 + 554 773 @@ -41,7 +41,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame @@ -56,7 +56,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -82,7 +82,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -100,7 +100,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame @@ -135,7 +135,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame @@ -150,13 +150,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::NoFrame + QFrame::Shape::NoFrame @@ -189,7 +189,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -209,7 +209,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -256,7 +256,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -276,7 +276,44 @@ - Qt::Horizontal + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Auto align + + + + + + + Qt::Orientation::Horizontal @@ -294,7 +331,7 @@ - Qt::Vertical + Qt::Orientation::Vertical diff --git a/mapclientplugins/scaffoldcreator/view/ui_scaffoldsettingswidget.py b/mapclientplugins/scaffoldcreator/view/ui_scaffoldsettingswidget.py index eb762f0..f1b66e3 100644 --- a/mapclientplugins/scaffoldcreator/view/ui_scaffoldsettingswidget.py +++ b/mapclientplugins/scaffoldcreator/view/ui_scaffoldsettingswidget.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'scaffoldsettingswidget.ui' ## -## Created by: Qt User Interface Compiler version 6.8.1 +## Created by: Qt User Interface Compiler version 6.9.1 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -23,7 +23,7 @@ class Ui_ScaffoldSettings(object): def setupUi(self, ScaffoldSettings): if not ScaffoldSettings.objectName(): ScaffoldSettings.setObjectName(u"ScaffoldSettings") - ScaffoldSettings.resize(556, 773) + ScaffoldSettings.resize(554, 773) self.verticalLayout_2 = QVBoxLayout(ScaffoldSettings) self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) @@ -35,7 +35,7 @@ def setupUi(self, ScaffoldSettings): sizePolicy.setHeightForWidth(self.subscaffold_frame.sizePolicy().hasHeightForWidth()) self.subscaffold_frame.setSizePolicy(sizePolicy) self.subscaffold_frame.setMinimumSize(QSize(0, 0)) - self.subscaffold_frame.setFrameShape(QFrame.NoFrame) + self.subscaffold_frame.setFrameShape(QFrame.Shape.NoFrame) self.verticalLayout_5 = QVBoxLayout(self.subscaffold_frame) self.verticalLayout_5.setObjectName(u"verticalLayout_5") self.subscaffold_label = QLabel(self.subscaffold_frame) @@ -71,36 +71,36 @@ def setupUi(self, ScaffoldSettings): self.meshType_frame = QFrame(ScaffoldSettings) self.meshType_frame.setObjectName(u"meshType_frame") - self.meshType_frame.setFrameShape(QFrame.NoFrame) + self.meshType_frame.setFrameShape(QFrame.Shape.NoFrame) self.formLayout = QFormLayout(self.meshType_frame) self.formLayout.setObjectName(u"formLayout") self.formLayout.setContentsMargins(0, -1, 0, -1) self.meshType_label = QLabel(self.meshType_frame) self.meshType_label.setObjectName(u"meshType_label") - self.formLayout.setWidget(0, QFormLayout.LabelRole, self.meshType_label) + self.formLayout.setWidget(0, QFormLayout.ItemRole.LabelRole, self.meshType_label) self.meshType_comboBox = QComboBox(self.meshType_frame) self.meshType_comboBox.setObjectName(u"meshType_comboBox") - self.formLayout.setWidget(0, QFormLayout.FieldRole, self.meshType_comboBox) + self.formLayout.setWidget(0, QFormLayout.ItemRole.FieldRole, self.meshType_comboBox) self.parameterSet_label = QLabel(self.meshType_frame) self.parameterSet_label.setObjectName(u"parameterSet_label") - self.formLayout.setWidget(1, QFormLayout.LabelRole, self.parameterSet_label) + self.formLayout.setWidget(1, QFormLayout.ItemRole.LabelRole, self.parameterSet_label) self.parameterSet_comboBox = QComboBox(self.meshType_frame) self.parameterSet_comboBox.setObjectName(u"parameterSet_comboBox") - self.formLayout.setWidget(1, QFormLayout.FieldRole, self.parameterSet_comboBox) + self.formLayout.setWidget(1, QFormLayout.ItemRole.FieldRole, self.parameterSet_comboBox) self.verticalLayout_2.addWidget(self.meshType_frame) self.meshTypeOptions_frame = QFrame(ScaffoldSettings) self.meshTypeOptions_frame.setObjectName(u"meshTypeOptions_frame") - self.meshTypeOptions_frame.setFrameShape(QFrame.NoFrame) + self.meshTypeOptions_frame.setFrameShape(QFrame.Shape.NoFrame) self.verticalLayout_9 = QVBoxLayout(self.meshTypeOptions_frame) self.verticalLayout_9.setObjectName(u"verticalLayout_9") self.verticalLayout_9.setContentsMargins(0, -1, 0, -1) @@ -109,12 +109,12 @@ def setupUi(self, ScaffoldSettings): self.modifyOptions_frame = QFrame(ScaffoldSettings) self.modifyOptions_frame.setObjectName(u"modifyOptions_frame") - self.modifyOptions_frame.setFrameShape(QFrame.NoFrame) + self.modifyOptions_frame.setFrameShape(QFrame.Shape.NoFrame) self.verticalLayout = QVBoxLayout(self.modifyOptions_frame) self.verticalLayout.setObjectName(u"verticalLayout") self.deleteElementsRanges_frame = QFrame(self.modifyOptions_frame) self.deleteElementsRanges_frame.setObjectName(u"deleteElementsRanges_frame") - self.deleteElementsRanges_frame.setFrameShape(QFrame.NoFrame) + self.deleteElementsRanges_frame.setFrameShape(QFrame.Shape.NoFrame) self.verticalLayout_10 = QVBoxLayout(self.deleteElementsRanges_frame) self.verticalLayout_10.setObjectName(u"verticalLayout_10") self.verticalLayout_10.setContentsMargins(0, 0, 0, 0) @@ -197,6 +197,24 @@ def setupUi(self, ScaffoldSettings): self.verticalLayout.addLayout(self.horizontalLayout_12) + self.horizontalLayout_5 = QHBoxLayout() + self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") + self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + + self.horizontalLayout_5.addItem(self.horizontalSpacer_2) + + self.autoAlignTransformation_pushButton = QPushButton(self.modifyOptions_frame) + self.autoAlignTransformation_pushButton.setObjectName(u"autoAlignTransformation_pushButton") + + self.horizontalLayout_5.addWidget(self.autoAlignTransformation_pushButton) + + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + + self.horizontalLayout_5.addItem(self.horizontalSpacer) + + + self.verticalLayout.addLayout(self.horizontalLayout_5) + self.verticalLayout_2.addWidget(self.modifyOptions_frame) @@ -222,5 +240,6 @@ def retranslateUi(self, ScaffoldSettings): self.scale_label.setText(QCoreApplication.translate("ScaffoldSettings", u"Scale x, y, z:", None)) self.translation_label.setText(QCoreApplication.translate("ScaffoldSettings", u"Translation x, y, z", None)) self.applyTransformation_pushButton.setText(QCoreApplication.translate("ScaffoldSettings", u"Apply transformation", None)) + self.autoAlignTransformation_pushButton.setText(QCoreApplication.translate("ScaffoldSettings", u"Auto align", None)) # retranslateUi From 87592c57b0fa4d10133ce62746ab8ddc269acdfd Mon Sep 17 00:00:00 2001 From: 0Huitzil Date: Fri, 16 Jan 2026 13:26:14 +1300 Subject: [PATCH 2/5] Added basic functionality to auto align scaffold to data --- .../model/scaffoldcreatormodel.py | 58 ++++++++++++++++++- .../view/scaffoldcreatorwidget.py | 5 ++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py b/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py index bf7ab46..15f5273 100644 --- a/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py +++ b/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py @@ -8,7 +8,7 @@ from cmlibs.utils.zinc.general import ChangeManager, HierarchicalChangeManager from cmlibs.utils.zinc.group import group_add_group_elements, group_get_highest_dimension, \ identifier_ranges_fix, identifier_ranges_from_string, identifier_ranges_to_string, mesh_group_to_identifier_ranges -from cmlibs.utils.zinc.region import determine_appropriate_glyph_size +from cmlibs.utils.zinc.region import determine_appropriate_glyph_size, copy_fitting_data from cmlibs.utils.zinc.scene import ( scene_create_selection_group, scene_get_selection_group, scene_create_node_derivative_graphics) from cmlibs.zinc.field import Field, FieldGroup @@ -18,8 +18,11 @@ from scaffoldmaker.annotation.annotationgroup import findAnnotationGroupByName, getAnnotationMarkerGroup, \ getAnnotationMarkerLocationField, getAnnotationMarkerNameField from scaffoldmaker.scaffolds import Scaffolds +from scaffoldmaker.utils.zinc_utils import find_or_create_field_zero_fibres from scaffoldmaker.scaffoldpackage import ScaffoldPackage from scaffoldmaker.utils.exportvtk import ExportVtk +from scaffoldfitter.fitter import Fitter as GeometryFitter +from scaffoldfitter.fitterstepalign import FitterStepAlign import copy import math @@ -734,6 +737,59 @@ def applyTransformation(self, editCoordinatesField): self._checkCustomParameterSet() self._setGraphicsTransformation() + def autoAlignTransformation(self): + """ + Docstring for autoAlignTransformation + + :param self: Description + """ + scaffoldPackage = self._scaffoldPackages[-1] + # Load data into the current region + scaffold_region = self._region + data_region = self._region.getParent().findChildByName('data') + if not data_region.isValid(): + # logger.warning('Missing input data') + return None + data_fieldmodule = data_region.getFieldmodule() + with ChangeManager(data_fieldmodule): + copy_fitting_data(scaffold_region, data_region) + del data_region, data_fieldmodule + # Setup fitting routine + fieldmodule = scaffold_region.getFieldmodule() + fitter = GeometryFitter(region=scaffold_region) + fitter.getInitialFitterStepConfig() + # Load the _loadModel routines + fitter._discoverModelCoordinatesField() + fitter._discoverModelFitGroup() + zero_fibres = find_or_create_field_zero_fibres(fieldmodule) + fitter.setFibreField(zero_fibres) + del zero_fibres + fitter._discoverFlattenGroup() + fitter.defineCommonMeshFields() + # Load the _loadData routines + fitter._discoverDataCoordinatesField() + fitter._discoverMarkerGroup() + fitter.defineCommonMeshFields + fitter.defineDataProjectionFields() + # Start fit + fitter.initializeFit() + # Setup Align step + fit1 = FitterStepAlign() + fitter.addFitterStep(fit1) + fit1.setAlignMarkers(True) + fit1._doAutoAlign() + rotation = [rad * 180.0 / math.pi for rad in fit1._rotation] + scale = [fit1._scale for i in range(3)] + translation = fit1._translation + del fit1 + # If any visual settings changes, update graphics settings + update_rotation = scaffoldPackage.setRotation(rotation) + update_scale = scaffoldPackage.setScale(scale) + update_translation = scaffoldPackage.setTranslation(translation) + if update_rotation or update_scale or update_translation: + self._setGraphicsTransformation() + + def getRotationText(self): return ', '.join(STRING_FLOAT_FORMAT.format(value) for value in self._scaffoldPackages[-1].getRotation()) diff --git a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py index 5d52ab8..8d34454 100644 --- a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py +++ b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py @@ -166,6 +166,7 @@ def _makeConnections(self): self._scaffold_settings_ui.scale_lineEdit.editingFinished.connect(self._scaleLineEditChanged) self._scaffold_settings_ui.translation_lineEdit.editingFinished.connect(self._translationLineEditChanged) self._scaffold_settings_ui.applyTransformation_pushButton.clicked.connect(self._applyTransformationButtonPressed) + self._scaffold_settings_ui.autoAlignTransformation_pushButton.clicked.connect(self._autoAlignTransformationButtonPressed) self._display_settings_ui.displayDataGroup_fieldChooser.setNullObjectName('-') self._display_settings_ui.displayDataGroup_fieldChooser.setRegion(self._segmentation_data_model.getRegion()) self._display_settings_ui.displayDataGroup_fieldChooser.setConditional(field_is_managed_group) @@ -700,6 +701,10 @@ def _applyTransformationButtonPressed(self): self._scaffold_model.applyTransformation(self._display_settings_ui.displayModelCoordinates_fieldChooser.getField()) self._transformationChanged() + def _autoAlignTransformationButtonPressed(self): + self._scaffold_model.autoAlignTransformation() + self._transformationChanged() + def _displayDataGroupChanged(self, index): """ Callback for change in model coordinates field chooser widget. From 7eea47ccb9074b6d599630f8ef4b7c861991b5ea Mon Sep 17 00:00:00 2001 From: 0Huitzil Date: Wed, 21 Jan 2026 11:01:46 +1300 Subject: [PATCH 3/5] Updated custom layout for dialog box --- .../view/scaffoldcreatorwidget.py | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py index 8d34454..ee7eadc 100644 --- a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py +++ b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py @@ -702,8 +702,36 @@ def _applyTransformationButtonPressed(self): self._transformationChanged() def _autoAlignTransformationButtonPressed(self): - self._scaffold_model.autoAlignTransformation() - self._transformationChanged() + # Create dialog + reply = QtWidgets.QDialog(self) + reply.setWindowTitle('Confirm action') + layout = QtWidgets.QVBoxLayout(reply) + # Add text + textLabel = QtWidgets.QLabel('Auto align?') + textLabel.setWordWrap(True) + layout.addWidget(textLabel) + layout.addSpacing(10) + # Add checkboxes for options + alignMarkers = QtWidgets.QCheckBox('Align to markers') + alignMarkers.setChecked(True) + alignGroups = QtWidgets.QCheckBox('Align groups') + alignGroups.setChecked(False) + layout.addWidget(alignGroups) + layout.addWidget(alignMarkers) + layout.addSpacing(10) + # Add standard buttons + buttons = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.StandardButton.Yes | QtWidgets.QDialogButtonBox.StandardButton.No + ) + layout.addWidget(buttons) + buttons.accepted.connect(reply.accept) + buttons.rejected.connect(reply.reject) + # Execute dialog + if reply.exec() == QtWidgets.QDialog.Accepted: + self._scaffold_model.autoAlignTransformation( + alignMarkers.isChecked(), alignGroups.isChecked() + ) + self._transformationChanged() def _displayDataGroupChanged(self, index): """ From 7a1ade59effc093e869e7d07410a3b260360c892 Mon Sep 17 00:00:00 2001 From: 0Huitzil Date: Tue, 27 Jan 2026 11:31:04 +1300 Subject: [PATCH 4/5] Basic version with auto detection of markers/groups --- .../model/scaffoldcreatormodel.py | 83 +++++++++++++------ .../view/scaffoldcreatorwidget.py | 63 +++++++++----- 2 files changed, 98 insertions(+), 48 deletions(-) diff --git a/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py b/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py index 15f5273..8f2605c 100644 --- a/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py +++ b/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py @@ -737,47 +737,81 @@ def applyTransformation(self, editCoordinatesField): self._checkCustomParameterSet() self._setGraphicsTransformation() - def autoAlignTransformation(self): + def initializeAutoAlignTransformation(self): """ - Docstring for autoAlignTransformation + Docstring for initializeAutoAlignTransformation :param self: Description """ - scaffoldPackage = self._scaffoldPackages[-1] - # Load data into the current region + # scaffoldPackage = self._scaffoldPackages[-1] scaffold_region = self._region - data_region = self._region.getParent().findChildByName('data') - if not data_region.isValid(): - # logger.warning('Missing input data') - return None + # Load data into the current region (copied from load_vagus_data in 3d_nerve1) + # This way of loading data is probably not completely right? Need to consult for a better way + data_region = self._parentRegion.findChildByName('data') data_fieldmodule = data_region.getFieldmodule() with ChangeManager(data_fieldmodule): copy_fitting_data(scaffold_region, data_region) del data_region, data_fieldmodule # Setup fitting routine fieldmodule = scaffold_region.getFieldmodule() - fitter = GeometryFitter(region=scaffold_region) - fitter.getInitialFitterStepConfig() + self.fitter = GeometryFitter(region=scaffold_region) + self.fitter.getInitialFitterStepConfig() # Load the _loadModel routines - fitter._discoverModelCoordinatesField() - fitter._discoverModelFitGroup() + self.fitter._discoverModelCoordinatesField() + self.fitter._discoverModelFitGroup() zero_fibres = find_or_create_field_zero_fibres(fieldmodule) - fitter.setFibreField(zero_fibres) + self.fitter.setFibreField(zero_fibres) del zero_fibres - fitter._discoverFlattenGroup() - fitter.defineCommonMeshFields() + self.fitter._discoverFlattenGroup() + self.fitter.defineCommonMeshFields() # Load the _loadData routines - fitter._discoverDataCoordinatesField() - fitter._discoverMarkerGroup() - fitter.defineCommonMeshFields - fitter.defineDataProjectionFields() + self.fitter._discoverDataCoordinatesField() + self.fitter._discoverMarkerGroup() + self.fitter.defineDataProjectionFields() # Start fit - fitter.initializeFit() - # Setup Align step + self.fitter.initializeFit() fit1 = FitterStepAlign() - fitter.addFitterStep(fit1) - fit1.setAlignMarkers(True) + self.fitter.addFitterStep(fit1) + return None + + # def canAutoAlignGroups(self): + # """ + # Docstring for canAutoAlignGroups + + # :param self: Description + # """ + # fitterSteps = self.fitter.getFitterSteps() + # alignStep = fitterSteps[-1] + # canAlignGroups = alignStep.canAlignGroups() + # return canAlignGroups + + # def canAutoAlignGroups(self): + # """ + # Docstring for canAutoAlignGroups + + # :param self: Description + # """ + # fitterSteps = self.fitter.getFitterSteps() + # alignStep = fitterSteps[-1] + # canAlignMarkers = alignStep.canAlignMarkers() + # return canAlignMarkers + + def runAutoAlignTransformation(self): + """ + Docstring for runAutoAlignTransformation + + :param self: Description + """ + scaffoldPackage = self._scaffoldPackages[-1] + fit1 = self.fitter.getFitterSteps()[-1] + # Add markers/groups to align step if possible + if fit1.canAlignMarkers(): + fit1.setAlignMarkers(True) + if fit1.canAlignGroups(): + fit1.setAlignGroups(True) + # Run align step fit1._doAutoAlign() + # Store align rotation settings rotation = [rad * 180.0 / math.pi for rad in fit1._rotation] scale = [fit1._scale for i in range(3)] translation = fit1._translation @@ -787,8 +821,7 @@ def autoAlignTransformation(self): update_scale = scaffoldPackage.setScale(scale) update_translation = scaffoldPackage.setTranslation(translation) if update_rotation or update_scale or update_translation: - self._setGraphicsTransformation() - + self._setGraphicsTransformation() def getRotationText(self): return ', '.join(STRING_FLOAT_FORMAT.format(value) for value in self._scaffoldPackages[-1].getRotation()) diff --git a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py index ee7eadc..5a89fb7 100644 --- a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py +++ b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py @@ -706,31 +706,48 @@ def _autoAlignTransformationButtonPressed(self): reply = QtWidgets.QDialog(self) reply.setWindowTitle('Confirm action') layout = QtWidgets.QVBoxLayout(reply) - # Add text - textLabel = QtWidgets.QLabel('Auto align?') - textLabel.setWordWrap(True) - layout.addWidget(textLabel) - layout.addSpacing(10) - # Add checkboxes for options - alignMarkers = QtWidgets.QCheckBox('Align to markers') - alignMarkers.setChecked(True) - alignGroups = QtWidgets.QCheckBox('Align groups') - alignGroups.setChecked(False) - layout.addWidget(alignGroups) - layout.addWidget(alignMarkers) - layout.addSpacing(10) - # Add standard buttons - buttons = QtWidgets.QDialogButtonBox( - QtWidgets.QDialogButtonBox.StandardButton.Yes | QtWidgets.QDialogButtonBox.StandardButton.No - ) - layout.addWidget(buttons) - buttons.accepted.connect(reply.accept) - buttons.rejected.connect(reply.reject) + # If no data supply, send message + hasData = self._segmentation_data_model.hasData() + if not hasData: + # Add text + textLabel = QtWidgets.QLabel('No data file supplied') + textLabel.setWordWrap(True) + layout.addWidget(textLabel) + layout.addSpacing(10) + # add Ok Button + buttons = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.StandardButton.Ok) + buttons.accepted.connect(reply.reject) + layout.addWidget(buttons) + else: + # Initilize fitter + self._scaffold_model.initializeAutoAlignTransformation() + # Verify if markers and/or groups can be aligned + # canAlignMarkers = self._scaffold_model.canAutoAlignGroups() + # canAlignGroups = self._scaffold_model.canAutoAlignGroups() + # Add text + textLabel = QtWidgets.QLabel('Auto align?') + textLabel.setWordWrap(True) + layout.addWidget(textLabel) + layout.addSpacing(10) + # Add checkboxes for options + # alignMarkers = QtWidgets.QCheckBox('Align to markers') + # alignMarkers.setChecked(True) + # alignGroups = QtWidgets.QCheckBox('Align groups') + # alignGroups.setChecked(False) + # layout.addWidget(alignGroups) + # layout.addWidget(alignMarkers) + # layout.addSpacing(10) + # Add standard buttons + buttons = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.StandardButton.Yes | QtWidgets.QDialogButtonBox.StandardButton.No + ) + layout.addWidget(buttons) + buttons.accepted.connect(reply.accept) + buttons.rejected.connect(reply.reject) # Execute dialog if reply.exec() == QtWidgets.QDialog.Accepted: - self._scaffold_model.autoAlignTransformation( - alignMarkers.isChecked(), alignGroups.isChecked() - ) + # input_zinc_data_file = self._segmentation_data_model._data_filename + self._scaffold_model.runAutoAlignTransformation() self._transformationChanged() def _displayDataGroupChanged(self, index): From 5606ff03c613dbdd1b5b9f00444bcd63fa1eb964 Mon Sep 17 00:00:00 2001 From: 0Huitzil Date: Tue, 27 Jan 2026 11:42:12 +1300 Subject: [PATCH 5/5] Added case for 'not enough groups/markers' --- .../model/scaffoldcreatormodel.py | 33 ++---------- .../view/scaffoldcreatorwidget.py | 52 +++++++++---------- 2 files changed, 29 insertions(+), 56 deletions(-) diff --git a/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py b/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py index 8f2605c..fa742e5 100644 --- a/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py +++ b/mapclientplugins/scaffoldcreator/model/scaffoldcreatormodel.py @@ -739,11 +739,8 @@ def applyTransformation(self, editCoordinatesField): def initializeAutoAlignTransformation(self): """ - Docstring for initializeAutoAlignTransformation - - :param self: Description + Initialize the fitter for the automatic align process """ - # scaffoldPackage = self._scaffoldPackages[-1] scaffold_region = self._region # Load data into the current region (copied from load_vagus_data in 3d_nerve1) # This way of loading data is probably not completely right? Need to consult for a better way @@ -772,35 +769,11 @@ def initializeAutoAlignTransformation(self): self.fitter.initializeFit() fit1 = FitterStepAlign() self.fitter.addFitterStep(fit1) - return None + return fit1.canAutoAlign() - # def canAutoAlignGroups(self): - # """ - # Docstring for canAutoAlignGroups - - # :param self: Description - # """ - # fitterSteps = self.fitter.getFitterSteps() - # alignStep = fitterSteps[-1] - # canAlignGroups = alignStep.canAlignGroups() - # return canAlignGroups - - # def canAutoAlignGroups(self): - # """ - # Docstring for canAutoAlignGroups - - # :param self: Description - # """ - # fitterSteps = self.fitter.getFitterSteps() - # alignStep = fitterSteps[-1] - # canAlignMarkers = alignStep.canAlignMarkers() - # return canAlignMarkers - def runAutoAlignTransformation(self): """ - Docstring for runAutoAlignTransformation - - :param self: Description + Run the align step and update visual settings """ scaffoldPackage = self._scaffoldPackages[-1] fit1 = self.fitter.getFitterSteps()[-1] diff --git a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py index 5a89fb7..cf640c9 100644 --- a/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py +++ b/mapclientplugins/scaffoldcreator/view/scaffoldcreatorwidget.py @@ -706,7 +706,6 @@ def _autoAlignTransformationButtonPressed(self): reply = QtWidgets.QDialog(self) reply.setWindowTitle('Confirm action') layout = QtWidgets.QVBoxLayout(reply) - # If no data supply, send message hasData = self._segmentation_data_model.hasData() if not hasData: # Add text @@ -720,33 +719,34 @@ def _autoAlignTransformationButtonPressed(self): layout.addWidget(buttons) else: # Initilize fitter - self._scaffold_model.initializeAutoAlignTransformation() - # Verify if markers and/or groups can be aligned - # canAlignMarkers = self._scaffold_model.canAutoAlignGroups() - # canAlignGroups = self._scaffold_model.canAutoAlignGroups() - # Add text - textLabel = QtWidgets.QLabel('Auto align?') - textLabel.setWordWrap(True) - layout.addWidget(textLabel) - layout.addSpacing(10) - # Add checkboxes for options - # alignMarkers = QtWidgets.QCheckBox('Align to markers') - # alignMarkers.setChecked(True) - # alignGroups = QtWidgets.QCheckBox('Align groups') - # alignGroups.setChecked(False) - # layout.addWidget(alignGroups) - # layout.addWidget(alignMarkers) - # layout.addSpacing(10) - # Add standard buttons - buttons = QtWidgets.QDialogButtonBox( - QtWidgets.QDialogButtonBox.StandardButton.Yes | QtWidgets.QDialogButtonBox.StandardButton.No - ) - layout.addWidget(buttons) - buttons.accepted.connect(reply.accept) - buttons.rejected.connect(reply.reject) + canAutoAlign = self._scaffold_model.initializeAutoAlignTransformation() + if canAutoAlign: + # Add text + textLabel = QtWidgets.QLabel('Automatically align scaffold to data?') + textLabel.setWordWrap(True) + layout.addWidget(textLabel) + layout.addSpacing(10) + # Add buttons + buttons = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.StandardButton.Yes | + QtWidgets.QDialogButtonBox.StandardButton.No + ) + layout.addWidget(buttons) + buttons.accepted.connect(reply.accept) + buttons.rejected.connect(reply.reject) + else: + # Add text + textLabel = QtWidgets.QLabel('Not enough markers and/or groups' \ + ' to perform automatic alignment to data') + textLabel.setWordWrap(True) + layout.addWidget(textLabel) + layout.addSpacing(10) + # add Ok Button + buttons = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.StandardButton.Ok) + layout.addWidget(buttons) + buttons.accepted.connect(reply.reject) # Execute dialog if reply.exec() == QtWidgets.QDialog.Accepted: - # input_zinc_data_file = self._segmentation_data_model._data_filename self._scaffold_model.runAutoAlignTransformation() self._transformationChanged()