Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.3.2] bug fixes: dcm odd axis + tabs management #1100

Merged
merged 3 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if(POLICY CMP0020)
endif()

if(NOT DEFINED ${MEDINRIA_SUPERBUILD_VERSION})
set(MEDINRIA_SUPERBUILD_VERSION 3.3.1)
set(MEDINRIA_SUPERBUILD_VERSION 3.3.2)
endif()

SET(CMAKE_CXX_STANDARD 17)
Expand Down
3 changes: 3 additions & 0 deletions RELEASE_NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ medInria 3.3:
- PolygonROI, solve graphical/ergonomy pb and crashes (split, clear)
- Variational Segmentation: enhance GUI, solve a spacing error on output masks
- BUGFIX 3.3.1: [Four-views] solve crash closing the views
- BUGFIX 3.3.2:
* Avoid corruption of exported/imported dcm with odd axis
* Fix errors with view tabs if the user switch 2 of them, or remove some of them

medInria 3.2:
- Add some tooltips in view navigator
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
cmake_minimum_required(VERSION 3.3)

if(NOT DEFINED ${medInria_VERSION})
set(medInria_VERSION 3.3.1)
set(medInria_VERSION 3.3.2)
endif()

project(medInria VERSION ${medInria_VERSION})
Expand Down
46 changes: 42 additions & 4 deletions src/layers/legacy/medCoreLegacy/gui/medTabbedViewContainers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,12 @@ medTabbedViewContainers::medTabbedViewContainers(medAbstractWorkspaceLegacy* own
d->closeShortcut = new QShortcut(this);
d->closeShortcut->setKey(Qt::ControlModifier + Qt::Key_W);

// ///////////////////////////////////////////////////////////////////////
// Connect for creation and remove tab
// Connect for creation, removal and move of tabs
connect(d->addTabButton, SIGNAL(clicked()), this, SLOT(addContainerInTabUnNamed()));
connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
connect(d->closeShortcut, SIGNAL(activated()), this, SLOT(closeCurrentTab()));
connect(tabBar(), SIGNAL(tabMoved(int,int)), this, SLOT(movedTabs(int,int)));

// ///////////////////////////////////////////////////////////////////////
// Connect group of view handling
connect(medViewContainerManager::instance(), SIGNAL(containerAboutToBeDestroyed(QUuid)), this, SLOT(removeContainerFromSelection(QUuid)));
connect(this, SIGNAL(containersSelectedChanged()), this, SLOT(buildTemporaryPool()));
Expand Down Expand Up @@ -257,15 +256,38 @@ void medTabbedViewContainers::closeTab(int index)
poMainSpliter->disconnect(this);
}
poTmp->deleteLater();

//Reset tab name if it follows the rule '<Workspace Name>###' is follows
for (int i = 0; i < this->count(); ++i)
{
if (this->tabText(i).isEmpty() || this->tabText(i).startsWith(d->owningWorkspace->name(), Qt::CaseSensitive))
{
this->setTabText(i, d->owningWorkspace->name() + " " + QString::number(i + 1));
}
}

// If medTabbedViewContainers is empty and empty is not allowed, we recreate one tab
if (d->bKeepLeastOne && (this->count() < 1))
{
this->addContainerInTabUnNamed();
}
else
{
// Update the remaining tab indexes
d->containerSelectedForTabIndex.remove(index);
QHash <int, QList<QUuid> > copyHash;
for(auto currentTabIndex : d->containerSelectedForTabIndex.keys())
{
auto previousTab = d->containerSelectedForTabIndex.take(currentTabIndex);
copyHash.insert(copyHash.count(), previousTab);
}
d->containerSelectedForTabIndex.clear();
d->containerSelectedForTabIndex = copyHash;

// Update the current tab to the last one
setCurrentIndex(this->count()-1);
emit containersSelectedChanged();
}
}

