Skip to content

Commit

Permalink
Merge branch 'AcademySoftwareFoundation:main' into add-nodegraph-hotkey
Browse files Browse the repository at this point in the history
  • Loading branch information
WaffleBoyTom authored Oct 30, 2024
2 parents b7e6a20 + ed450e8 commit 9f29709
Show file tree
Hide file tree
Showing 37 changed files with 929 additions and 287 deletions.
18 changes: 18 additions & 0 deletions documents/Specification/MaterialX.Proposals.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,25 @@ We have a standard 3d fractal noise, but a 2d variant would be useful as well.
* `period` (float or vector3): the positive integer distance at which the noise function returns the same value for input coordinate repeated at that step. Default is 0, meaning the noise is not periodic.
* `in` (float): the 1D coordinate at which the noise is evaluated.

<a id="node-worleynoise2d"> </a>

Expanded 2D Worley noise to support different distance metrics and periodicity.

* **`worleynoise2d`**: 2D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features).
* `metric` (uniform string): the distance metric to return, one of "distance" (Euclidean distance to feature), "distance2" (Euclidean distance squared), "manhattan" or "chebyshev". Default is "distance".
* `period` (float or vector3): the positive integer distance at which the noise function returns the same value for texture coordinates repeated at that step. Default is 0, meaning the noise is not periodic.

<a id="node-worleynoise3d"> </a>

Expanded 3D Worley noise to support different distance metrics and periodicity.

* **`worleynoise3d`**: 3D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features).
* `metric` (uniform string): the distance metric to return, one of "distance" (Euclidean distance to feature), "distance2" (Euclidean distance squared), "manhattan" or "chebyshev". Default is "distance".
* `period` (float or vector3): the positive integer distance at which the noise function returns the same value for position coordinates repeated at that step. Default is 0, meaning the noise is not periodic.

#### Periodic Noises

In #1201 it was decided that separate periodic versions of all of the noises is preferred to adding it to the existing noises.

### Shape Nodes

Expand Down
4 changes: 0 additions & 4 deletions documents/Specification/MaterialX.Specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -887,16 +887,12 @@ Standard Noise nodes:
<a id="node-worleynoise2d"> </a>

* **`worleynoise2d`**: 2D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features).
* `metric` (uniform string): the distance metric to return, one of "distance" (Euclidean distance to feature), "distance2" (Euclidean distance squared), "manhattan" or "chebyshev". Default is "distance".
* `period` (float or vector3): the positive integer distance at which the noise function returns the same value for texture coordinates repeated at that step. Default is 0, meaning the noise is not periodic.
* `jitter` (float): amount to jitter the cell center position, with smaller values creating a more regular pattern. Default is 1.0.
* `texcoord` (vector2): the 2D position at which the noise is evaluated. Default is to use the first set of texture coordinates.

<a id="node-worleynoise3d"> </a>

* **`worleynoise3d`**: 3D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features).
* `metric` (uniform string): the distance metric to return, one of "distance" (Euclidean distance to feature), "distance2" (Euclidean distance squared), "manhattan" or "chebyshev". Default is "distance".
* `period` (float or vector3): the positive integer distance at which the noise function returns the same value for position coordinates repeated at that step. Default is 0, meaning the noise is not periodic.
* `jitter` (float): amount to jitter the cell center position, with smaller values creating a more regular pattern. Default is 1.0.
* `position` (vector3): the 3D position at which the noise is evaluated. Default is to use the current 3D object-space coordinate.

Expand Down
6 changes: 5 additions & 1 deletion libraries/bxdf/translation/standard_surface_to_usd.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,14 @@
</dot>

<!-- Emissive -->
<multiply name="emissiveColor" type="color3">
<multiply name="scaledEmissionColor" type="color3">
<input name="in1" type="color3" interfacename="emission_color" />
<input name="in2" type="float" interfacename="emission" />
</multiply>
<multiply name="emissiveColor" type="color3">
<input name="in1" type="color3" nodename="scaledEmissionColor" />
<input name="in2" type="color3" nodename="coatAttenuation" />
</multiply>

