diff --git a/javascript/MaterialXTest/element.spec.js b/javascript/MaterialXTest/element.spec.js index cbb672c5c2..bafee4d6af 100644 --- a/javascript/MaterialXTest/element.spec.js +++ b/javascript/MaterialXTest/element.spec.js @@ -164,3 +164,28 @@ describe('Element', () => }); }); }); + +describe('Equivalence', () => +{ + let mx, doc, doc2 + + before(async () => { + mx = await Module(); + doc = mx.createDocument(); + doc.addNodeGraph("graph"); + doc2 = mx.createDocument(); + doc2.addNodeGraph("graph1"); + }); + + it('Compare document equivalency', () => + { + let options = new mx.ElementEquivalenceOptions(); + let differences = {}; + options.performValueComparisons = false; + let result = doc.isEquivalent(doc2, options, differences); + expect(result).to.be.false; + expect(differences.message).to.not.be.empty; + result = doc.isEquivalent(doc2, options, undefined); + expect(result).to.be.false; + }); +}); diff --git a/source/JsMaterialX/JsMaterialXCore/JsElement.cpp b/source/JsMaterialX/JsMaterialXCore/JsElement.cpp index c912d036c1..31670ad090 100644 --- a/source/JsMaterialX/JsMaterialXCore/JsElement.cpp +++ b/source/JsMaterialX/JsMaterialXCore/JsElement.cpp @@ -35,11 +35,35 @@ namespace mx = MaterialX; EMSCRIPTEN_BINDINGS(element) { + ems::class_("ElementEquivalenceOptions") + .constructor<>() + .property("performValueComparisons", &mx::ElementEquivalenceOptions::performValueComparisons) + .property("floatFormat", &mx::ElementEquivalenceOptions::floatFormat) + .property("floatPrecision", &mx::ElementEquivalenceOptions::floatPrecision) + .function("setAttributeExclusionList", ems::optional_override([](mx::ElementEquivalenceOptions& self, const std::vector& exclusionList) + { + self.attributeExclusionList = std::set(exclusionList.begin(), exclusionList.end()); + })); + ems::class_("Element") .smart_ptr>("Element") .smart_ptr>("Element") // mx::ConstElementPtr .function("equals", ems::optional_override([](mx::Element& self, const mx::Element& rhs) { return self == rhs; })) .function("notEquals", ems::optional_override([](mx::Element& self, const mx::Element& rhs) { return self != rhs; })) + .function("isEquivalent", ems::optional_override([](mx::Element &self, const mx::Element& rhs, + const mx::ElementEquivalenceOptions& options, + ems::val message = ems::val::undefined()) + { + mx::ConstElementPtr rhsPtr = rhs.getSelf(); + std::string nativeMessage; + bool handleMessage = !message.isUndefined() && message.typeOf().as() == "object"; + bool res = self.isEquivalent(rhsPtr, options, handleMessage ? &nativeMessage : nullptr); + if (!res && handleMessage) + { + message.set("message", nativeMessage); + } + return res; + })) .function("setCategory", &mx::Element::setCategory) .function("getCategory", &mx::Element::getCategory) .function("setName", &mx::Element::setName)