void medTabbedViewContainers::tabBarDoubleClickedHandler(int index)
Expand Down Expand Up @@ -456,3 +478,19 @@ void medTabbedViewContainers::minimizeSplitterContainers(QUuid containerMaximize
splitter->show();
}
}

/**
* @brief Launched when a tab from the tabs bar is moved to a new position
*
* @param from index tab before
* @param to index tab after
*/
void medTabbedViewContainers::movedTabs(int from, int to)
{
auto previousFrom = d->containerSelectedForTabIndex.take(from);
auto previousTo = d->containerSelectedForTabIndex.take(to);
d->containerSelectedForTabIndex.insert(from, previousTo);
d->containerSelectedForTabIndex.insert(to, previousFrom);

emit containersSelectedChanged();
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public slots:
medViewContainer* insertNewTab(int index, const QString &name);
void closeCurrentTab();
void closeTab(int index);
void movedTabs(int from, int to);

private slots :
void tabBarDoubleClickedHandler(int index);
Expand Down
54 changes: 15 additions & 39 deletions src/layers/legacy/medImageIO/itkDCMTKImageIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,53 +670,29 @@ void DCMTKImageIO::DetermineOrientation()
}
}


double DCMTKImageIO::GetPositionOnStackingAxisForImage (int index)
{
// Getting the unit vector of the closest axis
// so we know which part of the image position to use
vnl_vector<double> closestAxis (3);
closestAxis[0] = round(m_Direction[2][0]);
closestAxis[1] = round(m_Direction[2][1]);
closestAxis[2] = round(m_Direction[2][2]);
if (fabs(closestAxis[0] + closestAxis[1] + closestAxis[2]) != 1)
// Get maximum absolute value, which is the closest to an axis
auto result = std::max_element(m_Direction[2].begin(), m_Direction[2].end(), [](double a, double b)
{
itkExceptionMacro (
<< "Ambiguous slice stack direction: "
<<m_Direction[2][0]<<" "
<<m_Direction[2][1]<<" "
<<m_Direction[2][2]
);
}
return std::abs(a) < std::abs(b);
});

std::string s_position = this->GetMetaDataValueString("(0020,0032)", index);
std::istringstream is_stream( s_position.c_str() );
// Index of the value in the vector
auto principalAxisIndex = std::distance(m_Direction[2].begin(), result);

double pos = 0.0;
bool foundAxis=false;
return GetPositionFromPrincipalAxisIndex(index, principalAxisIndex);
}

for (int i=0; i<3; i++)
{
if (!(is_stream >> pos) )
{
itkWarningMacro ( << "Cannot convert string to double: " << s_position.c_str() << std::endl );
}
else
{
if (fabs(closestAxis[i]) == 1)
{
foundAxis = true;
break;
}
}
}
double DCMTKImageIO::GetPositionFromPrincipalAxisIndex(int index, int principalAxisIndex)
{
std::string s_position = this->GetMetaDataValueString("(0020,0032)", index);

if (!foundAxis)
{
itkWarningMacro ( <<"Could not identify position on stacking axis, returning zero." << std::endl );
}
// Convert string metadata to vector of double
std::stringstream lineStream(s_position);
std::vector<double> positionVector(std::istream_iterator<double>(lineStream), {});

return pos;
return positionVector[principalAxisIndex];
}


Expand Down
4 changes: 3 additions & 1 deletion src/layers/legacy/medImageIO/itkDCMTKImageIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <medImageIOExport.h>

#include <iterator>
#include <map>
#include <vector>
#include <set>
Expand Down Expand Up @@ -188,7 +189,8 @@ class MEDIMAGEIO_EXPORT DCMTKImageIO : public MultiThreadedImageIOBase
void DetermineOrigin();
void DetermineOrientation();

double GetPositionOnStackingAxisForImage (int);
double GetPositionOnStackingAxisForImage(int);
double GetPositionFromPrincipalAxisIndex(int, int);
double GetSliceLocation(std::string);

void ReadHeader( const std::string& name, const int& fileIndex, const int& fileCount );
Expand Down