diff --git a/DVRTransferFunction/src/TransferFunctionPlugin.cpp b/DVRTransferFunction/src/TransferFunctionPlugin.cpp index 8e9e01c..1701dd7 100644 --- a/DVRTransferFunction/src/TransferFunctionPlugin.cpp +++ b/DVRTransferFunction/src/TransferFunctionPlugin.cpp @@ -136,8 +136,6 @@ TransferFunctionPlugin::TransferFunctionPlugin(const PluginFactory* factory) : return dropRegions; }); - auto& selectionAction = _settingsAction.getSelectionAction(); - getSamplerAction().setHtmlViewGeneratorFunction([this](const ViewPluginSamplerAction::SampleContext& toolTipContext) -> QString { QStringList localPointIndices, globalPointIndices; diff --git a/DVRVolumeLoader/src/DVRVolumeLoader.cpp b/DVRVolumeLoader/src/DVRVolumeLoader.cpp index 617a1e4..6c852c1 100644 --- a/DVRVolumeLoader/src/DVRVolumeLoader.cpp +++ b/DVRVolumeLoader/src/DVRVolumeLoader.cpp @@ -156,97 +156,112 @@ void DVRVolumeLoader::loadData() connect(inputDialog, &QDialog::accepted, this, [this, inputDialog]() -> void { - if (!inputDialog->getDatasetName().isEmpty()) { - auto sourceDataset = inputDialog->getSourceDataset(); - auto numDims = inputDialog->getNumberOfValueDimensions(); - auto storeAs = inputDialog->getStoreAs(); - - Dataset point_data; - - if (sourceDataset.isValid()) - point_data = mv::data().createDerivedDataset(inputDialog->getDatasetName(), sourceDataset); - else - point_data = mv::data().createDataset("Points", inputDialog->getDatasetName()); - - - Size3D volumeBoxSize = Size3D(inputDialog->getNumberOfDimensionsX(), inputDialog->getNumberOfDimensionsY(), inputDialog->getNumberOfDimensionsZ()); - int valueDimensions = inputDialog->getNumberOfValueDimensions(); - - if (inputDialog->getDatasetSource() == DatasetSource::PointDatasets) { - Dataset spatialDataset = inputDialog->getSpatialDataset(); - Dataset valueDataset = inputDialog->getValueDataset(); - - mv::Vector3f min = mv::Vector3f(FLT_MAX, FLT_MAX, FLT_MAX); - mv::Vector3f max = mv::Vector3f(FLT_MIN, FLT_MIN, FLT_MIN); - std::vector spatialPositions; - spatialDataset->visitData([&min, &max, &spatialPositions](auto pointData) { - for (const auto& point : pointData) - { - min.x = std::min(min.x, static_cast(point[0])); - min.y = std::min(min.y, static_cast(point[1])); - min.z = std::min(min.z, static_cast(point[2])); - max.x = std::max(max.x, static_cast(point[0])); - max.y = std::max(max.y, static_cast(point[1])); - max.z = std::max(max.z, static_cast(point[2])); - - for (auto& value : point) { - spatialPositions.push_back(value); - } + if (inputDialog->getDatasetName().isEmpty()) { + qWarning() << "DVRVolumeLoader::loadData: No dataset name provided."; + return; + } + + const auto parentDataset = inputDialog->getSourceDataset(); + const auto sourceType = inputDialog->getDatasetSource(); + const auto datasetName = inputDialog->getDatasetName(); + const auto numDims = inputDialog->getNumberOfValueDimensions(); + const auto storeAs = inputDialog->getStoreAs(); + const auto volumeBoxSize = Size3D(inputDialog->getNumberOfDimensionsX(), inputDialog->getNumberOfDimensionsY(), inputDialog->getNumberOfDimensionsZ()); + + auto createValuesDataset = [sourceType, &datasetName, &parentDataset]() -> Dataset + { + if (sourceType == DatasetSource::VolumePointDatasets) + return parentDataset; + + return parentDataset.isValid() + ? mv::data().createDerivedDataset(datasetName, parentDataset) + : mv::data().createDataset("Points", datasetName); + }; + + Dataset valuesDataset = createValuesDataset(); + + switch (inputDialog->getDatasetSource()) + { + case DatasetSource::ScatteredPointDatasets: { + Dataset spatialDataset = inputDialog->getSpatialDataset(); + Dataset valueDataset = inputDialog->getValueDataset(); + + mv::Vector3f min = mv::Vector3f(FLT_MAX, FLT_MAX, FLT_MAX); + mv::Vector3f max = mv::Vector3f(FLT_MIN, FLT_MIN, FLT_MIN); + std::vector spatialPositions; + spatialDataset->visitData([&min, &max, &spatialPositions](auto pointData) { + for (const auto& point : pointData) + { + min.x = std::min(min.x, static_cast(point[0])); + min.y = std::min(min.y, static_cast(point[1])); + min.z = std::min(min.z, static_cast(point[2])); + max.x = std::max(max.x, static_cast(point[0])); + max.y = std::max(max.y, static_cast(point[1])); + max.z = std::max(max.z, static_cast(point[2])); + + for (auto& value : point) { + spatialPositions.push_back(value); } + } }); - std::vector newDataset(volumeBoxSize.width() * volumeBoxSize.height() * volumeBoxSize.depth() * valueDimensions, 0.0f); - std::vector numValuesPlaced(volumeBoxSize.width() * volumeBoxSize.height() * volumeBoxSize.depth() * valueDimensions, 0.0f); - int i = 0; - valueDataset->visitData([this, &spatialPositions, &numValuesPlaced, &newDataset, &min, &max, &volumeBoxSize, &valueDimensions, &i](auto pointData) { - for (const auto& point : pointData) - { - mv::Vector3f normalizedPos = normalizePosition(mv::Vector3f(spatialPositions[i], spatialPositions[i + 1], spatialPositions[i + 2]), min, max, volumeBoxSize); - int x = int(std::round(normalizedPos.x)); - int y = int(std::round(normalizedPos.y)); - int z = int(std::round(normalizedPos.z)); - int voxelIndex = x + y * volumeBoxSize.width() + z * volumeBoxSize.width() * volumeBoxSize.height(); - //Populate the texture data with values - for (int j = 0; j < valueDimensions; ++j) { - newDataset[voxelIndex * valueDimensions + j] += point[j]; - numValuesPlaced[voxelIndex * valueDimensions + j] += 1; - } - i = i + 3; + std::vector newDataset(volumeBoxSize.width() * volumeBoxSize.height() * volumeBoxSize.depth() * numDims, 0.0f); + std::vector numValuesPlaced(volumeBoxSize.width() * volumeBoxSize.height() * volumeBoxSize.depth() * numDims, 0.0f); + int i = 0; + valueDataset->visitData([this, &spatialPositions, &numValuesPlaced, &newDataset, &min, &max, &volumeBoxSize, &numDims, &i](auto pointData) { + for (const auto& point : pointData) + { + const mv::Vector3f normalizedPos = normalizePosition(mv::Vector3f(spatialPositions[i], spatialPositions[i + 1], spatialPositions[i + 2]), min, max, volumeBoxSize); + const int x = static_cast(std::round(normalizedPos.x)); + const int y = static_cast(std::round(normalizedPos.y)); + const int z = static_cast(std::round(normalizedPos.z)); + const int voxelIndex = x + y * volumeBoxSize.width() + z * volumeBoxSize.width() * volumeBoxSize.height(); + //Populate the texture data with values + for (int j = 0; j < numDims; ++j) { + newDataset[voxelIndex * numDims + j] += point[j]; + numValuesPlaced[voxelIndex * numDims + j] += 1; } + i = i + 3; + } }); - for (size_t i = 0; i < numValuesPlaced.size(); ++i) { // Average the values - if(numValuesPlaced[i] != 0) { - newDataset[i] = newDataset[i] / numValuesPlaced[i]; - } + for (size_t i = 0; i < numValuesPlaced.size(); ++i) { // Average the values + if (numValuesPlaced[i] != 0) { + newDataset[i] = newDataset[i] / numValuesPlaced[i]; } - point_data->setData(newDataset, valueDimensions); } - else { + valuesDataset->setData(newDataset, numDims); - if (inputDialog->getDataType() == BinaryDataType::FLOAT) - { - recursiveReadDataAndAddToCore(storeAs, point_data, numDims, _contents); - } - else if (inputDialog->getDataType() == BinaryDataType::UBYTE) - { - recursiveReadDataAndAddToCore(storeAs, point_data, numDims, _contents); - } - else if (inputDialog->getDataType() == BinaryDataType::UINT16) - { - recursiveReadDataAndAddToCore(storeAs, point_data, numDims, _contents); - } + break; + } + case DatasetSource::File: { + if (inputDialog->getDataType() == BinaryDataType::FLOAT) { + recursiveReadDataAndAddToCore(storeAs, valuesDataset, numDims, _contents); + } + else if (inputDialog->getDataType() == BinaryDataType::UBYTE) { + recursiveReadDataAndAddToCore(storeAs, valuesDataset, numDims, _contents); } + else if (inputDialog->getDataType() == BinaryDataType::UINT16) { + recursiveReadDataAndAddToCore(storeAs, valuesDataset, numDims, _contents); + } + + break; + } + case DatasetSource::VolumePointDatasets: { + if (!parentDataset.isValid()) + qWarning() << "DVRVolumeLoader::loadData: Source data must be set for DatasetSource::VolumePointDatasets."; - //Create the Volumes dataset - auto volumeDataset = mv::data().createDataset("Volumes", inputDialog->getDatasetName(), point_data); + break; + } + } - volumeDataset->setVolumeSize(volumeBoxSize); - volumeDataset->setComponentsPerVoxel(valueDimensions); + // Create the Volumes dataset + _volumesDataset = mv::data().createDataset("Volumes", inputDialog->getDatasetName(), valuesDataset); - events().notifyDatasetDataChanged(volumeDataset); + _volumesDataset->setVolumeSize(volumeBoxSize); + _volumesDataset->setComponentsPerVoxel(numDims); + + events().notifyDatasetDataChanged(_volumesDataset); - _volumesDataset = volumeDataset; - } else { qWarning() << "DVRVolumeLoader::loadData: No dataset name provided."; } }); inputDialog->open(); @@ -302,7 +317,12 @@ DVRVolumeLoadingInputDialog::DVRVolumeLoadingInputDialog(QWidget* parent, DVRVol _fileLoadAction(this, "Load File"), _settingsGroupAction(this, "Settings"), _fileGroupAction(this, "File selection"), - _datasetGroupAction(this, "Dataset selection"), + _scatteredDataGroupAction(this, "Dataset (scat.) selection"), + _volumeDataGroupAction(this, "Dataset (vol.) selection"), + _fileRadioButton(new QRadioButton(tr("File"), this)), + _scatteredDataRadioButton(new QRadioButton(tr("Datasets (scat.)"), this)), + _volumeDataRadioButton(new QRadioButton(tr("Datasets (vol.)"), this)), + _dataSourceButtonGroup(new QButtonGroup(this)), _selectedWidget(nullptr) { setWindowTitle(tr("DVRVolume Loader")); @@ -338,12 +358,9 @@ DVRVolumeLoadingInputDialog::DVRVolumeLoadingInputDialog(QWidget* parent, DVRVol _settingsGroupAction.addAction(&_datasetNameAction); // Add radio buttons for dataset source selection - _fileRadioButton = new QRadioButton(tr("File"), this); - _pointDatasetsRadioButton = new QRadioButton(tr("Point Datasets"), this); - - _dataSourceButtonGroup = new QButtonGroup(this); _dataSourceButtonGroup->addButton(_fileRadioButton, DatasetSource::File); - _dataSourceButtonGroup->addButton(_pointDatasetsRadioButton, DatasetSource::PointDatasets); + _dataSourceButtonGroup->addButton(_scatteredDataRadioButton, DatasetSource::ScatteredPointDatasets); + _dataSourceButtonGroup->addButton(_volumeDataRadioButton, DatasetSource::VolumePointDatasets); _fileRadioButton->setChecked(true); // Default to None @@ -355,7 +372,8 @@ DVRVolumeLoadingInputDialog::DVRVolumeLoadingInputDialog(QWidget* parent, DVRVol auto buttonsLayout = new QHBoxLayout(); buttonsLayout->setContentsMargins(150, 0, 0, 0); buttonsLayout->addWidget(_fileRadioButton); - buttonsLayout->addWidget(_pointDatasetsRadioButton); + buttonsLayout->addWidget(_scatteredDataRadioButton); + buttonsLayout->addWidget(_volumeDataRadioButton); layout->addLayout(buttonsLayout); _fileGroupAction.addAction(&_fileLoadAction); @@ -365,9 +383,14 @@ DVRVolumeLoadingInputDialog::DVRVolumeLoadingInputDialog(QWidget* parent, DVRVol _spatialDatasetPickerAction.setDatasets(dataSets); _valueDatasetPickerAction.setDatasets(dataSets); - _datasetGroupAction.addAction(&_spatialDatasetPickerAction); - _datasetGroupAction.addAction(&_valueDatasetPickerAction); - _datasetGroupAction.addAction(&_acceptAction); + _scatteredDataGroupAction.addAction(&_spatialDatasetPickerAction); + _scatteredDataGroupAction.addAction(&_valueDatasetPickerAction); + _scatteredDataGroupAction.addAction(&_acceptAction); + + auto stringAction = new mv::gui::StringAction(this, "Info", "You must select a source dataset for this option!"); + stringAction->setDefaultWidgetFlags(mv::gui::StringAction::WidgetFlag::Label); + _volumeDataGroupAction.addAction(stringAction); + _volumeDataGroupAction.addAction(&_acceptAction); _selectedWidget = _fileGroupAction.createWidget(this); layout->addWidget(_selectedWidget); @@ -380,23 +403,40 @@ DVRVolumeLoadingInputDialog::DVRVolumeLoadingInputDialog(QWidget* parent, DVRVol //Update the selected widget when a radio button is clicked connect(_dataSourceButtonGroup, &QButtonGroup::buttonClicked, this, [this, layout]() -> void { - int id = _dataSourceButtonGroup->checkedId(); - _datasetSource = static_cast(id); + const int id = _dataSourceButtonGroup->checkedId(); + _datasetSource = static_cast(id); + if (_selectedWidget) { layout->removeWidget(_selectedWidget); _selectedWidget->deleteLater(); } - if (_datasetSource == DatasetSource::File) { + + bool enableAccept = true; + + switch (_datasetSource) + { + case DatasetSource::File: _selectedWidget = _fileGroupAction.createWidget(this); + break; + case DatasetSource::ScatteredPointDatasets: + _selectedWidget = _scatteredDataGroupAction.createWidget(this); + break; + case DatasetSource::VolumePointDatasets: + _selectedWidget = _volumeDataGroupAction.createWidget(this); + enableAccept = (_sourceDatasetPickerAction.getCurrentIndex() != -1); + + break; } - else if (_datasetSource == DatasetSource::PointDatasets) { - _selectedWidget = _datasetGroupAction.createWidget(this); - } + + _acceptAction.setEnabled(enableAccept); + layout->addWidget(_selectedWidget); layout->update(); }); - + connect(&_sourceDatasetPickerAction, &mv::gui::DatasetPickerAction::datasetPicked, this, [this](const Dataset<>&) { + _acceptAction.setEnabled(true); + }); // Update the state of the dataset picker const auto updateDatasetPicker = [this]() -> void { diff --git a/DVRVolumeLoader/src/DVRVolumeLoader.h b/DVRVolumeLoader/src/DVRVolumeLoader.h index 3b06db9..2ffc01b 100644 --- a/DVRVolumeLoader/src/DVRVolumeLoader.h +++ b/DVRVolumeLoader/src/DVRVolumeLoader.h @@ -30,7 +30,9 @@ enum BinaryDataType enum DatasetSource { - File, PointDatasets + File, + ScatteredPointDatasets, + VolumePointDatasets, }; class DVRVolumeLoadingInputDialog : public QDialog @@ -128,12 +130,14 @@ class DVRVolumeLoadingInputDialog : public QDialog mv::gui::TriggerAction _fileLoadAction; /** File action */ mv::gui::GroupAction _settingsGroupAction; /** Shared group action */ mv::gui::GroupAction _fileGroupAction; /** File specific group action */ - mv::gui::GroupAction _datasetGroupAction; /** Datasets specific group action */ + mv::gui::GroupAction _scatteredDataGroupAction; /** Datasets specific group action */ + mv::gui::GroupAction _volumeDataGroupAction; /** Datasets specific group action */ DatasetSource _datasetSource; /** Dataset source */ QRadioButton* _fileRadioButton; /** File radio button */ - QRadioButton* _pointDatasetsRadioButton; /** Point datasets radio button */ + QRadioButton* _scatteredDataRadioButton; /** Point dataset (scattered) radio button */ + QRadioButton* _volumeDataRadioButton; /** Point dataset (volume) radio button */ QButtonGroup* _dataSourceButtonGroup; /** Data source button group */ QWidget* _selectedWidget; /** File widget */