Skip to content

Commit 1b23aef

Browse files
niklasharryssonjstone-lucasfilm
authored andcommitted
Value class float formatting (AcademySoftwareFoundation#124)
* Support for setting float format and precision to Value class, for handling conversion from values to string values. * Small fix for build problem on linux/mac * Added enum for the supported float formats. * Added test for float formatting in value conversion to string. * Fixed build problem on Linux. * Fixed coding standard inconsistencies
1 parent b2664df commit 1b23aef

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

source/MaterialXCore/Value.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77

88
#include <MaterialXCore/Util.h>
99

10+
#include <iomanip>
1011
#include <sstream>
1112
#include <type_traits>
1213

1314
namespace MaterialX
1415
{
1516

1617
Value::CreatorMap Value::_creatorMap;
18+
Value::FloatFormat Value::_floatFormat = Value::FloatFormatDefault;
19+
int Value::_floatPrecision = 6;
1720

1821
namespace {
1922

@@ -93,6 +96,15 @@ template <class T> void stringToData(const string& str, enable_if_std_vector_t<T
9396
template <class T> void dataToString(const T& data, string& str)
9497
{
9598
std::stringstream ss;
99+
100+
// Set float format and precision for the stream
101+
const Value::FloatFormat fmt = Value::getFloatFormat();
102+
ss.setf(std::ios_base::fmtflags(
103+
(fmt == Value::FloatFormatFixed ? std::ios_base::fixed :
104+
(fmt == Value::FloatFormatScientific ? std::ios_base::scientific : 0))),
105+
std::ios_base::floatfield);
106+
ss.precision(Value::getFloatPrecision());
107+
96108
ss << data;
97109
str = ss.str();
98110
}
@@ -232,6 +244,20 @@ template<class T> T Value::asA() const
232244
return typedVal->getData();
233245
}
234246

247+
Value::ScopedFloatFormatting::ScopedFloatFormatting(FloatFormat format, int precision) :
248+
_format(Value::getFloatFormat()),
249+
_precision(Value::getFloatPrecision())
250+
{
251+
Value::setFloatFormat(format);
252+
Value::setFloatPrecision(precision);
253+
}
254+
255+
Value::ScopedFloatFormatting::~ScopedFloatFormatting()
256+
{
257+
Value::setFloatFormat(_format);
258+
Value::setFloatPrecision(_precision);
259+
}
260+
235261
//
236262
// Value registry class
237263
//

source/MaterialXCore/Value.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ template <class T> class TypedValue;
2626
/// A generic, discriminated value, whose type may be queried dynamically.
2727
class Value
2828
{
29+
public:
30+
/// Float formats to use when converting values to strings.
31+
enum FloatFormat
32+
{
33+
FloatFormatDefault = 0,
34+
FloatFormatFixed = 1,
35+
FloatFormatScientific = 2
36+
};
37+
2938
public:
3039
Value()
3140
{
@@ -64,6 +73,45 @@ class Value
6473
/// Return the value string for this value.
6574
virtual string getValueString() const = 0;
6675

76+
/// Set float formatting for converting values to strings.
77+
/// Formats to use are FloatFormatFixed, FloatFormatScientific
78+
/// or FloatFormatDefault to set default format.
79+
static void setFloatFormat(FloatFormat format)
80+
{
81+
_floatFormat = format;
82+
}
83+
84+
/// Set float precision for converting values to strings.
85+
static void setFloatPrecision(int precision)
86+
{
87+
_floatPrecision = precision;
88+
}
89+
90+
/// Return the current float format.
91+
static FloatFormat getFloatFormat()
92+
{
93+
return _floatFormat;
94+
}
95+
96+
/// Return the current float precision.
97+
static int getFloatPrecision()
98+
{
99+
return _floatPrecision;
100+
}
101+
102+
/// RAII class for scoped setting of float formatting.
103+
/// Flags are reset when the object goes out of scope.
104+
class ScopedFloatFormatting
105+
{
106+
public:
107+
ScopedFloatFormatting(FloatFormat format, int precision = 6);
108+
~ScopedFloatFormatting();
109+
110+
private:
111+
FloatFormat _format;
112+
int _precision;
113+
};
114+
67115
protected:
68116
template <class T> friend class ValueRegistry;
69117

@@ -72,6 +120,8 @@ class Value
72120

73121
private:
74122
static CreatorMap _creatorMap;
123+
static FloatFormat _floatFormat;
124+
static int _floatPrecision;
75125
};
76126

77127
/// The class template for typed subclasses of Value

source/MaterialXTest/Value.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ TEST_CASE("Value strings", "[value]")
5050
REQUIRE(mx::toValueString(mx::Color3(1.0f)) == "1, 1, 1");
5151
REQUIRE(mx::toValueString(std::string("text")) == "text");
5252

53+
// Convert from data values to value strings
54+
// using the various float formattings.
55+
{
56+
mx::Value::ScopedFloatFormatting fmt(mx::Value::FloatFormatFixed, 3);
57+
REQUIRE(mx::toValueString(0.1234f) == "0.123");
58+
REQUIRE(mx::toValueString(mx::Color3(1.0f)) == "1.000, 1.000, 1.000");
59+
}
60+
{
61+
mx::Value::ScopedFloatFormatting fmt(mx::Value::FloatFormatScientific, 2);
62+
REQUIRE(mx::toValueString(0.1234f) == "1.23e-01");
63+
}
64+
{
65+
mx::Value::ScopedFloatFormatting fmt(mx::Value::FloatFormatDefault, 2);
66+
REQUIRE(mx::toValueString(0.1234f) == "0.12");
67+
}
68+
5369
// Convert from value strings to data values.
5470
REQUIRE(mx::fromValueString<int>("1") == 1);
5571
REQUIRE(mx::fromValueString<float>("1") == 1.0f);

0 commit comments

Comments
 (0)