From 0beb4ce779831dd9846c96d2188b94bdc142971a Mon Sep 17 00:00:00 2001 From: Serguei Kalentchouk Date: Fri, 18 May 2018 04:18:15 -0400 Subject: [PATCH] logical ops --- src/Condition.h | 80 +++++++++++++++++++++++++++++++++++++++++ src/Plugin.cpp | 12 +++++++ tests/test_condition.py | 18 ++++++++++ 3 files changed, 110 insertions(+) diff --git a/src/Condition.h b/src/Condition.h index 69a4b47..1b6f91b 100644 --- a/src/Condition.h +++ b/src/Condition.h @@ -193,3 +193,83 @@ SELECT_NODE(MVector, SelectVector); SELECT_NODE(MMatrix, SelectMatrix); SELECT_NODE(MEulerRotation, SelectRotation); SELECT_NODE(MQuaternion, SelectQuaternion); + + +template +inline bool logical_and(TType a, TType b) +{ + return a && b; +} + +template +inline bool logical_or(TType a, TType b) +{ + return a || b; +} + +template +inline bool logical_xor(TType a, TType b) +{ + return !a != !b; +} + +template +class LogicalNode : public BaseNode +{ +public: + static MStatus initialize() + { + createAttribute(input1Attr_, "input1", DefaultValue()); + createAttribute(input2Attr_, "input2", DefaultValue()); + createAttribute(outputAttr_, "output", DefaultValue(), false); + + MPxNode::addAttribute(input1Attr_); + MPxNode::addAttribute(input2Attr_); + MPxNode::addAttribute(outputAttr_); + + MPxNode::attributeAffects(input1Attr_, outputAttr_); + MPxNode::attributeAffects(input2Attr_, outputAttr_); + + return MS::kSuccess; + } + + MStatus compute(const MPlug& plug, MDataBlock& dataBlock) override + { + if (plug == outputAttr_ || (plug.isChild() && plug.parent() == outputAttr_)) + { + const auto input1Value = getAttribute(dataBlock, input1Attr_); + const auto input2Value = getAttribute(dataBlock, input2Attr_); + + setAttribute(dataBlock, outputAttr_, TFuncPtr(input1Value, input2Value)); + + return MS::kSuccess; + } + + return MS::kUnknownParameter; + } + +private: + static Attribute input1Attr_; + static Attribute input2Attr_; + static Attribute outputAttr_; +}; + +template +Attribute LogicalNode::input1Attr_; + +template +Attribute LogicalNode::input2Attr_; + +template +Attribute LogicalNode::outputAttr_; + +#define LOGICAL_NODE(AttrType, NodeName, FuncPtr) \ + TEMPLATE_PARAMETER_LINKAGE char name##NodeName[] = #NodeName; \ + class NodeName : public LogicalNode {}; + +LOGICAL_NODE(bool, AndBool, &logical_and); +LOGICAL_NODE(bool, OrBool, &logical_or); +LOGICAL_NODE(bool, XorBool, &logical_xor); +LOGICAL_NODE(int, AndInt, &logical_and); +LOGICAL_NODE(int, OrInt, &logical_or); +LOGICAL_NODE(int, XorInt, &logical_xor); diff --git a/src/Plugin.cpp b/src/Plugin.cpp index 5ce756e..e1865c8 100644 --- a/src/Plugin.cpp +++ b/src/Plugin.cpp @@ -121,6 +121,8 @@ initializePlugin(MObject pluginObj) VectorLengthSquared::registerNode(pluginFn, typeId++); // 1.1.0 + AndBool::registerNode(pluginFn, typeId++); + AndInt::registerNode(pluginFn, typeId++); Average::registerNode(pluginFn, typeId++); AverageAngle::registerNode(pluginFn, typeId++); AverageInt::registerNode(pluginFn, typeId++); @@ -128,6 +130,8 @@ initializePlugin(MObject pluginObj) AverageRotation::registerNode(pluginFn, typeId++); AverageVector::registerNode(pluginFn, typeId++); AverageQuaternion::registerNode(pluginFn, typeId++); + OrBool::registerNode(pluginFn, typeId++); + OrInt::registerNode(pluginFn, typeId++); Sum::registerNode(pluginFn, typeId++); SumAngle::registerNode(pluginFn, typeId++); SumInt::registerNode(pluginFn, typeId++); @@ -139,6 +143,8 @@ initializePlugin(MObject pluginObj) WeightedAverageQuaternion::registerNode(pluginFn, typeId++); WeightedAverageRotation::registerNode(pluginFn, typeId++); WeightedAverageVector::registerNode(pluginFn, typeId++); + XorBool::registerNode(pluginFn, typeId++); + XorInt::registerNode(pluginFn, typeId++); return MS::kSuccess; } @@ -238,6 +244,8 @@ uninitializePlugin(MObject pluginObj) VectorLength::deregisterNode(pluginFn); VectorLengthSquared::deregisterNode(pluginFn); + AndBool::deregisterNode(pluginFn); + AndInt::deregisterNode(pluginFn); Average::deregisterNode(pluginFn); AverageAngle::deregisterNode(pluginFn); AverageInt::deregisterNode(pluginFn); @@ -245,6 +253,8 @@ uninitializePlugin(MObject pluginObj) AverageRotation::deregisterNode(pluginFn); AverageVector::deregisterNode(pluginFn); AverageQuaternion::deregisterNode(pluginFn); + OrBool::deregisterNode(pluginFn); + OrInt::deregisterNode(pluginFn); Sum::deregisterNode(pluginFn); SumAngle::deregisterNode(pluginFn); SumInt::deregisterNode(pluginFn); @@ -256,6 +266,8 @@ uninitializePlugin(MObject pluginObj) WeightedAverageQuaternion::deregisterNode(pluginFn); WeightedAverageRotation::deregisterNode(pluginFn); WeightedAverageVector::deregisterNode(pluginFn); + XorBool::deregisterNode(pluginFn); + XorInt::deregisterNode(pluginFn); return MS::kSuccess; } diff --git a/tests/test_condition.py b/tests/test_condition.py index a140e56..3c5ec3f 100644 --- a/tests/test_condition.py +++ b/tests/test_condition.py @@ -54,3 +54,21 @@ def test_select_matrix(self): def test_select_quaternion(self): self.create_node('SelectQuaternion', {'input2': [1.0, 0.0, 0.0, 1.0], 'condition': True}, [1.0, 0.0, 0.0, 1.0]) + + def test_and_bool(self): + self.create_node('AndBool', {'input1': True, 'input2': True}, True) + + def test_and_int(self): + self.create_node('AndInt', {'input1': 1, 'input2': 0}, False) + + def test_or_bool(self): + self.create_node('OrBool', {'input1': True, 'input2': True}, True) + + def test_or_int(self): + self.create_node('OrInt', {'input1': 0, 'input2': 0}, False) + + def test_xor_bool(self): + self.create_node('XorBool', {'input1': True, 'input2': True}, False) + + def test_xor_int(self): + self.create_node('XorInt', {'input1': 1, 'input2': 0}, True)