diff --git a/source/MRCommonPlugins/ViewerButtons/MRIOFilesMenuItems.cpp b/source/MRCommonPlugins/ViewerButtons/MRIOFilesMenuItems.cpp index 063d79bb0b0f..8e233ec68fd0 100644 --- a/source/MRCommonPlugins/ViewerButtons/MRIOFilesMenuItems.cpp +++ b/source/MRCommonPlugins/ViewerButtons/MRIOFilesMenuItems.cpp @@ -3,6 +3,8 @@ #include "MRViewer/MRMouseController.h" #include "MRViewer/MRRecentFilesStore.h" #include "MRViewer/MRViewport.h" +#include "MRViewer/MRUnitSettings.h" +#include "MRViewer/MRUnits.h" #include "MRViewer/MROpenObjects.h" #include "MRMesh/MRDirectory.h" #include "MRMesh/MRIOFormatsRegistry.h" @@ -333,11 +335,16 @@ void sOpenDICOMs( const std::filesystem::path & directory, const std::string & s std::vector> voxelObjects; ProgressBar::setTaskCount( (int)loadRes.size() + 1 ); std::string errors; + // conversion factor from meters into current UI length units + float scaleFactor = 1; + if ( auto uiLengthUnit = UnitSettings::getUiLengthUnit() ) + scaleFactor = getUnitInfo( LengthUnit::meters ).conversionFactor / getUnitInfo( *uiLengthUnit ).conversionFactor; for ( auto & res : loadRes ) { if ( res.has_value() ) { ProgressBar::nextTask( "Construct ObjectVoxels" ); + res->vol.voxelSize *= scaleFactor; auto expObj = createObjectVoxels( *res, ProgressBar::callBackSetProgress ); if ( ProgressBar::isCanceled() ) { @@ -416,10 +423,10 @@ void OpenDirectoryMenuItem::openDirectory( const std::filesystem::path& director #if !defined( MESHLIB_NO_VOXELS ) && !defined( MRVOXELS_NO_DICOM ) // check if the directory can be opened as a DICOM archive if ( VoxelsLoad::isDicomFolder( directory ) ) - { - sOpenDICOMs( directory, "Failed to open directory as DICOM:\n" + utf8string( directory ) ); - return; - } + { + sOpenDICOMs( directory, "Failed to open directory as DICOM:\n" + utf8string( directory ) ); + return; + } #endif bool isAnySupportedFiles = isSupportedFileInSubfolders( directory ); diff --git a/source/MRViewer/MROpenObjects.cpp b/source/MRViewer/MROpenObjects.cpp index 94d4045248dc..d7eebed6379a 100644 --- a/source/MRViewer/MROpenObjects.cpp +++ b/source/MRViewer/MROpenObjects.cpp @@ -1,4 +1,5 @@ #include "MROpenObjects.h" +#include "MRUnitSettings.h" #include #include #include @@ -126,7 +127,11 @@ Expected makeObjectTreeFromFolder( const std::filesystem::path & f { loadTasks.emplace_back( std::async( std::launch::async, [folder = node.path, &loadingCanceled] () { - return VoxelsLoad::makeObjectVoxelsFromDicomFolder( folder, [&loadingCanceled]( float ){ return !loadingCanceled; } ).and_then( + float scaleFactor = 1; + if ( auto uiLengthUnit = UnitSettings::getUiLengthUnit() ) + scaleFactor = getUnitInfo( LengthUnit::meters ).conversionFactor / getUnitInfo( *uiLengthUnit ).conversionFactor; + return VoxelsLoad::makeObjectVoxelsFromDicomFolder( folder, scaleFactor, + [&loadingCanceled]( float ){ return !loadingCanceled; } ).and_then( [&]( LoadedObjectVoxels && ld ) -> loadObjResultType { return LoadedObjects{ .objs = { ld.obj } }; diff --git a/source/MRVoxels/MRDicom.cpp b/source/MRVoxels/MRDicom.cpp index 172fb24edb5d..7330f0b2ce09 100644 --- a/source/MRVoxels/MRDicom.cpp +++ b/source/MRVoxels/MRDicom.cpp @@ -860,12 +860,14 @@ Expected> createObjectVoxels( const DicomVolumeAsV return obj; } -Expected makeObjectVoxelsFromDicomFolder( const std::filesystem::path& folder, const ProgressCallback& callback ) +Expected makeObjectVoxelsFromDicomFolder( const std::filesystem::path& folder, + float scaleFactor, const ProgressCallback& callback ) { MR_TIMER return loadDicomFolder( folder, 4, subprogress( callback, 0.0f, 0.5f ) ).and_then( [&]( DicomVolumeAsVdb && vdb ) { + vdb.vol.voxelSize *= scaleFactor; return createObjectVoxels( vdb, subprogress( callback, 0.5f, 1.0f ) ); } ).and_then( [&]( std::shared_ptr && objVoxels ) -> Expected diff --git a/source/MRVoxels/MRDicom.h b/source/MRVoxels/MRDicom.h index d70626a7312c..a558a25cba0d 100644 --- a/source/MRVoxels/MRDicom.h +++ b/source/MRVoxels/MRDicom.h @@ -56,7 +56,9 @@ MRVOXELS_API std::vector> loadDicomsFolderTreeAsVdb( MRVOXELS_API Expected> createObjectVoxels( const DicomVolumeAsVdb & dcm, const ProgressCallback & cb = {} ); /// Loads 3D volumetric data from dicom-files in given folder, and converts them into an ObjectVoxels -MRVOXELS_API Expected makeObjectVoxelsFromDicomFolder( const std::filesystem::path& folder, const ProgressCallback& callback = {} ); +/// \param scaleFactor multiplier for voxel size +MRVOXELS_API Expected makeObjectVoxelsFromDicomFolder( const std::filesystem::path& folder, + float scaleFactor, const ProgressCallback& callback = {} ); /// Loads 3D volumetric data from a single DICOM file template