MaterialX icon indicating copy to clipboard operation
MaterialX copied to clipboard

Default float formatting causes programmatically generated documents to be invalid

Open pablode opened this issue 2 years ago • 0 comments

When using the C++ API with default settings, very small or large float values (f.i. from an external data source) can cause a programmatically generated document to be invalid.

Following test case demonstrates the issue:

in MaterialXTest/MaterialXFormat/XmlIo.cpp:

TEST_CASE("Float value representation", "[xmlio]")
{
  float floatCloseToZero = std::nextafter(0.0f, 1.0f);
  auto floatString = mx::Value::createValue(floatCloseToZero)->getValueString();

  mx::DocumentPtr doc = mx::createDocument();
  auto node = doc->addNode("constant", mx::EMPTY_STRING, "float");
  auto input = node->addInput("value", "float");
  input->setValueString(floatString);

  std::string errMsg;
  bool validationResult = doc->validate(&errMsg);
  if (!errMsg.empty())
  {
    fprintf(stderr, "%s\n", errMsg.c_str());
  }
  REQUIRE(validationResult);
}

The problem is that the <iostream> API is used to serialize the float to a string (Value.cpp:95), where the default format mode emits a scientific notation (1.4013e-45 in this case), which is not valid MaterialX float syntax. The behaviour can be 'fixed' by setting the float format mode:

mx::ScopedFloatFormatting fmt(mx::Value::FloatFormatFixed);

However, this is not the default behaviour and the need for setting a specific float format mode only becomes apparent after running into the problem described above.

pablode avatar Dec 13 '22 16:12 pablode