<!-- Opacity -->
<convert name="opacityVector" type="vector3">
Expand Down
20 changes: 3 additions & 17 deletions libraries/bxdf/usd_preview_surface.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -152,16 +152,10 @@
<input name="normal" type="vector3" nodename="surface_normal" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<ifgreater name="transmission_mix_amount" type="float">
<input name="value1" type="float" interfacename="opacityThreshold" />
<input name="value2" type="float" value="0" />
<input name="in1" type="float" value="1" />
<input name="in2" type="float" interfacename="opacity" />
</ifgreater>
<mix name="transmission_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="diffuse_bsdf" />
<input name="bg" type="BSDF" nodename="transmission_bsdf" />
<input name="mix" type="float" nodename="transmission_mix_amount" />
<input name="mix" type="float" interfacename="opacity" />
</mix>

<!-- Specular Workflow -->
Expand All @@ -176,12 +170,8 @@
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" nodename="surface_normal" />
</generalized_schlick_bsdf>
<mix name="specular_bsdf1_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="specular_bsdf1" />
<input name="mix" type="float" nodename="transmission_mix_amount" />
</mix>
<layer name="specular_workflow_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf1_mix" />
<input name="top" type="BSDF" nodename="specular_bsdf1" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>

Expand Down Expand Up @@ -223,12 +213,8 @@
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" nodename="surface_normal" />
</generalized_schlick_bsdf>
<mix name="specular_bsdf2_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="specular_bsdf2" />
<input name="mix" type="float" nodename="transmission_mix_amount" />
</mix>
<layer name="metalness_specular_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf2_mix" />
<input name="top" type="BSDF" nodename="specular_bsdf2" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>
<artistic_ior name="artistic_ior" type="multioutput">
Expand Down
2 changes: 1 addition & 1 deletion source/JsMaterialX/JsMaterialXCore/JsValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ EMSCRIPTEN_BINDINGS(value)
.function("copy", &mx::Value::copy, ems::pure_virtual())
.function("getTypeString", &mx::Value::getTypeString)
.function("getValueString", &mx::Value::getValueString)
.class_function("createValueFromStrings", &mx::Value::createValueFromStrings)
BIND_CLASS_FUNC("createValueFromStrings", mx::Value, createValueFromStrings, 2, 3, stRef, stRef, mx::ConstTypeDefPtr)
.class_function("setFloatFormat", &mx::Value::setFloatFormat)
.class_function("setFloatPrecision", &mx::Value::setFloatPrecision)
.class_function("getFloatFormat", &mx::Value::getFloatFormat)
Expand Down
8 changes: 8 additions & 0 deletions source/MaterialXCore/Definition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,12 @@ vector<UnitDefPtr> UnitTypeDef::getUnitDefs() const
return unitDefs;
}

ValuePtr AttributeDef::getValue() const
{
if (!hasValue())
return ValuePtr();

return Value::createValueFromStrings(getValueString(), getType(), getDocument()->getTypeDef(getType()));
}

MATERIALX_NAMESPACE_END
11 changes: 3 additions & 8 deletions source/MaterialXCore/Definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,11 +423,11 @@ class MX_CORE_API TargetDef : public TypedElement

/// @class Member
/// A member element within a TypeDef.
class MX_CORE_API Member : public TypedElement
class MX_CORE_API Member : public ValueElement
{
public:
Member(ElementPtr parent, const string& name) :
TypedElement(parent, CATEGORY, name)
ValueElement(parent, CATEGORY, name)
{
}
virtual ~Member() { }
Expand Down Expand Up @@ -625,12 +625,7 @@ class MX_CORE_API AttributeDef : public TypedElement
///
/// @return A shared pointer to the typed value of this element, or an
/// empty shared pointer if no value is present.
ValuePtr getValue() const
{
if (!hasValue())
return ValuePtr();
return Value::createValueFromStrings(getValueString(), getType());
}
ValuePtr getValue() const;

/// @}
/// @name Elements
Expand Down
16 changes: 16 additions & 0 deletions source/MaterialXCore/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,22 @@ string ValueElement::getResolvedValueString(StringResolverPtr resolver) const
return resolver->resolve(getValueString(), getType());
}

ValuePtr ValueElement::getValue() const
{
if (!hasValue())
return ValuePtr();

return Value::createValueFromStrings(getValueString(), getType(), getDocument()->getTypeDef(getType()));
}

ValuePtr ValueElement::getResolvedValue(StringResolverPtr resolver) const
{
if (!hasValue())
return ValuePtr();

return Value::createValueFromStrings(getResolvedValueString(resolver), getType(), getDocument()->getTypeDef(getType()));
}

