void XformDescriptor::parse()

in lib/DepthMapTransform.cpp [167:265]


void XformDescriptor::parse(const std::string& str) {
  depthType = DepthXformType::None;
  spatialType = SpatialXformType::None;

  const size_t pos = str.find('(');
  const std::string typeStr = str.substr(0, pos);

  std::vector<std::string> args;

  auto getArgs = [&]() {
    if (pos == str.npos || str[str.length() - 1] != ')') {
      throw std::runtime_error("Malformed descriptor string.");
    }

    std::string argsStr = str.substr(pos + 1, str.size() - 1 - (pos + 1));
    args = explode(argsStr, ',');
    for (std::string& s : args) {
      trim(s);
    }
  };

  auto checkNumArgs = [&](const int num) {
    if (args.size() != num) {
      throw std::runtime_error("Incorrect number of parameters.");
    }
  };

  if (type == XformType::Depth) {
    getArgs();

    // Backwards-compatibility hack to load old files using 2D grids.
    if (typeStr == "BicubicGrid" || typeStr == "BilinearGrid") {
      args = {
        args[0], // Value xform
        (typeStr == "BicubicGrid" ? "Cubic" : "Linear"),
        args[1], // Grid cols
        args[2], // Grid rows
        "1"
      };
      depthType = DepthXformType::Grid;
    } else {
      parseEnum(depthType, typeStr, depthXformTypeStrs);
    }

    switch (depthType) {
    case DepthXformType::Identity:
      checkNumArgs(0);
      break;
    case DepthXformType::Global:
      checkNumArgs(1);
      assert(!args.empty()); // For Lint.
      parseEnum(valueXform, args[0], valueXformStrs);
      break;
    case DepthXformType::Grid:
      if (args.size() < 5) {
        throw std::runtime_error("Incorrect number of parameters.");
      }
      parseEnum(valueXform, args[0], valueXformStrs);
      if (args[1] == "Cubic") {
        cubicInterpolation = true;
      } else if (args[1] == "Linear") {
        cubicInterpolation = false;
      } else {
        throw std::runtime_error("Invalid interpolation mode.");
      }

      gridSize.x() = std::stoi(args[2]);
      gridSize.y() = std::stoi(args[3]);
      gridSize.z() = std::stoi(args[4]);

      if (gridSize.z() <= 1) {
        checkNumArgs(5);
      } else {
        checkNumArgs(7);
        depthMinMax.x() = std::stof(args[5]);
        depthMinMax.y() = std::stof(args[6]);
      }
      break;
    default:
      throw std::runtime_error("Invalid depth transform type.");
    }
  } else if (type == XformType::Spatial) {
    parseEnum(spatialType, typeStr, spatialXformTypeStrs);

    switch(spatialType) {
    case SpatialXformType::BilinearGrid:
    case SpatialXformType::BicubicGrid:
      getArgs();
      checkNumArgs(2);
      assert(!args.empty()); // For Lint.
      gridSize.x() = std::stoi(args[0]);
      gridSize.y() = std::stoi(args[1]);
    default:
      break;
    }
  } else {
    throw std::runtime_error("Invalid transform type.");
  }
}