diff --git a/modules/dataloader/dataloadermodule.cpp b/modules/dataloader/dataloadermodule.cpp index 80ec3bc0f4..af7280b41c 100644 --- a/modules/dataloader/dataloadermodule.cpp +++ b/modules/dataloader/dataloadermodule.cpp @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +// #include + #include #include #include diff --git a/modules/dataloader/dataloadermodule_lua.inl b/modules/dataloader/dataloadermodule_lua.inl index c0134b3f17..67543cc91b 100644 --- a/modules/dataloader/dataloadermodule_lua.inl +++ b/modules/dataloader/dataloadermodule_lua.inl @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + namespace openspace::luascriptfunctions { /** @@ -34,7 +36,7 @@ int loadItem(lua_State* L) { using ghoul::lua::errorLocation; - const std::string path = ghoul::lua::checkStringAndPop(L); + const char* path = ghoul::lua::checkStringAndPop(L); /** handle path to check item type or handle it in different function **/ @@ -54,7 +56,7 @@ int uploadItem(lua_State* L) { using ghoul::lua::errorLocation; - const std::string dictionaryString = ghoul::lua::checkStringAndPop(L); + const char* dictionaryString = ghoul::lua::checkStringAndPop(L); OsEng.moduleEngine().module()->uploadDataItem(dictionaryString); ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack"); diff --git a/modules/dataloader/operators/loader.cpp b/modules/dataloader/operators/loader.cpp index f6cb3bc290..d6fd8eea8a 100644 --- a/modules/dataloader/operators/loader.cpp +++ b/modules/dataloader/operators/loader.cpp @@ -23,11 +23,14 @@ ****************************************************************************************/ #include -#include +#include +#include #include +#include #include #include #include +#include #include #include #include @@ -48,8 +51,15 @@ const std::string KeyRenderableType = "RenderableTimeVaryingVolume"; const std::string scaleTypeKey = "StaticScale"; const std::string translationTypeKey = "SpiceTranslation"; const std::string volumesGuiPathKey = "/Solar System/Volumes"; +const std::string KeyVolumeToRawTask = "KameleonVolumeToRawTask"; const bool guiHidden = false; + +const std::string testInput = "/home/jgrangien/Data/mas_merged_step_276.cdf"; +const std::string testVariable = "rho"; +const std::string testFactor = "true"; +const std::string testRawOutput = "/home/jgrangien/Data/test/mas.rawvolume"; +const std::string testDictOutput = "/home/jgrangien/Data/test/mas.dictionary"; } namespace { @@ -65,6 +75,12 @@ namespace { "If this property is triggered it will call the function to load data" }; + static const openspace::properties::Property::PropertyInfo VolumeConversionProgressInfo = { + "VolumeConversionProgress", + "Progress value for volume conversion", + "This float value between 0 and 1 corresponds to the progress of volume conversion" + }; + static const openspace::properties::Property::PropertyInfo UploadedDataDimensionsInfo = { "UploadedDataDimensions", "The Dimensions of an uploaded data set", @@ -107,6 +123,7 @@ Loader::Loader() : PropertyOwner({ "Loader" }) , _filePaths(SelectedFilesInfo) , _uploadDataTrigger(UploadDataTriggerInfo) + , _volumeConversionProgress(VolumeConversionProgressInfo) , _uploadedDataDimensions(UploadedDataDimensionsInfo) , _uploadedDataVariable(UploadedDataVariableInfo) , _uploadedDataFactorRSquared(UploadedDataFactorRSquaredInfo) @@ -119,6 +136,7 @@ Loader::Loader() addProperty(_filePaths); addProperty(_uploadDataTrigger); + addProperty(_volumeConversionProgress); addProperty(_uploadedDataDimensions); addProperty(_uploadedDataVariable); @@ -297,14 +315,28 @@ void Loader::processCurrentlySelectedUploadData(const std::string& dictionaryStr // Determine path to new volume item std::string itemPathBase = "${DATA}/.internal/volumes_from_cdf/"; - // Create dictionary with properties as values - // ghoul::Dictionary conversionDictionary = createTaskDictionaryForOneVolumeItem(_filePaths, itemPathBase); - ghoul::Dictionary dictionary = ghoul::lua::loadDictionaryFromString(dictionaryString); + _currentVolumeConversionDictionary = ghoul::lua::loadDictionaryFromString(dictionaryString); // Schedule tasks? How to loop through several CDF timesteps and run VolumeToRaw for each // Create instance of KameleonVolumeToRaw and run - // KameleonVolumeToRawTask kameleonVolumeToRawTask(conversionDictionary); - // kameleonVolumeToRawTask.perform(); + + { + std::thread t([&](){ + auto volumeToRawTask = Task::createFromDictionary(_currentVolumeConversionDictionary); + + std::mutex m; + const float e = 0.0003f; + std::function cb = [&](float progress) { + std::lock_guard g(m); + _volumeConversionProgress = progress; + }; + + volumeToRawTask->perform(cb); + LINFO("Conversion complete"); + }); + + t.detach(); + } // Create state file, transferfunction file in volume item directory } @@ -318,7 +350,7 @@ ghoul::Dictionary Loader::createTaskDictionaryForOneVolumeItem(std::string input // const int lowerDomainBound[3] = {1, -90, 0}; // const int upperDomainBound[3] = {15, 90, 360}; - // Set item dirLeaf as name + Set item dirLeaf as name const std::string itemName = openspace::dataloader::helpers::getDirLeaf(inputPath); const std::string itemOutputFilePath = outputBasePath + ghoul::filesystem::FileSystem::PathSeparator + @@ -347,3 +379,4 @@ ghoul::Dictionary Loader::createTaskDictionaryForOneVolumeItem(std::string input // } } + diff --git a/modules/dataloader/operators/loader.h b/modules/dataloader/operators/loader.h index 2a6658f3ed..c8d1c6f9ad 100644 --- a/modules/dataloader/operators/loader.h +++ b/modules/dataloader/operators/loader.h @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -76,6 +77,9 @@ class Loader : public PropertyOwner, public Operator { private: properties::StringProperty _filePaths; properties::TriggerProperty _uploadDataTrigger; + properties::FloatProperty _volumeConversionProgress; + + ghoul::Dictionary _currentVolumeConversionDictionary; // Volume specific. // Put in structs for different data types? Different file? diff --git a/modules/kameleonvolume/kameleonvolumereader.cpp b/modules/kameleonvolume/kameleonvolumereader.cpp index 937b0bd3d0..861a3ea222 100644 --- a/modules/kameleonvolume/kameleonvolumereader.cpp +++ b/modules/kameleonvolume/kameleonvolumereader.cpp @@ -148,6 +148,9 @@ std::unique_ptr> KameleonVolumeReader::readFloatVolume( }; float* data = volume->data(); + + size_t progressUpdateStep = volume->nCells() / 20; + for (size_t index = 0; index < volume->nCells(); ++index) { const glm::vec3 coords = volume->indexToCoords(index); const glm::vec3 coordsZeroToOne = coords / dims; @@ -159,12 +162,6 @@ std::unique_ptr> KameleonVolumeReader::readFloatVolume( continue; } - // Radius is within custom limit of exclusion, skip value - if (volumeCoords.x < innerRadialLimit) { - // std::cout << "Skipping radius " << volumeCoords.x << std::endl; - continue; - } - float value = !variable.empty() ? sample(volumeCoords) : sampleVectorVariablesLength(volumeCoords); // Multiply value by the squared first coordinate @@ -182,7 +179,7 @@ std::unique_ptr> KameleonVolumeReader::readFloatVolume( data[index] = value; - if (_readerCallback != nullptr) { + if (_readerCallback != nullptr && index % progressUpdateStep == 0) { (*_readerCallback)((float) index / volume->nCells()); } } diff --git a/modules/webgui/web/src/components/DataLoader/PrepareUploadedData.jsx b/modules/webgui/web/src/components/DataLoader/PrepareUploadedData.jsx index 9f70cc235a..18e0176de3 100644 --- a/modules/webgui/web/src/components/DataLoader/PrepareUploadedData.jsx +++ b/modules/webgui/web/src/components/DataLoader/PrepareUploadedData.jsx @@ -19,8 +19,9 @@ class PrepareUploadedData extends Component { super(props); this.state = { + volumeProgress: 0, activated: false, - dimensions: { x: 100, y: 100, z: 100 }, + dimensions: { x: 100, y: 100, z: 128 }, lowerDomainBounds: { r: 1, theta: -90, phi: 0 }, upperDomainBounds: { r: 15, theta: 90, phi: 360 }, variable: 'rho', @@ -33,6 +34,8 @@ class PrepareUploadedData extends Component { this.changeVariable = this.changeVariable.bind(this); this.changeRSquared = this.changeRSquared.bind(this); this.upload = this.upload.bind(this); + this.handleProgressValue = this.handleProgressValue.bind(this); + this.subscribeToVolumeConversionProgress = this.subscribeToVolumeConversionProgress.bind(this); } componentDidUpdate(prevProps, prevState) { @@ -41,6 +44,16 @@ class PrepareUploadedData extends Component { if( filePaths !== prevProps.filePaths && filePaths !== undefined ) { this.setState({ activated: true }); } + + this.subscribeToVolumeConversionProgress(); + } + + handleProgressValue(data) { + this.setState({volumeProgress: data.Value}); + } + + subscribeToVolumeConversionProgress() { + DataManager.subscribe('Modules.DataLoader.Loader.VolumeConversionProgress', this.handleProgressValue); } // TODO: Generalize the onChange function of OptionSelect! @@ -82,16 +95,20 @@ class PrepareUploadedData extends Component { const { dimensions, variable, lowerDomainBounds, upperDomainBounds, rSquared } = this.state; let data = `\' return { + Type="KameleonVolumeToRawTask", + Input="/home/jgrangien/Data/mas_merged_step_276.cdf", Dimensions={${dimensions.x}, ${dimensions.y}, ${dimensions.z}}, Variable="${variable.toLowerCase()}", LowerDomainBound={${lowerDomainBounds.x}, ${lowerDomainBounds.y}, ${lowerDomainBounds.z}}, UpperDomainBound={${upperDomainBounds.x}, ${upperDomainBounds.y}, ${upperDomainBounds.z}}, FactorRSquared="${rSquared}" + RawVolumeOutput="/home/jgrangien/Data/test/mas.rawvolume", + DictionaryOutput="/home/jgrangien/Data/test/mas.dictionary" } \'` data = removeLineBreakCharacters(data); - const script = UploadDataItemScript.replace(ValuePlaceholder, data); + DataManager.runScript(script); } @@ -101,11 +118,14 @@ class PrepareUploadedData extends Component { render() { const { width, height } = this.props; - const { dimensions, variable, lowerDomainBounds, upperDomainBounds } = this.state; + const { dimensions, variable, lowerDomainBounds, upperDomainBounds, volumeProgress } = this.state; + const size = { width: width / 2, height: height / 2 } + const progressPercent = Math.floor(volumeProgress * 100); + return(
{ this.state.activated && ( @@ -135,6 +155,11 @@ class PrepareUploadedData extends Component { label={'Factor R-Squared?'} onChange={this.changeRSquared}/> + +
+
+
+ )}