static void action_param (int argc, const char *argv[]) { std::string command = argv[0]; bool use_reparam = false; if (OIIO::Strutil::istarts_with(command, "--reparam") || OIIO::Strutil::istarts_with(command, "-reparam")) use_reparam = true; ParamValueList ¶ms (use_reparam ? reparams : (::params)); std::string paramname = argv[1]; std::string stringval = argv[2]; TypeDesc type = TypeDesc::UNKNOWN; bool unlockgeom = false; float f[16]; size_t pos; while ((pos = command.find_first_of(":")) != std::string::npos) { command = command.substr (pos+1, std::string::npos); std::vector<std::string> splits; OIIO::Strutil::split (command, splits, ":", 1); if (splits.size() < 1) {} else if (OIIO::Strutil::istarts_with(splits[0],"type=")) type.fromstring (splits[0].c_str()+5); else if (OIIO::Strutil::istarts_with(splits[0],"lockgeom=")) unlockgeom = (strtol (splits[0].c_str()+9, NULL, 10) == 0); } // If it is or might be a matrix, look for 16 comma-separated floats if ((type == TypeDesc::UNKNOWN || type == TypeDesc::TypeMatrix) && sscanf (stringval.c_str(), "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9], &f[10], &f[11], &f[12], &f[13], &f[14], &f[15]) == 16) { params.push_back (ParamValue()); params.back().init (paramname, TypeDesc::TypeMatrix, 1, f); if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // If it is or might be a vector type, look for 3 comma-separated floats if ((type == TypeDesc::UNKNOWN || equivalent(type,TypeDesc::TypeVector)) && sscanf (stringval.c_str(), "%g, %g, %g", &f[0], &f[1], &f[2]) == 3) { if (type == TypeDesc::UNKNOWN) type = TypeDesc::TypeVector; params.push_back (ParamValue()); params.back().init (paramname, type, 1, f); if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // If it is or might be an int, look for an int that takes up the whole // string. if ((type == TypeDesc::UNKNOWN || type == TypeDesc::TypeInt)) { char *endptr = NULL; int ival = strtol(stringval.c_str(),&endptr,10); if (endptr && *endptr == 0) { params.push_back (ParamValue()); params.back().init (paramname, TypeDesc::TypeInt, 1, &ival); if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } } // If it is or might be an float, look for a float that takes up the // whole string. if ((type == TypeDesc::UNKNOWN || type == TypeDesc::TypeFloat)) { char *endptr = NULL; float fval = (float) strtod(stringval.c_str(),&endptr); if (endptr && *endptr == 0) { params.push_back (ParamValue()); params.back().init (paramname, TypeDesc::TypeFloat, 1, &fval); if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } } // All remaining cases -- it's a string const char *s = stringval.c_str(); params.push_back (ParamValue()); params.back().init (paramname, TypeDesc::TypeString, 1, &s); if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); }
static void action_param (int argc, const char *argv[]) { std::string command = argv[0]; bool use_reparam = false; if (OIIO::Strutil::istarts_with(command, "--reparam") || OIIO::Strutil::istarts_with(command, "-reparam")) use_reparam = true; ParamValueList ¶ms (use_reparam ? reparams : (::params)); string_view paramname (argv[1]); string_view stringval (argv[2]); TypeDesc type = TypeDesc::UNKNOWN; bool unlockgeom = false; float f[16]; size_t pos; while ((pos = command.find_first_of(":")) != std::string::npos) { command = command.substr (pos+1, std::string::npos); std::vector<std::string> splits; OIIO::Strutil::split (command, splits, ":", 1); if (splits.size() < 1) {} else if (OIIO::Strutil::istarts_with(splits[0],"type=")) type.fromstring (splits[0].c_str()+5); else if (OIIO::Strutil::istarts_with(splits[0],"lockgeom=")) unlockgeom = (OIIO::Strutil::from_string<int> (splits[0]) == 0); } // If it is or might be a matrix, look for 16 comma-separated floats if ((type == TypeDesc::UNKNOWN || type == TypeDesc::TypeMatrix) && sscanf (stringval.c_str(), "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9], &f[10], &f[11], &f[12], &f[13], &f[14], &f[15]) == 16) { #if OIIO_VERSION >= 10804 params.emplace_back (paramname, TypeDesc::TypeMatrix, 1, f); #else params.push_back (ParamValue()); params.back().init (paramname, TypeDesc::TypeMatrix, 1, f); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // If it is or might be a vector type, look for 3 comma-separated floats if ((type == TypeDesc::UNKNOWN || equivalent(type,TypeDesc::TypeVector)) && sscanf (stringval.c_str(), "%g, %g, %g", &f[0], &f[1], &f[2]) == 3) { if (type == TypeDesc::UNKNOWN) type = TypeDesc::TypeVector; #if OIIO_VERSION >= 10804 params.emplace_back (paramname, type, 1, f); #else params.push_back (ParamValue()); params.back().init (paramname, type, 1, f); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // If it is or might be an int, look for an int that takes up the whole // string. if ((type == TypeDesc::UNKNOWN || type == TypeDesc::TypeInt) && OIIO::Strutil::string_is<int>(stringval)) { #if OIIO_VERSION >= 10804 params.emplace_back (paramname, OIIO::Strutil::from_string<int>(stringval)); #else params.push_back (ParamValue()); int i = OIIO::Strutil::from_string<int>(stringval); params.back().init (paramname, TypeDesc::TypeInt, 1, &i); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // If it is or might be an float, look for a float that takes up the // whole string. if ((type == TypeDesc::UNKNOWN || type == TypeDesc::TypeFloat) && OIIO::Strutil::string_is<float>(stringval)) { #if OIIO_VERSION >= 10804 params.emplace_back (paramname, OIIO::Strutil::from_string<float>(stringval)); #else params.push_back (ParamValue()); float f = OIIO::Strutil::from_string<float>(stringval); params.back().init (paramname, TypeDesc::TypeFloat, 1, &f); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // Catch-all for float types and arrays if (type.basetype == TypeDesc::FLOAT) { int n = type.aggregate * type.numelements(); std::vector<float> vals (n); for (int i = 0; i < n; ++i) { OIIO::Strutil::parse_float (stringval, vals[i]); OIIO::Strutil::parse_char (stringval, ','); } #if OIIO_VERSION >= 10804 params.emplace_back (paramname, type, 1, &vals[0]); #else params.push_back (ParamValue()); params.back().init (paramname, type, 1, &vals[0]); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // Catch-all for int types and arrays if (type.basetype == TypeDesc::INT) { int n = type.aggregate * type.numelements(); std::vector<int> vals (n); for (int i = 0; i < n; ++i) { OIIO::Strutil::parse_int (stringval, vals[i]); OIIO::Strutil::parse_char (stringval, ','); } #if OIIO_VERSION >= 10804 params.emplace_back (paramname, type, 1, &vals[0]); #else params.push_back (ParamValue()); params.back().init (paramname, type, 1, &vals[0]); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // String arrays are slightly tricky if (type.basetype == TypeDesc::STRING && type.is_array()) { std::vector<string_view> splitelements; OIIO::Strutil::split (stringval, splitelements, ",", type.arraylen); splitelements.resize (type.arraylen); std::vector<ustring> strelements; for (auto&& s : splitelements) strelements.push_back (ustring(s)); #if OIIO_VERSION >= 10804 params.emplace_back (paramname, type, 1, &strelements[0]); #else params.push_back (ParamValue()); params.back().init (paramname, type, 1, &strelements[0]); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); return; } // All remaining cases -- it's a string const char *s = stringval.c_str(); #if OIIO_VERSION >= 10804 params.emplace_back (paramname, TypeDesc::TypeString, 1, &s); #else params.push_back (ParamValue()); params.back().init (paramname, TypeDesc::TypeString, 1, &s); #endif if (unlockgeom) params.back().interp (ParamValue::INTERP_VERTEX); }
// Add the attribute -- figure out the type void parse_param(string_view paramname, string_view val, ImageSpec& spec) { TypeDesc type; // start out unknown // If the param string starts with a type name, that's what it is if (size_t typeportion = type.fromstring(paramname)) { paramname.remove_prefix(typeportion); Strutil::skip_whitespace(paramname); } // If the value string starts with a type name, that's what it is else if (size_t typeportion = type.fromstring(val)) { val.remove_prefix(typeportion); Strutil::skip_whitespace(val); } if (type.basetype == TypeDesc::UNKNOWN) { // If we didn't find a type name, try to guess if (val.size() >= 2 && val.front() == '\"' && val.back() == '\"') { // Surrounded by quotes? it's a string (strip off the quotes) val.remove_prefix(1); val.remove_suffix(1); type = TypeDesc::TypeString; } else if (Strutil::string_is<int>(val)) { // Looks like an int, is an int type = TypeDesc::TypeInt; } else if (Strutil::string_is<float>(val)) { // Looks like a float, is a float type = TypeDesc::TypeFloat; } else { // Everything else is assumed a string type = TypeDesc::TypeString; } } // Read the values and set the attribute int n = type.numelements() * type.aggregate; if (type.basetype == TypeDesc::INT) { std::vector<int> values(n); for (int i = 0; i < n; ++i) { Strutil::parse_int(val, values[i]); Strutil::parse_char(val, ','); // optional } if (n > 0) spec.attribute(paramname, type, &values[0]); } if (type.basetype == TypeDesc::FLOAT) { std::vector<float> values(n); for (int i = 0; i < n; ++i) { Strutil::parse_float(val, values[i]); Strutil::parse_char(val, ','); // optional } if (n > 0) spec.attribute(paramname, type, &values[0]); } else if (type.basetype == TypeDesc::STRING) { std::vector<ustring> values(n); for (int i = 0; i < n; ++i) { string_view v; Strutil::parse_string(val, v); Strutil::parse_char(val, ','); // optional values[i] = v; } if (n > 0) spec.attribute(paramname, type, &values[0]); } }
static void TypeDesc_fromstring (TypeDesc &t, const char* typestring) { t.fromstring (typestring); }