Skip to content
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
84 changes: 21 additions & 63 deletions source/MRCommonPlugins/ViewerButtons/MRIOFilesMenuItems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "MRViewer/MRViewport.h"
#include "MRViewer/MROpenObjects.h"
#include "MRMesh/MRDirectory.h"
#include "MRMesh/MRIOFormatsRegistry.h"
#include "MRMesh/MRLinesLoad.h"
#include "MRMesh/MRPointsLoad.h"
#include "MRMesh/MRSerializer.h"
Expand Down Expand Up @@ -321,78 +320,37 @@ OpenDirectoryMenuItem::OpenDirectoryMenuItem() :
}

#if !defined( MESHLIB_NO_VOXELS ) && !defined( MRVOXELS_NO_DICOM )
void sOpenDICOMs( const std::filesystem::path & directory, const std::string & simpleError )
void sOpenDICOMs( const std::filesystem::path & directory )
{
ProgressBar::orderWithMainThreadPostProcessing( "Open DICOMs", [directory, simpleError, viewer = Viewer::instance()] () -> std::function<void()>
ProgressBar::orderWithMainThreadPostProcessing( "Open DICOMs", [directory] () -> std::function<void()>
{
ProgressBar::nextTask( "Load DICOM Folder" );
auto loadRes = VoxelsLoad::loadDicomsFolderTreeAsVdb( directory, 4, ProgressBar::callBackSetProgress );
if ( !loadRes.empty() )
if ( auto loadRes = makeObjectTreeFromFolder( directory, true, ProgressBar::callBackSetProgress ) )
{
bool anySuccess = std::any_of( loadRes.begin(), loadRes.end(), []( const auto & r ) { return r.has_value(); } );
std::vector<std::shared_ptr<ObjectVoxels>> voxelObjects;
ProgressBar::setTaskCount( (int)loadRes.size() + 1 );
std::string errors;
for ( auto & res : loadRes )
return [obj = std::move( loadRes->obj ), directory, warnings = std::move( loadRes->warnings ) ]
{
if ( res.has_value() )
{
ProgressBar::nextTask( "Construct ObjectVoxels" );
auto expObj = createObjectVoxels( *res, ProgressBar::callBackSetProgress );
if ( ProgressBar::isCanceled() )
{
errors = getCancelMessage( directory );
break;
}
if ( !expObj )
{
errors += ( !errors.empty() ? "\n" : "" ) + expObj.error();
break;
}
voxelObjects.push_back( *expObj );
}
else if ( ProgressBar::isCanceled() )
{
errors = getCancelMessage( directory );
break;
}
else if ( !anySuccess )
{
if ( simpleError.empty() )
errors += ( !errors.empty() ? "\n" : "" ) + res.error();
else
errors = simpleError;
}
}
return [viewer, voxelObjects, errors, directory] ()
{
SCOPED_HISTORY( "Open DICOMs" );
for ( auto & obj : voxelObjects )
{
AppendHistory<ChangeSceneAction>( "Open DICOMs", obj, ChangeSceneAction::Type::AddObject );
SceneRoot::get().addChild( obj );
}
viewer->viewport().preciseFitDataToScreenBorder( { 0.9f } );

if ( voxelObjects.size() == 1 )
sSelectRecursive( *obj );
AppendHistory<ChangeSceneAction>( "Open DICOMs", obj, ChangeSceneAction::Type::AddObject );
SceneRoot::get().addChild( obj );
getViewerInstance().viewport().preciseFitDataToScreenBorder( { 0.9f } );
getViewerInstance().recentFilesStore().storeFile( directory );
if ( getAllObjectsInTree( obj.get() ).size() == 1 )
{
std::filesystem::path scenePath = directory;
scenePath += ".mru";
getViewerInstance().onSceneSaved( scenePath, false );
}

if ( !voxelObjects.empty() )
getViewerInstance().recentFilesStore().storeFile( directory );

if ( !errors.empty() )
showError( errors );
if ( !warnings.empty() )
pushNotification( { .text = warnings, .type = NotificationType::Warning } );
};
}
return [] ()
else
{
showError( "Cannot open given folder, find more in log." );
};
}, 2 );
return [error = loadRes.error()]
{
showError( error );
};
}
} );
}
#endif

