mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-29 07:19:28 -05:00
Updated kameleonwrapper to be able to load several variables into a RGB texture. Added support for 'Variables' tag in .mod scenegraph files which takes 3 variables as an array
This commit is contained in:
@@ -46,8 +46,10 @@ public:
|
||||
KameleonWrapper(const std::string& filename, Model model);
|
||||
~KameleonWrapper();
|
||||
float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions);
|
||||
float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions);
|
||||
|
||||
private:
|
||||
void getGridVariables(std::string& x, std::string& y, std::string& z);
|
||||
ccmc::Model* _model;
|
||||
Model _type;
|
||||
ccmc::Interpolator* _interpolator;
|
||||
|
||||
@@ -102,63 +102,103 @@ std::string RenderableVolume::findPath(const std::string& path) {
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary) {
|
||||
if( ! FileSys.fileExists(filepath)) {
|
||||
LWARNING("Could not load volume, could not find '" << filepath << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(hasExtension(filepath, "raw")) {
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
ghoul::RawVolumeReader rawReader(hints);
|
||||
return rawReader.read(filepath);
|
||||
} else if(hasExtension(filepath, "cdf")) {
|
||||
|
||||
std::string modelString;
|
||||
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
|
||||
KameleonWrapper::Model model;
|
||||
if (modelString == "BATSRUS") {
|
||||
model = KameleonWrapper::Model::BATSRUS;
|
||||
} else if (modelString == "ENLIL") {
|
||||
model = KameleonWrapper::Model::ENLIL;
|
||||
} else {
|
||||
LWARNING("Hints does not specify a valid 'Model'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
glm::size3_t dimensions(1,1,1);
|
||||
double tempValue;
|
||||
if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[0] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[1] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath, model);
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable'");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
LWARNING("Hints does not specify a 'Model'");
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
if( ! FileSys.fileExists(filepath)) {
|
||||
LWARNING("Could not load volume, could not find '" << filepath << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(hasExtension(filepath, "raw")) {
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
ghoul::RawVolumeReader rawReader(hints);
|
||||
return rawReader.read(filepath);
|
||||
} else if(hasExtension(filepath, "cdf")) {
|
||||
|
||||
std::string modelString;
|
||||
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
|
||||
KameleonWrapper::Model model;
|
||||
if (modelString == "BATSRUS") {
|
||||
model = KameleonWrapper::Model::BATSRUS;
|
||||
} else if (modelString == "ENLIL") {
|
||||
model = KameleonWrapper::Model::ENLIL;
|
||||
} else {
|
||||
LWARNING("Hints does not specify a valid 'Model'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glm::size3_t dimensions(1,1,1);
|
||||
double tempValue;
|
||||
if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[0] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[1] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath, model);
|
||||
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
|
||||
} else if (hintsDictionary.hasKey("Variables")) {
|
||||
std::string xVariable, yVariable, zVariable;
|
||||
bool xVar, yVar, zVar;
|
||||
xVar = hintsDictionary.getValue("Variables.1", xVariable);
|
||||
yVar = hintsDictionary.getValue("Variables.2", yVariable);
|
||||
zVar = hintsDictionary.getValue("Variables.3", zVariable);
|
||||
|
||||
if (!xVar || !yVar || !zVar) {
|
||||
LERROR("Error reading variables! Must be 3 and must exist in CDF data");
|
||||
} else {
|
||||
float* data = kw.getUniformSampledVectorValues(xVariable, yVariable, zVariable, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT);
|
||||
}
|
||||
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable' or 'Variables'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// float* data = kw.getUniformSampledVectorValues(variableString, dimensions);
|
||||
// return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT);
|
||||
|
||||
// float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
// new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
|
||||
// ghoul::opengl::Texture* texture;
|
||||
// float* data;
|
||||
|
||||
// if (hintsDictionary.hasKey("VectorData") && hintsDictionary.getValue("VectorData", variableString)) {
|
||||
// if (variableString == "1") { // Vector data
|
||||
// LDEBUG("VectorData");
|
||||
// data = kw.getUniformSampledVectorValues(variableString, dimensions);
|
||||
// texture = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGB, GL_RGB8, GL_FLOAT);
|
||||
// } else { // Scalar data
|
||||
// LDEBUG("ScalarData");
|
||||
// data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
// texture = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
LWARNING("Hints does not specify a 'Model'");
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
|
||||
|
||||
@@ -248,14 +248,17 @@ bool RenderableVolumeExpert::initialize() {
|
||||
|
||||
for (int i = 0; i < _volumePaths.size(); ++i) {
|
||||
ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i));
|
||||
if(volume) {
|
||||
if(volume != nullptr) {
|
||||
LDEBUG("All is well");
|
||||
volume->uploadTexture();
|
||||
|
||||
LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'");
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
} else {
|
||||
LDEBUG("nullptr, derp");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+131
-74
@@ -42,19 +42,19 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ
|
||||
switch (_type) {
|
||||
case Model::BATSRUS:
|
||||
_model = new ccmc::BATSRUS();
|
||||
if(!_model) LERROR("BATSRUS:Failed to create model instance");
|
||||
if(!_model) LERROR("BATSRUS:Failed to create BATSRUS model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("BATSRUS:Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("BATSRUS:Failed to create interpolator");
|
||||
if (!_interpolator) LERROR("BATSRUS:Failed to create BATSRUS interpolator");
|
||||
break;
|
||||
case Model::ENLIL:
|
||||
_model = new ccmc::ENLIL();
|
||||
if(!_model) LERROR("Failed to create model instance");
|
||||
if(!_model) LERROR("Failed to create ENLIL model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("Failed to create interpolator");
|
||||
if (!_interpolator) LERROR("Failed to create ENLIL interpolator");
|
||||
break;
|
||||
default:
|
||||
LERROR("No valid model type provided!");
|
||||
@@ -70,54 +70,14 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Loading CDF data");
|
||||
LINFO("Loading variable " << var << " from CDF data with a uniform sampling");
|
||||
|
||||
int size = outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
|
||||
// get the grid system string
|
||||
std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString();
|
||||
|
||||
// remove leading and trailing brackets
|
||||
gridSystem = gridSystem.substr(1,gridSystem.length()-2);
|
||||
|
||||
// remove all whitespaces
|
||||
gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end());
|
||||
|
||||
// replace all comma signs with whitespaces
|
||||
std::replace( gridSystem.begin(), gridSystem.end(), ',', ' ');
|
||||
|
||||
// tokenize
|
||||
std::istringstream iss(gridSystem);
|
||||
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};
|
||||
|
||||
// validate
|
||||
if (tokens.size() != 3) {
|
||||
LERROR("Something went wrong");
|
||||
delete[] data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string v_x = tokens.at(0), v_y = tokens.at(1), v_z = tokens.at(2);
|
||||
/*
|
||||
for(auto t: tokens)
|
||||
LDEBUG("t: " << t);
|
||||
*/
|
||||
/*
|
||||
LERROR("getVariableAttributeNames");
|
||||
std::vector<std::string> attributeNames = _model->getVariableAttributeNames();
|
||||
for(auto name : attributeNames)
|
||||
LDEBUG(name);
|
||||
*/
|
||||
//_model->getVa
|
||||
|
||||
//auto fan = std::find(attributeNames.begin(), attributeNames.end(), "");
|
||||
|
||||
|
||||
//KameleonWrapper (Debug) grid_system_1
|
||||
//KameleonWrapper (Debug) grid_1_type
|
||||
|
||||
LDEBUG("Using coordinate system: " << v_x << ", " << v_y << ", " << v_z);
|
||||
std::string v_x, v_y, v_z;
|
||||
getGridVariables(v_x, v_y, v_z);
|
||||
LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z);
|
||||
|
||||
float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat();
|
||||
float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat();
|
||||
@@ -132,7 +92,6 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
float stepY = (yMax-yMin)/(static_cast<float>(outDimensions.y));
|
||||
float stepZ = (zMax-zMin)/(static_cast<float>(outDimensions.z));
|
||||
|
||||
|
||||
LDEBUG(v_x << "Min: " << xMin);
|
||||
LDEBUG(v_x << "Max: " << xMax);
|
||||
LDEBUG(v_y << "Min: " << yMin);
|
||||
@@ -174,10 +133,6 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
// scale to [0,1]
|
||||
data[index] = (value-varMin)/(varMax-varMin);
|
||||
} else if (_type == Model::ENLIL) {
|
||||
//LDEBUG("data: " << theval);
|
||||
|
||||
// Calculate array index
|
||||
//unsigned int index = r + theta*xDim_ + phi*xDim_*yDim_;
|
||||
|
||||
// Put r in the [0..sqrt(3)] range
|
||||
float rNorm = sqrt(3.0)*(float)x/(float)(outDimensions.x-1);
|
||||
@@ -191,15 +146,12 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
// Go to physical coordinates before sampling
|
||||
float rPh = xMin + rNorm*(xMax-xMin);
|
||||
float thetaPh = thetaNorm;
|
||||
//phi range needs to be mapped to the slightly different
|
||||
// model range to avoid gaps in the data
|
||||
// Subtract a small term to avoid rounding errors when comparing
|
||||
// to phiMax.
|
||||
// phi range needs to be mapped to the slightly different model
|
||||
// range to avoid gaps in the data Subtract a small term to
|
||||
// avoid rounding errors when comparing to phiMax.
|
||||
float phiPh = zMin + phiNorm/(2.0*M_PI)*(zMax-zMin-0.000001);
|
||||
|
||||
// Hardcoded variables (rho or rho - rho_back)
|
||||
// TODO Don't hardcode, make more flexible
|
||||
float varValue = 0.f;//, rho_back = 0.f, diff = 0.f;
|
||||
float varValue = 0.f;
|
||||
// See if sample point is inside domain
|
||||
if (rPh < xMin || rPh > xMax || thetaPh < yMin ||
|
||||
thetaPh > yMax || phiPh < zMin || phiPh > zMax) {
|
||||
@@ -218,22 +170,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
phiPh = phiPh*180.f/M_PI;
|
||||
// Sample
|
||||
varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh);
|
||||
//rho_back = _interpolator->interpolate("rho-back",rPh,thetaPh,phiPh);
|
||||
|
||||
// Calculate difference (or just rho)
|
||||
//diff = rho;
|
||||
//diff = rho - rho_back;
|
||||
|
||||
// Clamp to 0
|
||||
//if (diff < 0.f) diff = 0.f;
|
||||
}
|
||||
//if(var < 0.0f) var = 0.0f;
|
||||
//data[index] = var;
|
||||
|
||||
data[index] = (varValue-varMin)/(varMax-varMin);
|
||||
//LDEBUG("varValue:" << varValue);
|
||||
//LDEBUG("data[index]:" << data[index]);
|
||||
//data[index] = var;
|
||||
//data[index] = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,5 +183,123 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
return data;
|
||||
}
|
||||
|
||||
float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions) {
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Loading variables " << xVar << " " << yVar << " " << zVar << " from CDF data with a uniform sampling");
|
||||
|
||||
int size = 4*outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
|
||||
std::string v_x, v_y, v_z;
|
||||
getGridVariables(v_x, v_y, v_z);
|
||||
LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z);
|
||||
|
||||
float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat();
|
||||
float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat();
|
||||
float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat();
|
||||
float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat();
|
||||
float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat();
|
||||
float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat();
|
||||
float varXMin = _model->getVariableAttribute(xVar, "actual_min").getAttributeFloat();
|
||||
float varXMax = _model->getVariableAttribute(xVar, "actual_max").getAttributeFloat();
|
||||
float varYMin = _model->getVariableAttribute(yVar, "actual_min").getAttributeFloat();
|
||||
float varYMax = _model->getVariableAttribute(yVar, "actual_max").getAttributeFloat();
|
||||
float varZMin = _model->getVariableAttribute(zVar, "actual_min").getAttributeFloat();
|
||||
float varZMax = _model->getVariableAttribute(zVar, "actual_max").getAttributeFloat();
|
||||
|
||||
float stepX = (xMax-xMin)/(static_cast<float>(outDimensions.x));
|
||||
float stepY = (yMax-yMin)/(static_cast<float>(outDimensions.y));
|
||||
float stepZ = (zMax-zMin)/(static_cast<float>(outDimensions.z));
|
||||
|
||||
LDEBUG(v_x << "Min: " << xMin);
|
||||
LDEBUG(v_x << "Max: " << xMax);
|
||||
LDEBUG(v_y << "Min: " << yMin);
|
||||
LDEBUG(v_y << "Max: " << yMax);
|
||||
LDEBUG(v_z << "Min: " << zMin);
|
||||
LDEBUG(v_z << "Max: " << zMax);
|
||||
LDEBUG(xVar << "Min: " << varXMin);
|
||||
LDEBUG(xVar << "Max: " << varXMax);
|
||||
LDEBUG(yVar << "Min: " << varYMin);
|
||||
LDEBUG(yVar << "Max: " << varYMax);
|
||||
LDEBUG(zVar << "Min: " << varZMin);
|
||||
LDEBUG(zVar << "Max: " << varZMax);
|
||||
|
||||
int barWidth = 70;
|
||||
int lastiProgress = -1;
|
||||
for (int x = 0; x < outDimensions.x; ++x) {
|
||||
float progress = static_cast<float>(x) / static_cast<float>(outDimensions.x-1);
|
||||
int iprogress = static_cast<int>(progress*100.0f);
|
||||
if (iprogress != lastiProgress) {
|
||||
|
||||
int pos = barWidth * progress;
|
||||
int eqWidth = pos+1;
|
||||
int spWidth = barWidth - pos + 2;
|
||||
std::cout << "[" << std::setfill('=') << std::setw(eqWidth)
|
||||
<< ">" << std::setfill(' ') << std::setw(spWidth)
|
||||
<< "] " << iprogress << " % \r" << std::flush;
|
||||
}
|
||||
lastiProgress = iprogress;
|
||||
|
||||
for (int y = 0; y < outDimensions.y; ++y) {
|
||||
for (int z = 0; z < outDimensions.z; ++z) {
|
||||
|
||||
int index = 4*x + 4*y*outDimensions.x + 4*z*outDimensions.x*outDimensions.y;
|
||||
|
||||
if(_type == Model::BATSRUS) {
|
||||
float xPos = xMin + stepX*x;
|
||||
float yPos = yMin + stepY*y;
|
||||
float zPos = zMin + stepZ*z;
|
||||
|
||||
// get interpolated data value for (xPos, yPos, zPos)
|
||||
float xValue = _interpolator->interpolate(xVar, xPos, yPos, zPos);
|
||||
float yValue = _interpolator->interpolate(yVar, xPos, yPos, zPos);
|
||||
float zValue = _interpolator->interpolate(zVar, xPos, yPos, zPos);
|
||||
|
||||
// scale to [0,1]
|
||||
data[index] = (xValue-varXMin)/(varXMax-varXMin);
|
||||
data[index + 1] = (yValue-varYMin)/(varYMax-varYMin);
|
||||
data[index + 2] = (zValue-varZMin)/(varZMax-varZMin);
|
||||
data[index + 3] = 1.0;
|
||||
} else {
|
||||
LERROR("Only BATSRUS supported for getUniformSampledVectorValues");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
LINFO("Done!");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::string& z) {
|
||||
// get the grid system string
|
||||
std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString();
|
||||
|
||||
// remove leading and trailing brackets
|
||||
gridSystem = gridSystem.substr(1,gridSystem.length()-2);
|
||||
|
||||
// remove all whitespaces
|
||||
gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end());
|
||||
|
||||
// replace all comma signs with whitespaces
|
||||
std::replace( gridSystem.begin(), gridSystem.end(), ',', ' ');
|
||||
|
||||
// tokenize
|
||||
std::istringstream iss(gridSystem);
|
||||
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};
|
||||
|
||||
// validate
|
||||
if (tokens.size() != 3) {
|
||||
LERROR("Something went wrong");
|
||||
}
|
||||
|
||||
x = tokens.at(0);
|
||||
y = tokens.at(1);
|
||||
z = tokens.at(2);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
|
||||
Reference in New Issue
Block a user