ValuePtr ValueElement::getDefaultValue() const
{
ConstElementPtr parent = getParent();
Expand Down
14 changes: 2 additions & 12 deletions source/MaterialXCore/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -1037,12 +1037,7 @@ class MX_CORE_API ValueElement : public TypedElement
///
/// @return A shared pointer to the typed value of this element, or an
/// empty shared pointer if no value is present.
ValuePtr getValue() const
{
if (!hasValue())
return ValuePtr();
return Value::createValueFromStrings(getValueString(), getType());
}
ValuePtr getValue() const;

/// Return the resolved value of an element as a generic value object, which
/// may be queried to access its data.
Expand All @@ -1052,12 +1047,7 @@ class MX_CORE_API ValueElement : public TypedElement
/// will be created at this scope and applied to the return value.
/// @return A shared pointer to the typed value of this element, or an
/// empty shared pointer if no value is present.
ValuePtr getResolvedValue(StringResolverPtr resolver = nullptr) const
{
if (!hasValue())
return ValuePtr();
return Value::createValueFromStrings(getResolvedValueString(resolver), getType());
}
ValuePtr getResolvedValue(StringResolverPtr resolver = nullptr) const;

/// Return the default value for this element as a generic value object, which
/// may be queried to access its data.
Expand Down
8 changes: 8 additions & 0 deletions source/MaterialXCore/Exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ class MX_CORE_API Exception : public std::exception
string _msg;
};

/// @class ExceptionTypeError
/// An exception that is thrown when a type mismatch is encountered.
class MX_CORE_API ExceptionTypeError : public Exception
{
public:
using Exception::Exception;
};

MATERIALX_NAMESPACE_END

#endif
73 changes: 72 additions & 1 deletion source/MaterialXCore/Value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXCore/Definition.h>
#include <MaterialXCore/Document.h>
#include <MaterialXCore/Value.h>

#include <iomanip>
Expand Down Expand Up @@ -267,12 +269,18 @@ template <class T> ValuePtr TypedValue<T>::createFromString(const string& value)
// Value methods
//

ValuePtr Value::createValueFromStrings(const string& value, const string& type)
ValuePtr Value::createValueFromStrings(const string& value, const string& type, ConstTypeDefPtr typeDef)
{
CreatorMap::iterator it = _creatorMap.find(type);
if (it != _creatorMap.end())
return it->second(value);

if (typeDef && !typeDef->getMembers().empty())
{
// If we're given a TypeDef pointer that has child members, then we can create a new AggregateValue.
return AggregateValue::createAggregateValueFromString(value, type, typeDef);
}

return TypedValue<string>::createFromString(value);
}

Expand All @@ -291,6 +299,69 @@ template <class T> const T& Value::asA() const
return typedVal->getData();
}

template <>
MX_CORE_API bool Value::isA<AggregateValue>() const
{
return dynamic_cast<const AggregateValue*>(this) != nullptr;
}

template <>
MX_CORE_API const AggregateValue& Value::asA<AggregateValue>() const
{
const AggregateValue* typedVal = dynamic_cast<const AggregateValue*>(this);
if (!typedVal)
{
throw ExceptionTypeError("Incorrect type specified for value");
}
return *typedVal;
}

string AggregateValue::getValueString() const
{
if (_data.empty())
return EMPTY_STRING;

std::string result = "{";
std::string separator = "";
for (const auto& val : _data)
{
result += separator + val->getValueString();
separator = ";";
}
result += "}";

return result;
}

AggregateValuePtr AggregateValue::createAggregateValueFromString(const string& value, const string& type, ConstTypeDefPtr typeDef)
{
StringVec subValues = parseStructValueString(value);

AggregateValuePtr result = AggregateValue::createAggregateValue(type);
const auto& members = typeDef->getMembers();

if (subValues.size() != members.size())
{
std::stringstream ss;
ss << "Wrong number of initializers - expect " << members.size();
throw Exception(ss.str());
}

auto doc = typeDef->getDocument();
for (size_t i = 0; i < members.size(); ++i)
{
const auto& member = members[i];

// This will return nullptr if the type is not a listed typedef.
ConstTypeDefPtr subTypeDef = doc->getTypeDef(members[i]->getType());

// Calling Value::createValueFromStrings() here allows support for recursively nested structs.
result->appendValue(Value::createValueFromStrings(subValues[i], member->getType(), subTypeDef));
}

return result;
}

ScopedFloatFormatting::ScopedFloatFormatting(Value::FloatFormat format, int precision) :
_format(Value::getFloatFormat()),
_precision(Value::getFloatPrecision())
Expand Down
Loading

0 comments on commit 9f29709

Please sign in to comment.