Skip to content

Commit 7b229d1

Browse files
Improve robustness of string array parsing
- Add support for parsing arrays of strings with internal spaces (e.g. "Item A, Item B, Item C") - Leverage the new parsing logic in getUIProperties. - Update the interface of LamaSSS to enable enum parsing. - Extend unit tests to validate the new logic.
1 parent f942671 commit 7b229d1

4 files changed

Lines changed: 15 additions & 40 deletions

File tree

libraries/bxdf/lama/lama_sss.mtlx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
doc="Diffuse Mean Free Path, expressed for each color channel in mm. Indicates on average how much the light travels under the surface before being scattered. The higher the value, the softer the result will be. If null, the computation simplifies to a Lambertian lobe." />
1010
<input name="sssScale" type="float" value="1.0" uiname="Scale" uifolder="SSS"
1111
doc="Multiplies the radius, to adjust its scale to the scene at hand. If null, the computation simplifies to a Lambertian lobe." />
12-
<input name="sssMode" type="integer" enum="Path-traced Davis,Path-traced exponential,Diffusion Burley,Diffusion Burley (mean free path)" enumvalues="0,1,2,3" value="0" uiname="Mode" uifolder="Main"
12+
<input name="sssMode" type="integer" uniform="true" enum="Path-traced Davis,Path-traced exponential,Diffusion Burley,Diffusion Burley (mean free path)" enumvalues="0,1,2,3" value="0" uiname="Mode" uifolder="Main"
1313
doc="Selects what method should be used to compute sub-surface scattering. Proposes two path-traced variants, and a more traditional approximate diffusion model." />
1414
<input name="sssIOR" type="float" value="1.0" uimin="1.0" uimax="2.0" uiname="IOR" uifolder="SSS"
1515
doc="Index of refraction use to trigger cases of total internal reflections, when the paths are reaching the surface after having travelled under it. Can be used to avoid excessive glow in highly curved regions (corners, creases, ...)." />
@@ -25,7 +25,7 @@
2525
doc="When enabled, ignores internal geometry and jumps to the last surface." />
2626
<input name="sssUnitLength" type="float" value="0.00328" uiname="Unit Length" uifolder="SSS"
2727
doc="Specifies what unit length the scene is using. It is a multiplier on the mean free path or diffuse mean free path which is expressed in mm. The default value of 0.00328 converts between feet and mm." />
28-
<input name="mode" type="integer" enum="Reflection,Transmission,Reflection(with direct illumination)" enumvalues="0,1,2" value="0" uiname="Mode" uifolder="Advanced"
28+
<input name="mode" type="integer" uniform="true" enum="Reflection,Transmission,Reflection(with direct illumination)" enumvalues="0,1,2" value="0" uiname="Mode" uifolder="Advanced"
2929
doc="If the subsurface is enabled, Reflection: should be used when both the camera and the light are outside of the object. Reflection(with direct illumination): should be used when both the camera and the light are outside of the object. This mode also computes the direct illumination at the sss ray exit point. Transmission: should be used when the light is inside the object while the camera is outside. " />
3030
<input name="albedoInversionMethod" type="integer" enum="Pixar,Chiang" enumvalues="0,1" value="0" uiname="Albedo Inversion Method" uifolder="Advanced"
3131
doc="Decides which albedo inversion methods is used. Pixar: Does the Pixar Path Traced SSS default albedo inversion. Chiang: Does Chiang's albedo inversion (with no dmfp remapping). The look is closer to Arnold Standard Surface randomwalk." />

source/MaterialXCore/Value.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,13 @@ template <class T> void stringToData(const string& str, enable_if_mx_matrix_t<T>
8484

8585
template <class T> void stringToData(const string& str, enable_if_std_vector_t<T>& data)
8686
{
87-
for (const string& token : splitString(str, ARRAY_VALID_SEPARATORS))
87+
// This code path parses an array of arbitrary substrings, so we split the string
88+
// in a fashion that preserves substrings with internal spaces.
89+
const string COMMA_SEPARATOR = ",";
90+
for (const string& token : splitString(str, COMMA_SEPARATOR))
8891
{
8992
typename T::value_type val;
90-
stringToData(token, val);
93+
stringToData(trimSpaces(token), val);
9194
data.push_back(val);
9295
}
9396
}

source/MaterialXRender/Util.cpp

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -127,46 +127,18 @@ unsigned int getUIProperties(InputPtr input, const string& target, UIProperties&
127127

128128
if (input->getIsUniform())
129129
{
130-
string enumString = input->getAttribute(ValueElement::ENUM_ATTRIBUTE);
131-
if (!enumString.empty())
130+
uiProperties.enumeration = input->getTypedAttribute<StringVec>(ValueElement::ENUM_ATTRIBUTE);
131+
if (!uiProperties.enumeration.empty())
132132
{
133-
uiProperties.enumeration = splitString(enumString, ",");
134-
if (!uiProperties.enumeration.empty())
135-
propertyCount++;
133+
propertyCount++;
136134
}
137135

138-
const string& enumerationValues = input->getAttribute(ValueElement::ENUM_VALUES_ATTRIBUTE);
136+
StringVec enumerationValues = input->getTypedAttribute<StringVec>(ValueElement::ENUM_VALUES_ATTRIBUTE);
139137
if (!enumerationValues.empty())
140138
{
141-
const string& elemType = input->getType();
142-
const TypeDesc* typeDesc = TypeDesc::get(elemType);
143-
if (typeDesc->isScalar() || typeDesc->isFloat2() || typeDesc->isFloat3() ||
144-
typeDesc->isFloat4())
145-
{
146-
StringVec stringValues = splitString(enumerationValues, ",");
147-
string valueString;
148-
size_t elementCount = typeDesc->getSize();
149-
elementCount--;
150-
size_t count = 0;
151-
for (const string& val : stringValues)
152-
{
153-
if (count == elementCount)
154-
{
155-
valueString += val;
156-
uiProperties.enumerationValues.push_back(Value::createValueFromStrings(valueString, elemType));
157-
valueString.clear();
158-
count = 0;
159-
}
160-
else
161-
{
162-
valueString += val + ",";
163-
count++;
164-
}
165-
}
166-
}
167-
else
139+
for (const string& val : enumerationValues)
168140
{
169-
uiProperties.enumerationValues.push_back(Value::createValue(enumerationValues));
141+
uiProperties.enumerationValues.push_back(Value::createValueFromStrings(val, input->getType()));
170142
}
171143
if (uiProperties.enumeration.size() != uiProperties.enumerationValues.size())
172144
{

source/MaterialXTest/MaterialXCore/Value.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ TEST_CASE("Typed values", "[value]")
110110
mx::BoolVec{true, true, true});
111111
testTypedValue(mx::FloatVec{1.0f, 2.0f, 3.0f},
112112
mx::FloatVec{4.0f, 5.0f, 6.0f});
113-
testTypedValue(mx::StringVec{"one", "two", "three"},
114-
mx::StringVec{"four", "five", "six"});
113+
testTypedValue(mx::StringVec{"Item A", "Item B", "Item C"},
114+
mx::StringVec{"Item D", "Item E", "Item F"});
115115

116116
// Alias types
117117
testTypedValue<long>(1l, 2l);

0 commit comments

Comments
 (0)