mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-17 17:31:10 -06:00
IswaGroup has own dataProcessor
This commit is contained in:
@@ -35,7 +35,7 @@ public:
|
||||
CygnetPlane(const ghoul::Dictionary& dictionary);
|
||||
~CygnetPlane();
|
||||
|
||||
private:
|
||||
protected:
|
||||
virtual bool createGeometry() override;
|
||||
virtual bool destroyGeometry() override;
|
||||
virtual void renderGeometry() override;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <modules/iswa/rendering/iswagroup.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "DataPlane";
|
||||
@@ -48,6 +49,7 @@ DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
|
||||
,_backgroundValues("backgroundValues", "Background Values", glm::vec2(0.0), glm::vec2(0), glm::vec2(1.0))
|
||||
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
|
||||
,_dataOptions("dataOptions", "Data Options")
|
||||
,_dataProcessor(nullptr)
|
||||
{
|
||||
std::string name;
|
||||
dictionary.getValue("Name", name);
|
||||
@@ -62,27 +64,35 @@ DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_transferFunctionsFile);
|
||||
addProperty(_dataOptions);
|
||||
|
||||
if(_data->groupName.empty()){
|
||||
_type = IswaManager::CygnetType::Data;
|
||||
|
||||
}
|
||||
|
||||
DataPlane::~DataPlane(){}
|
||||
|
||||
bool DataPlane::initialize(){
|
||||
IswaCygnet::initialize();
|
||||
|
||||
if(_group){
|
||||
std::cout << "add to group" << std::endl;
|
||||
_dataProcessor = _group->dataProcessor();
|
||||
}else{
|
||||
OsEng.gui()._iswa.registerProperty(&_useLog);
|
||||
OsEng.gui()._iswa.registerProperty(&_useHistogram);
|
||||
OsEng.gui()._iswa.registerProperty(&_normValues);
|
||||
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
|
||||
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
|
||||
OsEng.gui()._iswa.registerProperty(&_dataOptions);
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
}
|
||||
|
||||
setTransferFunctions(_transferFunctionsFile.value());
|
||||
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
|
||||
_normValues.onChange([this](){
|
||||
// FOR TESTING (should be done on all onChange)
|
||||
// _avgBenchmarkTime = 0.0;
|
||||
// _numOfBenchmarks = 0;
|
||||
_dataProcessor->normValues(_normValues.value());
|
||||
loadTexture();
|
||||
});
|
||||
@@ -103,12 +113,9 @@ DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
|
||||
setTransferFunctions(_transferFunctionsFile.value());
|
||||
});
|
||||
|
||||
_type = IswaManager::CygnetType::Data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DataPlane::~DataPlane(){}
|
||||
|
||||
void DataPlane::useLog(bool useLog){ _useLog.setValue(useLog); };
|
||||
void DataPlane::normValues(glm::vec2 normValues){ _normValues.setValue(normValues); };
|
||||
void DataPlane::useHistogram(bool useHistogram){ _useHistogram.setValue(useHistogram); };
|
||||
@@ -135,14 +142,15 @@ bool DataPlane::loadTexture() {
|
||||
|
||||
if(!_dataOptions.options().size()){ // load options for value selection
|
||||
fillOptions();
|
||||
_dataProcessor->addValues(_dataBuffer, _dataOptions);
|
||||
}
|
||||
|
||||
std::vector<float*> data = _dataProcessor->readData(_dataBuffer, _dataOptions);
|
||||
std::vector<float*> data = _dataProcessor->readData2(_dataBuffer, _dataOptions);
|
||||
|
||||
if(data.empty())
|
||||
return false;
|
||||
|
||||
_backgroundValues.setValue(_dataProcessor->filterValues());
|
||||
// _backgroundValues.setValue(_dataProcessor->filterValues());
|
||||
|
||||
bool texturesReady = false;
|
||||
std::vector<int> selectedOptions = _dataOptions.value();
|
||||
@@ -297,7 +305,7 @@ void DataPlane::fillOptions(){
|
||||
_textures.push_back(nullptr);
|
||||
}
|
||||
_dataOptions.setValue(std::vector<int>(1,0));
|
||||
if(!_data->groupName.empty())
|
||||
if(_group)
|
||||
IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options());
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ friend class IswaGroup;
|
||||
DataPlane(const ghoul::Dictionary& dictionary);
|
||||
~DataPlane();
|
||||
|
||||
bool initialize() override;
|
||||
|
||||
protected:
|
||||
virtual void useLog(bool useLog) override;
|
||||
virtual void normValues(glm::vec2 normValues) override;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <modules/base/rendering/planetgeometry.h>
|
||||
#include <fstream>
|
||||
#include <modules/iswa/rendering/iswagroup.h>
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -57,30 +58,37 @@ DataSphere::DataSphere(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_transferFunctionsFile);
|
||||
addProperty(_dataOptions);
|
||||
|
||||
if(_data->groupName.empty()){
|
||||
_type = IswaManager::CygnetType::Data;
|
||||
}
|
||||
|
||||
DataSphere::~DataSphere(){}
|
||||
|
||||
bool DataSphere::initialize(){
|
||||
IswaCygnet::initialize();
|
||||
|
||||
if(_group){
|
||||
_dataProcessor = _group->dataProcessor();
|
||||
}else{
|
||||
OsEng.gui()._iswa.registerProperty(&_useLog);
|
||||
OsEng.gui()._iswa.registerProperty(&_useHistogram);
|
||||
OsEng.gui()._iswa.registerProperty(&_normValues);
|
||||
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
|
||||
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
|
||||
OsEng.gui()._iswa.registerProperty(&_dataOptions);
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
}
|
||||
|
||||
setTransferFunctions(_transferFunctionsFile.value());
|
||||
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
|
||||
_normValues.onChange([this](){
|
||||
// FOR TESTING (should be done on all onChange)
|
||||
// _avgBenchmarkTime = 0.0;
|
||||
// _numOfBenchmarks = 0;
|
||||
_dataProcessor->normValues(_normValues.value());
|
||||
loadTexture();
|
||||
});
|
||||
|
||||
_useLog.onChange([this](){
|
||||
_dataProcessor->useLog(_useLog.value());
|
||||
loadTexture();
|
||||
@@ -97,14 +105,9 @@ DataSphere::DataSphere(const ghoul::Dictionary& dictionary)
|
||||
setTransferFunctions(_transferFunctionsFile.value());
|
||||
});
|
||||
|
||||
|
||||
_type = IswaManager::CygnetType::Data;
|
||||
_dataBuffer = "";
|
||||
//_data->frame = "SM";
|
||||
return true;
|
||||
}
|
||||
|
||||
DataSphere::~DataSphere(){}
|
||||
|
||||
void DataSphere::useLog(bool useLog){ _useLog.setValue(useLog); };
|
||||
void DataSphere::normValues(glm::vec2 normValues){ _normValues.setValue(normValues); };
|
||||
void DataSphere::useHistogram(bool useHistogram){ _useHistogram.setValue(useHistogram); };
|
||||
@@ -131,9 +134,10 @@ bool DataSphere::loadTexture(){
|
||||
|
||||
if(!_dataOptions.options().size()){ // load options for value selection
|
||||
fillOptions();
|
||||
_dataProcessor->addValuesFromJSON(_dataBuffer, _dataOptions);
|
||||
}
|
||||
|
||||
std::vector<float*> data = _dataProcessor->readJSONData(_dataBuffer, _dataOptions);
|
||||
std::vector<float*> data = _dataProcessor->readJSONData2(_dataBuffer, _dataOptions);
|
||||
|
||||
if(data.empty())
|
||||
return false;
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
DataSphere(const ghoul::Dictionary& dictionary);
|
||||
~DataSphere();
|
||||
|
||||
bool initialize() override;
|
||||
|
||||
protected:
|
||||
virtual void useLog(bool useLog) override;
|
||||
virtual void normValues(glm::vec2 normValues) override;
|
||||
|
||||
@@ -37,6 +37,7 @@ IswaCygnet::IswaCygnet(const ghoul::Dictionary& dictionary)
|
||||
, _delete("delete", "Delete")
|
||||
, _shader(nullptr)
|
||||
,_type(IswaManager::CygnetType::NoType)
|
||||
,_group(nullptr)
|
||||
{
|
||||
_data = std::make_shared<Metadata>();
|
||||
|
||||
@@ -101,19 +102,23 @@ IswaCygnet::IswaCygnet(const ghoul::Dictionary& dictionary)
|
||||
_delete.onChange([this](){
|
||||
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + name() + "')");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
IswaCygnet::~IswaCygnet(){}
|
||||
bool IswaCygnet::initialize(){
|
||||
_textures.push_back(nullptr);
|
||||
|
||||
if(!_data->groupName.empty()){
|
||||
_group = IswaManager::ref().registerToGroup(_data->groupName, _type, this);
|
||||
std::cout << "Register group " << (_group != nullptr) << std::endl;
|
||||
}
|
||||
|
||||
initializeTime();
|
||||
createGeometry();
|
||||
createShader();
|
||||
updateTexture();
|
||||
|
||||
if(!_data->groupName.empty())
|
||||
IswaManager::ref().registerToGroup(_data->groupName, _type, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@ protected:
|
||||
std::vector<std::shared_ptr<TransferFunction>> _transferFunctions;
|
||||
std::future<DownloadManager::MemoryFile> _futureObject;
|
||||
|
||||
std::shared_ptr<IswaGroup> _group;
|
||||
|
||||
IswaManager::CygnetType _type;
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ IswaGroup::IswaGroup(std::string name)
|
||||
,_dataOptions("dataOptions", "Data Options")
|
||||
// ,_id(id)
|
||||
,_type(IswaManager::CygnetType::NoType)
|
||||
// ,_dataProcessor(nullptr)
|
||||
{
|
||||
setName(name);
|
||||
|
||||
@@ -54,6 +55,12 @@ IswaGroup::IswaGroup(std::string name)
|
||||
addProperty(_dataOptions);
|
||||
|
||||
addProperty(_delete);
|
||||
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
}
|
||||
|
||||
IswaGroup::~IswaGroup(){
|
||||
@@ -103,7 +110,13 @@ void IswaGroup::registerOptions(const std::vector<properties::SelectionProperty:
|
||||
if(_type == IswaManager::CygnetType::Data){
|
||||
if(_dataOptions.options().empty()){
|
||||
for(auto option : options){
|
||||
_dataOptions.addOption(option);
|
||||
|
||||
std::stringstream memorystream(option.description);
|
||||
std::string optionName;
|
||||
getline(memorystream, optionName, '/');
|
||||
getline(memorystream, optionName, '/');
|
||||
|
||||
_dataOptions.addOption({option.value, name()+"/"+optionName});
|
||||
}
|
||||
_dataOptions.setValue(std::vector<int>(1,0));
|
||||
}
|
||||
@@ -187,4 +200,8 @@ void IswaGroup::clearGroup(){
|
||||
unregisterProperties();
|
||||
}
|
||||
|
||||
std::shared_ptr<DataProcessor> IswaGroup::dataProcessor(){
|
||||
return _dataProcessor;
|
||||
}
|
||||
|
||||
} //namespace openspace
|
||||
@@ -33,6 +33,7 @@
|
||||
// #include <modules/iswa/rendering/iswacygnet.h>
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
#include <modules/iswa/util/iswamanager.h>
|
||||
#include <modules/iswa/util/dataprocessor.h>
|
||||
|
||||
|
||||
namespace openspace{
|
||||
@@ -47,6 +48,15 @@ public:
|
||||
void registerOptions(const std::vector<properties::SelectionProperty::Option>& options);
|
||||
bool checkType(IswaManager::CygnetType type);
|
||||
void clearGroup();
|
||||
|
||||
std::shared_ptr<DataProcessor> dataProcessor();
|
||||
|
||||
// bool useLog(){return _useLog.value();};
|
||||
// glm::vec2 normValues(){return _normValues.value();};
|
||||
// bool useHistogram(){return _useHistogram.value();};
|
||||
// std::vector<int> dataOptions(){return _dataOptions.value();};
|
||||
// std::string transferFunctionsFile(){return _transferFunctionsFile.value();};
|
||||
// glm::vec2 backgroundValues(){return _backgroundValues.value();};
|
||||
private:
|
||||
void registerProperties();
|
||||
void unregisterProperties();
|
||||
@@ -69,6 +79,8 @@ private:
|
||||
// int groupId;
|
||||
// IswaCygnet cygnet;
|
||||
int _id;
|
||||
|
||||
std::shared_ptr<DataProcessor> _dataProcessor;
|
||||
std::vector<IswaCygnet* > _cygnets;
|
||||
IswaManager::CygnetType _type;
|
||||
};
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <fstream>
|
||||
#include <modules/iswa/ext/json/json.hpp>
|
||||
#include <modules/iswa/rendering/iswagroup.h>
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -55,7 +56,7 @@ KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
|
||||
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
|
||||
,_dataOptions("dataOptions", "Data Options")
|
||||
,_fieldlines("fieldlineSeedsIndexFile", "Fieldline Seedpoints")
|
||||
,_resolution("resolution", "Resolutionx100", 2, 1, 5)
|
||||
,_resolution("resolution", "Resolutionx100", 1, 1, 5)
|
||||
,_slice("slice", "Slice", 0.0, 0.0, 1.0)
|
||||
{
|
||||
std::string name;
|
||||
@@ -74,26 +75,80 @@ KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_dataOptions);
|
||||
addProperty(_fieldlines);
|
||||
|
||||
if(_data->groupName.empty()){
|
||||
|
||||
_type = IswaManager::CygnetType::Data;
|
||||
|
||||
dictionary.getValue("kwPath", _kwPath);
|
||||
|
||||
std::string fieldlineIndexFile;
|
||||
dictionary.getValue("fieldlineSeedsIndexFile", fieldlineIndexFile);
|
||||
readFieldlinePaths(absPath(fieldlineIndexFile));
|
||||
|
||||
_fieldlines.onChange([this](){ updateFieldlineSeeds();} );
|
||||
|
||||
std::string axis;
|
||||
dictionary.getValue("axisCut", axis);
|
||||
|
||||
OsEng.gui()._iswa.registerProperty(&_slice);
|
||||
if(axis == "x"){
|
||||
_scale = _data->scale.x;
|
||||
_data->scale.x = 0;
|
||||
_data->offset.x = 0;
|
||||
|
||||
_slice.setValue((_data->offset.x - _data->gridMin.x)/_scale);
|
||||
}else if(axis == "y"){
|
||||
_scale = _data->scale.y;
|
||||
_data->scale.y = 0;
|
||||
_data->offset.y = 0;
|
||||
|
||||
_slice.setValue((_data->offset.y -_data->gridMin.y)/_scale);
|
||||
}else{
|
||||
_scale = _data->scale.z;
|
||||
_data->scale.z = 0;
|
||||
_data->offset.z = 0;
|
||||
|
||||
_slice.setValue((_data->offset.z - _data->gridMin.z)/_scale);
|
||||
}
|
||||
}
|
||||
|
||||
KameleonPlane::~KameleonPlane(){
|
||||
_kw = nullptr;
|
||||
}
|
||||
|
||||
bool KameleonPlane::initialize(){
|
||||
_textures.push_back(nullptr);
|
||||
|
||||
if(!_data->groupName.empty()){
|
||||
_group = IswaManager::ref().registerToGroup(_data->groupName, _type, this);
|
||||
std::cout << "Register group " << (_group != nullptr) << std::endl;
|
||||
}
|
||||
|
||||
initializeTime();
|
||||
createGeometry();
|
||||
createShader();
|
||||
|
||||
|
||||
if(_group){
|
||||
_dataProcessor = _group->dataProcessor();
|
||||
}else{
|
||||
OsEng.gui()._iswa.registerProperty(&_useLog);
|
||||
OsEng.gui()._iswa.registerProperty(&_useHistogram);
|
||||
OsEng.gui()._iswa.registerProperty(&_normValues);
|
||||
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
|
||||
OsEng.gui()._iswa.registerProperty(&_resolution);
|
||||
OsEng.gui()._iswa.registerProperty(&_slice);
|
||||
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
|
||||
OsEng.gui()._iswa.registerProperty(&_dataOptions);
|
||||
OsEng.gui()._iswa.registerProperty(&_fieldlines);
|
||||
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
setTransferFunctions(_transferFunctionsFile.value());
|
||||
|
||||
_dataProcessor = std::make_shared<DataProcessor>(
|
||||
_useLog.value(),
|
||||
_useHistogram.value(),
|
||||
_normValues
|
||||
);
|
||||
|
||||
_normValues.onChange([this](){
|
||||
_dataProcessor->normValues(_normValues.value());
|
||||
loadTexture();
|
||||
@@ -114,52 +169,27 @@ KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
|
||||
});
|
||||
|
||||
_resolution.onChange([this](){
|
||||
_dataProcessor->clear();
|
||||
updateTexture();
|
||||
});
|
||||
|
||||
_type = IswaManager::CygnetType::Data;
|
||||
|
||||
dictionary.getValue("kwPath", _kwPath);
|
||||
|
||||
std::string fieldlineIndexFile;
|
||||
dictionary.getValue("fieldlineSeedsIndexFile", fieldlineIndexFile);
|
||||
readFieldlinePaths(absPath(fieldlineIndexFile));
|
||||
|
||||
_fieldlines.onChange([this](){ updateFieldlineSeeds();} );
|
||||
|
||||
std::string axis;
|
||||
dictionary.getValue("axisCut", axis);
|
||||
|
||||
if(axis == "x"){
|
||||
_scale = _data->scale.x;
|
||||
_data->scale.x = 0;
|
||||
_data->offset.x = 0;
|
||||
|
||||
_slice.setValue((_data->offset.x - _data->gridMin.x)/_scale);
|
||||
}else if(axis == "y"){
|
||||
_scale = _data->scale.y;
|
||||
_data->scale.y = 0;
|
||||
_data->offset.y = 0;
|
||||
|
||||
_slice.setValue((_data->offset.y -_data->gridMin.y)/_scale);
|
||||
}else{
|
||||
_scale = _data->scale.z;
|
||||
_data->scale.z = 0;
|
||||
_data->offset.z = 0;
|
||||
|
||||
_slice.setValue((_data->offset.z - _data->gridMin.z)/_scale);
|
||||
}
|
||||
|
||||
_slice.onChange([this](){
|
||||
updateTexture();
|
||||
});
|
||||
|
||||
updateTexture();
|
||||
}
|
||||
|
||||
KameleonPlane::~KameleonPlane(){
|
||||
_kw = nullptr;
|
||||
}
|
||||
void KameleonPlane::useLog(bool useLog){ _useLog.setValue(useLog); };
|
||||
void KameleonPlane::normValues(glm::vec2 normValues){ _normValues.setValue(normValues); };
|
||||
void KameleonPlane::useHistogram(bool useHistogram){ _useHistogram.setValue(useHistogram); };
|
||||
void KameleonPlane::dataOptions(std::vector<int> options){ _dataOptions.setValue(options); };
|
||||
void KameleonPlane::transferFunctionsFile(std::string tfPath){ _transferFunctionsFile.setValue(tfPath); };
|
||||
void KameleonPlane::backgroundValues(glm::vec2 backgroundValues){ _backgroundValues.setValue(backgroundValues); };
|
||||
|
||||
bool KameleonPlane::loadTexture() {
|
||||
std::cout << "loadTexture()" << std::endl;
|
||||
|
||||
ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear;
|
||||
ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge;
|
||||
|
||||
@@ -169,13 +199,18 @@ bool KameleonPlane::loadTexture() {
|
||||
|
||||
for(int option : selectedOptions){
|
||||
if(!_dataSlices[option]){
|
||||
std::cout << options[option].description << std::endl;
|
||||
_dataSlices[option] = _kw->getUniformSliceValues(options[option].description, _dimensions, _slice.value());
|
||||
|
||||
std::stringstream memorystream(options[option].description);
|
||||
std::string optionName;
|
||||
getline(memorystream, optionName, '/');
|
||||
getline(memorystream, optionName, '/');
|
||||
// std::cout << options[option].description << std::endl;
|
||||
_dataSlices[option] = _kw->getUniformSliceValues(optionName, _dimensions, _slice.value());
|
||||
_dataProcessor->addValuesFromKameleonData(_dataSlices[option], _dimensions, options.size(), option);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<float*> data = _dataProcessor->processKameleonData(_dataSlices, _dimensions, _dataOptions);
|
||||
std::vector<float*> data = _dataProcessor->processKameleonData2(_dataSlices, _dimensions, _dataOptions);
|
||||
|
||||
if(data.empty())
|
||||
return false;
|
||||
@@ -261,8 +296,6 @@ bool KameleonPlane::updateTexture(){
|
||||
_textures[i] = std::move(nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loadTexture();
|
||||
|
||||
return true;
|
||||
@@ -366,16 +399,16 @@ void KameleonPlane::fillOptions(){
|
||||
|
||||
for(std::string option : options){
|
||||
if(option.size() < 4 && option != "x" && option != "y" && option != "z"){
|
||||
_dataOptions.addOption({numOptions, option});
|
||||
_dataOptions.addOption({numOptions, name()+"/"+option});
|
||||
_dataSlices.push_back(nullptr);
|
||||
_textures.push_back(nullptr);
|
||||
numOptions++;
|
||||
}
|
||||
}
|
||||
_dataOptions.setValue(std::vector<int>(1,0));
|
||||
_dataOptions.onChange([this](){loadTexture();});
|
||||
if(!_data->groupName.empty())
|
||||
if(_group)
|
||||
IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options());
|
||||
_dataOptions.onChange([this](){loadTexture();});
|
||||
}
|
||||
|
||||
void KameleonPlane::updateFieldlineSeeds(){
|
||||
|
||||
@@ -38,6 +38,16 @@
|
||||
KameleonPlane(const ghoul::Dictionary& dictionary);
|
||||
~KameleonPlane();
|
||||
|
||||
bool initialize() override;
|
||||
|
||||
protected:
|
||||
virtual void useLog(bool useLog) override;
|
||||
virtual void normValues(glm::vec2 normValues) override;
|
||||
virtual void useHistogram(bool useHistogram) override;
|
||||
virtual void dataOptions(std::vector<int> options) override;
|
||||
virtual void transferFunctionsFile(std::string tfPath) override;
|
||||
virtual void backgroundValues(glm::vec2 backgroundValues) override;
|
||||
|
||||
private:
|
||||
virtual bool loadTexture() override;
|
||||
virtual bool updateTexture() override;
|
||||
|
||||
@@ -48,6 +48,7 @@ DataProcessor::DataProcessor(bool useLog, bool useHistogram, glm::vec2 normValue
|
||||
,_useHistogram(useHistogram)
|
||||
,_normValues(normValues)
|
||||
,_filterValues(glm::vec2(0))
|
||||
,_numValues(0)
|
||||
{
|
||||
_coordinateVariables = {"x", "y", "z", "phi", "theta"};
|
||||
};
|
||||
@@ -115,11 +116,67 @@ std::vector<std::string> DataProcessor::readJSONHeader(std::string& dataBuffer){
|
||||
return options;
|
||||
}
|
||||
|
||||
void DataProcessor::addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions){
|
||||
int numOptions = dataOptions.options().size();
|
||||
|
||||
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
|
||||
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
|
||||
if(_sum.empty()) _sum = std::vector<float>(numOptions, 0.0f);
|
||||
if(_sd.empty()) _sd = std::vector<float>(numOptions, 0.0f);
|
||||
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
|
||||
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
|
||||
|
||||
if(!dataBuffer.empty()){
|
||||
|
||||
std::stringstream memorystream(dataBuffer);
|
||||
std::string line;
|
||||
std::vector<float> sum(numOptions, 0.0f);
|
||||
std::vector<std::vector<float>> values(numOptions, std::vector<float>());
|
||||
|
||||
int numValues = 0;
|
||||
while(getline(memorystream, line)){
|
||||
if(line.find("#") == 0) continue;
|
||||
|
||||
std::stringstream ss(line);
|
||||
std::vector<float> value;
|
||||
float v;
|
||||
while(ss >> v){
|
||||
value.push_back(v);
|
||||
}
|
||||
|
||||
if(value.size()){
|
||||
for(int i=0; i<numOptions; i++){
|
||||
float v = value[i+3];
|
||||
|
||||
values[i].push_back(v);
|
||||
_min[i] = std::min(_min[i], v);
|
||||
_max[i] = std::max(_max[i], v);
|
||||
sum[i] += v;
|
||||
}
|
||||
numValues++;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<numOptions; i++){
|
||||
float mean = (1.0/numValues)*sum[i];
|
||||
float var = 0;
|
||||
for(int j=0; j<numValues; j++){
|
||||
var += pow(values[i][j] - mean, 2);
|
||||
}
|
||||
float sd = sqrt(var / numValues);
|
||||
|
||||
_sum[i] += sum[i];
|
||||
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
|
||||
_numValues[i] += numValues;
|
||||
std::cout << i << " " << _numValues[i] << " " << _sum[i] << " " << _sd[i] << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<float*> DataProcessor::readData(std::string& dataBuffer, properties::SelectionProperty dataOptions){
|
||||
if(!dataBuffer.empty()){
|
||||
// if(!_dataOptions.options().size()) // load options for value selection
|
||||
// readHeader(dataBuffer);
|
||||
|
||||
std::stringstream memorystream(dataBuffer);
|
||||
std::string line;
|
||||
|
||||
@@ -207,18 +264,61 @@ std::vector<float*> DataProcessor::readData(std::string& dataBuffer, properties:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<float*> DataProcessor::readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){
|
||||
if(!dataBuffer.empty()){
|
||||
std::stringstream memorystream(dataBuffer);
|
||||
std::string line;
|
||||
|
||||
std::vector<int> selectedOptions = dataOptions.value();
|
||||
int numSelected = selectedOptions.size();
|
||||
|
||||
std::vector<std::vector<float>> values(selectedOptions.size(), std::vector<float>());
|
||||
std::vector<float*> data(dataOptions.options().size(), nullptr);
|
||||
|
||||
for(int option : selectedOptions){
|
||||
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
|
||||
}
|
||||
|
||||
int numValues = 0;
|
||||
while(getline(memorystream, line)){
|
||||
if(line.find("#") == 0){ //part of the header
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream ss(line);
|
||||
std::vector<float> value;
|
||||
float v;
|
||||
while(ss >> v){
|
||||
value.push_back(v);
|
||||
}
|
||||
|
||||
if(value.size()){
|
||||
for(int option : selectedOptions){
|
||||
float v = value[option+3]; //+3 because "options" x, y and z.
|
||||
data[option][numValues] = processDataPoint(v, option);
|
||||
}
|
||||
}
|
||||
numValues++;
|
||||
}
|
||||
|
||||
if(numValues != _dimensions.x*_dimensions.y){
|
||||
LWARNING("Number of values read and expected are not the same");
|
||||
return std::vector<float*>();
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}else{
|
||||
return std::vector<float*>();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions){
|
||||
if(!dataBuffer.empty()){
|
||||
json j = json::parse(dataBuffer);
|
||||
json var = j["variables"];
|
||||
|
||||
|
||||
// if(!_dataOptions.options().size()) // load options for value selection
|
||||
// readHeader(dataBuffer);
|
||||
|
||||
// std::stringstream memorystream(dataBuffer);
|
||||
// std::string line;
|
||||
|
||||
std::vector<int> selectedOptions = dataOptions.value();
|
||||
int numSelected = selectedOptions.size();
|
||||
|
||||
@@ -262,7 +362,6 @@ std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, propert
|
||||
|
||||
sum[i] += v;
|
||||
}
|
||||
// break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -279,23 +378,210 @@ std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, propert
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
|
||||
void DataProcessor::addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions){
|
||||
int numOptions = dataOptions.options().size();
|
||||
|
||||
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
|
||||
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
|
||||
if(_sum.empty()) _sum = std::vector<float>(numOptions, 0.0f);
|
||||
if(_sd.empty()) _sd = std::vector<float>(numOptions, 0.0f);
|
||||
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
|
||||
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
|
||||
|
||||
|
||||
if(!dataBuffer.empty()){
|
||||
json j = json::parse(dataBuffer);
|
||||
json var = j["variables"];
|
||||
|
||||
std::vector<int> selectedOptions = dataOptions.value();
|
||||
int numSelected = selectedOptions.size();
|
||||
std::vector<float> sum(numOptions, 0.0f);
|
||||
|
||||
std::vector<std::vector<float>> values(numOptions, std::vector<float>());
|
||||
auto options = dataOptions.options();
|
||||
std::vector<float*> data(options.size(), nullptr);
|
||||
int i = 0;
|
||||
|
||||
for(int i=0; i<numOptions; i++){
|
||||
std::stringstream memorystream(options[i].description);
|
||||
std::string optionName;
|
||||
getline(memorystream, optionName, '/');
|
||||
getline(memorystream, optionName, '/');
|
||||
|
||||
json valueArray = var[optionName];
|
||||
int ySize = valueArray.size();
|
||||
|
||||
for(int y=0; y<valueArray.size(); y++){
|
||||
json value = valueArray.at(y);
|
||||
for(int x=0; x<value.size(); x++){
|
||||
|
||||
float v = value.at(x);
|
||||
values[i].push_back(v);
|
||||
|
||||
_min[i] = std::min(_min[i],v);
|
||||
_max[i] = std::min(_max[i],v);
|
||||
sum[i] += v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<numOptions; i++){
|
||||
int numValues = values[i].size();
|
||||
float mean = (1.0/numValues)*sum[i];
|
||||
|
||||
float var = 0;
|
||||
for(int j=0; j<numValues; j++){
|
||||
var += pow(values[i][j] - mean, 2);
|
||||
}
|
||||
float sd = sqrt(var / numValues);
|
||||
|
||||
_sum[i] += sum[i];
|
||||
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
|
||||
_numValues[i] += numValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<float*> DataProcessor::readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){
|
||||
if(!dataBuffer.empty()){
|
||||
json j = json::parse(dataBuffer);
|
||||
json var = j["variables"];
|
||||
|
||||
std::vector<int> selectedOptions = dataOptions.value();
|
||||
int numSelected = selectedOptions.size();
|
||||
|
||||
std::vector<float> sum(numSelected, 0.0f);
|
||||
std::vector<std::vector<float>> values(numSelected, std::vector<float>());
|
||||
auto options = dataOptions.options();
|
||||
|
||||
std::vector<float*> data(options.size(), nullptr);
|
||||
for(int option : selectedOptions){
|
||||
|
||||
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
|
||||
|
||||
std::stringstream memorystream(options[option].description);
|
||||
std::string optionName;
|
||||
getline(memorystream, optionName, '/');
|
||||
getline(memorystream, optionName, '/');
|
||||
|
||||
json yArray = var[optionName];
|
||||
for(int y=0; y<yArray.size(); y++){
|
||||
json xArray = yArray.at(y);
|
||||
for(int x=0; x<xArray.size(); x++){
|
||||
|
||||
int i = x + y*xArray.size();
|
||||
// std::cout << _dimensions.x*_dimensions.y << " " << i << std::endl;
|
||||
float v = xArray.at(x);
|
||||
data[option][i] = processDataPoint(v, option);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
// LWARNING("Nothing in memory buffer, are you connected to the information super highway?");
|
||||
return std::vector<float*>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option){
|
||||
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
|
||||
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
|
||||
if(_sum.empty()) _sum= std::vector<float>(numOptions, 0.0f);
|
||||
if(_sd.empty()) _sd= std::vector<float>(numOptions, 0.0f);
|
||||
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
|
||||
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
|
||||
|
||||
|
||||
int numValues = dimensions.x*dimensions.y*dimensions.z;
|
||||
float sum = 0;
|
||||
|
||||
for(int i=0; i<numValues; i++){
|
||||
float v = kdata[i];
|
||||
_min[option] = std::min(_min[option],v);
|
||||
_max[option] = std::max(_max[option],v);
|
||||
sum += v;
|
||||
}
|
||||
|
||||
float mean = (1.0 / numValues) * sum;
|
||||
float var = 0;
|
||||
for(int i=0; i<numValues; i++){
|
||||
var += pow(kdata[i] - mean, 2);
|
||||
}
|
||||
float sd = sqrt ( var / numValues );
|
||||
|
||||
_sum[option] += sum;
|
||||
_sd[option] = sqrt(pow(_sd[option],2)+ pow(sd,2));
|
||||
_numValues[option] += numValues;
|
||||
}
|
||||
|
||||
std::vector<float*> DataProcessor::processKameleonData2(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
|
||||
std::vector<int> selectedOptions = dataOptions.value();
|
||||
int numSelected = selectedOptions.size();
|
||||
|
||||
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
|
||||
std::vector<std::vector<float>> values(selectedOptions.size(), std::vector<float>());
|
||||
std::vector<float*> data(dataOptions.options().size(), nullptr);
|
||||
int numValues = dimensions.x*dimensions.y*dimensions.z;
|
||||
|
||||
for(int option : selectedOptions){
|
||||
data[option] = new float[numValues]{0.0f};
|
||||
|
||||
for(int i=0; i<numValues; i++){
|
||||
float v = kdata[option][i];
|
||||
data[option][i] = processDataPoint(v, option);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
|
||||
std::vector<int> selectedOptions = dataOptions.value();
|
||||
int numSelected = selectedOptions.size();
|
||||
auto options = dataOptions.options();
|
||||
int numOptions = options.size();
|
||||
|
||||
if(_min.empty()){
|
||||
_min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
|
||||
}
|
||||
|
||||
if(_max.empty()){
|
||||
_max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
|
||||
}
|
||||
|
||||
if(_sum.empty()){
|
||||
_sum= std::vector<float>(numOptions, 0.0f);
|
||||
}
|
||||
|
||||
if(_sd.empty()){
|
||||
_sd= std::vector<float>(numOptions, 0.0f);
|
||||
}
|
||||
|
||||
if(_histograms.empty()){
|
||||
_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
|
||||
}
|
||||
|
||||
|
||||
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
|
||||
std::vector<float> max(numSelected, std::numeric_limits<float>::min());
|
||||
|
||||
std::vector<float> sum(numSelected, 0.0f);
|
||||
std::vector<std::vector<float>> optionValues(numSelected, std::vector<float>());
|
||||
|
||||
auto options = dataOptions.options();
|
||||
|
||||
std::vector<float*> data(options.size(), nullptr);
|
||||
int numValues = dimensions.x*dimensions.y*dimensions.z;
|
||||
int i = 0;
|
||||
|
||||
for(int option : selectedOptions){
|
||||
bool calculateMin = (_min[option] == std::numeric_limits<float>::max());
|
||||
bool calculateMax = (_max[option] == std::numeric_limits<float>::min());
|
||||
bool claculateSum = (_sum[option] == 0.0f);
|
||||
|
||||
data[option] = new float[numValues]{0.0f};
|
||||
|
||||
for(int j=0; j<numValues; j++){
|
||||
@@ -314,18 +600,28 @@ std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata
|
||||
max[i] = std::max(max[i], v);
|
||||
|
||||
sum[i] += v;
|
||||
|
||||
if(calculateMin)
|
||||
_min[option] = std::min(_min[option],v);
|
||||
if(calculateMax)
|
||||
_max[option] = std::max(_max[option],v);
|
||||
if(claculateSum)
|
||||
_sum[option] += v;
|
||||
}
|
||||
i++;
|
||||
// if(calculateMin)
|
||||
// std::cout << _min[option] << std::endl;
|
||||
}
|
||||
|
||||
for(int i=0; i<numSelected; i++){
|
||||
processData(data[ selectedOptions[i] ], optionValues[i], min[i], max[i], sum[i]);
|
||||
int selected = selectedOptions[i];
|
||||
processData(data[ selected ], optionValues[i], _min[selected], _max[selected], _sum[selected], selected);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void DataProcessor::processData(float* outputData, std::vector<float>& inputData, float min, float max,float sum){
|
||||
void DataProcessor::processData(float* outputData, std::vector<float>& inputData, float min, float max,float sum, int selected){
|
||||
const int numValues = inputData.size();
|
||||
Histogram histogram(min, max, 512);
|
||||
|
||||
@@ -371,6 +667,14 @@ void DataProcessor::processData(float* outputData, std::vector<float>& inputData
|
||||
// equalized.print();
|
||||
}
|
||||
|
||||
float DataProcessor::processDataPoint(float value, int option){
|
||||
if(_numValues.empty()) return 0.0f;
|
||||
|
||||
float mean = (1.0 / _numValues[option]) * _sum[option];
|
||||
float v = normalizeWithStandardScore(value, mean, _sd[option]);
|
||||
return v;
|
||||
}
|
||||
|
||||
float DataProcessor::normalizeWithStandardScore(float value, float mean, float sd){
|
||||
|
||||
float zScoreMin = _normValues.x;
|
||||
@@ -386,4 +690,12 @@ glm::vec2 DataProcessor::filterValues(){
|
||||
return _filterValues;
|
||||
}
|
||||
|
||||
void DataProcessor::clear(){
|
||||
_min.clear();
|
||||
_max.clear();
|
||||
_sum.clear();
|
||||
_sd.clear();
|
||||
_histograms.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <set>
|
||||
#include <openspace/util/histogram.h>
|
||||
|
||||
namespace openspace{
|
||||
class DataProcessor{
|
||||
@@ -57,23 +58,33 @@ public:
|
||||
|
||||
std::vector<std::string> readHeader(std::string& dataBuffer);
|
||||
std::vector<float*> readData(std::string& dataBuffer, properties::SelectionProperty dataOptions);
|
||||
std::vector<float*> readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions);
|
||||
void addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions);
|
||||
|
||||
std::vector<std::string> readJSONHeader(std::string& dataBuffer);
|
||||
std::vector<float*> readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions);
|
||||
std::vector<float*> readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions);
|
||||
void addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions);
|
||||
|
||||
std::vector<float*> processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions);
|
||||
std::vector<float*> processKameleonData2(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions);
|
||||
void addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option);
|
||||
|
||||
void clear();
|
||||
|
||||
glm::vec2 filterValues();
|
||||
|
||||
private:
|
||||
void processData(
|
||||
float* outputData, // Where you want your processed data to go
|
||||
std::vector<float>& inputData, //data that needs processing
|
||||
float min, // min value of the input data
|
||||
float max, // max valye of the input data
|
||||
float sum // sum of the input data
|
||||
float sum, // sum of the input data
|
||||
int selected = 0
|
||||
);
|
||||
|
||||
float processDataPoint(float value, int option);
|
||||
|
||||
float normalizeWithStandardScore(float value, float mean, float sd);
|
||||
|
||||
glm::size3_t _dimensions;
|
||||
@@ -82,6 +93,13 @@ private:
|
||||
glm::vec2 _normValues;
|
||||
glm::vec2 _filterValues;
|
||||
|
||||
std::vector<float> _min;
|
||||
std::vector<float> _max;
|
||||
std::vector<float> _sum;
|
||||
std::vector<float> _sd;
|
||||
std::vector<float> _numValues;
|
||||
std::vector<std::shared_ptr<Histogram>> _histograms;
|
||||
// int _numValues;
|
||||
std::set<std::string> _coordinateVariables;
|
||||
};
|
||||
|
||||
|
||||
@@ -201,12 +201,13 @@ std::string IswaManager::iswaUrl(int id, std::string type){
|
||||
return url;
|
||||
}
|
||||
|
||||
void IswaManager::registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet){
|
||||
std::shared_ptr<IswaGroup> IswaManager::registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet){
|
||||
if(_groups.find(name) == _groups.end()){
|
||||
_groups.insert(std::pair<std::string, std::shared_ptr<IswaGroup>>(name, std::make_shared<IswaGroup>(name)));
|
||||
}
|
||||
|
||||
_groups[name]->registerCygnet(cygnet, type);
|
||||
return _groups[name];
|
||||
}
|
||||
|
||||
void IswaManager::unregisterFromGroup(std::string name, IswaCygnet* cygnet){
|
||||
@@ -343,7 +344,7 @@ std::string IswaManager::parseKWToLuaTable(std::string kwPath, std::string cut,
|
||||
}
|
||||
|
||||
std::string table = "{"
|
||||
"Name = 'KameleonPlane_"+cut+"',"
|
||||
"Name = 'KameleonPlane-"+cut+"',"
|
||||
"Parent = '" + parent + "', "
|
||||
"Renderable = {"
|
||||
"Type = 'KameleonPlane', "
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
std::future<DownloadManager::MemoryFile> fetchDataCygnet(int id);
|
||||
std::string iswaUrl(int id, std::string type = "image");
|
||||
|
||||
void registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet);
|
||||
std::shared_ptr<IswaGroup> registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet);
|
||||
void unregisterFromGroup(std::string name, IswaCygnet* cygnet);
|
||||
void registerOptionsToGroup(std::string name, const std::vector<properties::SelectionProperty::Option>& options);
|
||||
std::shared_ptr<IswaGroup> iswaGroup(std::string name);
|
||||
|
||||
@@ -75,7 +75,7 @@ void renderOptionProperty(Property* prop) {
|
||||
void renderSelectionProperty(Property* prop) {
|
||||
SelectionProperty* p = static_cast<SelectionProperty*>(prop);
|
||||
std::string name = p->guiName();
|
||||
|
||||
|
||||
if (ImGui::CollapsingHeader((name).c_str())) {
|
||||
const std::vector<SelectionProperty::Option>& options = p->options();
|
||||
std::vector<int> newSelectedIndices;
|
||||
|
||||
Reference in New Issue
Block a user