Expand All @@ -418,7 +376,7 @@ void OpenDirectoryMenuItem::openDirectory( const std::filesystem::path& director
{
ProgressBar::orderWithMainThreadPostProcessing( "Open Directory", [directory] ()->std::function<void()>
{
if ( auto loadRes = makeObjectTreeFromFolder( directory, ProgressBar::callBackSetProgress ) )
if ( auto loadRes = makeObjectTreeFromFolder( directory, false, ProgressBar::callBackSetProgress ) )
{
return [obj = std::move( loadRes->obj ), directory, warnings = std::move( loadRes->warnings ) ]
{
Expand Down Expand Up @@ -454,7 +412,7 @@ bool OpenDICOMsMenuItem::action()
{
if ( directory.empty() )
return;
sOpenDICOMs( directory, "No DICOM files can be open from the directory:\n" + utf8string( directory ) );
sOpenDICOMs( directory );
} );
return false;
}
Expand Down
20 changes: 14 additions & 6 deletions source/MRViewer/MROpenObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
#include <MRMesh/MRParallelFor.h>
#include <fstream>
#include "MRPch/MRTBB.h"
#include "MRUnitSettings.h"

namespace MR
{


Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path & folder, const ProgressCallback& callback )
Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path & folder, bool dicomOnly, const ProgressCallback& callback )
{
MR_TIMER

Expand Down Expand Up @@ -122,8 +123,9 @@ Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path & f
createFolderObj( folder, pObj.get() );
}

for ( const FilePathNode& file : node.files )
nodes.push_back( { file, objPtr, cb.newTask() } );
if ( !dicomOnly )
for ( const FilePathNode& file : node.files )
nodes.push_back( { file, objPtr, cb.newTask() } );

#if !defined( MESHLIB_NO_VOXELS ) && !defined( MRVOXELS_NO_DICOM )
if ( node.dicomFolder )
Expand All @@ -141,9 +143,13 @@ Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path & f
tbb::task_group group;
std::atomic<int> completed;
bool loadingCanceled = false;
float dicomScaleFactor = 1.f;
if ( auto maybeUserScale = UnitSettings::getUiLengthUnit() )
dicomScaleFactor = getUnitInfo( LengthUnit::meters ).conversionFactor / getUnitInfo( *maybeUserScale ).conversionFactor;

for ( auto& nodeAndRes : nodes )
{
group.run( [&nodeAndRes, &completed] {
group.run( [&nodeAndRes, &completed, dicomScaleFactor] {
if ( !nodeAndRes.node.dicomFolder )
{
nodeAndRes.result = loadObjectFromFile( nodeAndRes.node.path, nodeAndRes.cb );
Expand All @@ -152,8 +158,10 @@ Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path & f
else
{
nodeAndRes.result = VoxelsLoad::makeObjectVoxelsFromDicomFolder( nodeAndRes.node.path, nodeAndRes.cb ).and_then(
[&]( LoadedObjectVoxels && ld ) -> loadObjResultType
[&, dicomScaleFactor]( LoadedObjectVoxels && ld ) -> loadObjResultType
{
// dicom is always opened in meters, and we can use this information to convert them properly
ld.obj->applyScale( dicomScaleFactor );
return LoadedObjects{ .objs = { ld.obj } };
} );
}
Expand Down Expand Up @@ -235,7 +243,7 @@ Expected<LoadedObject> makeObjectTreeFromZip( const std::filesystem::path& zipPa
if ( !resZip )
return unexpected( "ZIP container error: " + resZip.error() );

return makeObjectTreeFromFolder( contentsFolder, callback );
return makeObjectTreeFromFolder( contentsFolder, false, callback );
}

MR_ADD_SCENE_LOADER( IOFilter( "ZIP files (.zip)","*.zip" ), makeObjectTreeFromZip )
Expand Down
2 changes: 1 addition & 1 deletion source/MRViewer/MROpenObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace MR
{

/// load all supported files from given folder in new container object
MRVIEWER_API Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path& folder, const ProgressCallback& callback = {} );
MRVIEWER_API Expected<LoadedObject> makeObjectTreeFromFolder( const std::filesystem::path& folder, bool dicomOnly, const ProgressCallback& callback = {} );

/// load all supported files from given zip-archive in new container object
MRVIEWER_API Expected<LoadedObject> makeObjectTreeFromZip( const std::filesystem::path& zipPath, const ProgressCallback& callback = {} );
Expand Down