Skip to content

Commit 0beb4ce

Browse files
committed
logical ops
1 parent e81f968 commit 0beb4ce

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

src/Condition.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,83 @@ SELECT_NODE(MVector, SelectVector);
193193
SELECT_NODE(MMatrix, SelectMatrix);
194194
SELECT_NODE(MEulerRotation, SelectRotation);
195195
SELECT_NODE(MQuaternion, SelectQuaternion);
196+
197+
198+
template <typename TType>
199+
inline bool logical_and(TType a, TType b)
200+
{
201+
return a && b;
202+
}
203+
204+
template <typename TType>
205+
inline bool logical_or(TType a, TType b)
206+
{
207+
return a || b;
208+
}
209+
210+
template <typename TType>
211+
inline bool logical_xor(TType a, TType b)
212+
{
213+
return !a != !b;
214+
}
215+
216+
template<typename TAttrType, typename TClass, const char* TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
217+
class LogicalNode : public BaseNode<TClass, TTypeName>
218+
{
219+
public:
220+
static MStatus initialize()
221+
{
222+
createAttribute(input1Attr_, "input1", DefaultValue<TAttrType>());
223+
createAttribute(input2Attr_, "input2", DefaultValue<TAttrType>());
224+
createAttribute(outputAttr_, "output", DefaultValue<bool>(), false);
225+
226+
MPxNode::addAttribute(input1Attr_);
227+
MPxNode::addAttribute(input2Attr_);
228+
MPxNode::addAttribute(outputAttr_);
229+
230+
MPxNode::attributeAffects(input1Attr_, outputAttr_);
231+
MPxNode::attributeAffects(input2Attr_, outputAttr_);
232+
233+
return MS::kSuccess;
234+
}
235+
236+
MStatus compute(const MPlug& plug, MDataBlock& dataBlock) override
237+
{
238+
if (plug == outputAttr_ || (plug.isChild() && plug.parent() == outputAttr_))
239+
{
240+
const auto input1Value = getAttribute<TAttrType>(dataBlock, input1Attr_);
241+
const auto input2Value = getAttribute<TAttrType>(dataBlock, input2Attr_);
242+
243+
setAttribute(dataBlock, outputAttr_, TFuncPtr(input1Value, input2Value));
244+
245+
return MS::kSuccess;
246+
}
247+
248+
return MS::kUnknownParameter;
249+
}
250+
251+
private:
252+
static Attribute input1Attr_;
253+
static Attribute input2Attr_;
254+
static Attribute outputAttr_;
255+
};
256+
257+
template<typename TAttrType, typename TClass, const char* TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
258+
Attribute LogicalNode<TAttrType, TClass, TTypeName, TFuncPtr>::input1Attr_;
259+
260+
template<typename TAttrType, typename TClass, const char* TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
261+
Attribute LogicalNode<TAttrType, TClass, TTypeName, TFuncPtr>::input2Attr_;
262+
263+
template<typename TAttrType, typename TClass, const char* TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
264+
Attribute LogicalNode<TAttrType, TClass, TTypeName, TFuncPtr>::outputAttr_;
265+
266+
#define LOGICAL_NODE(AttrType, NodeName, FuncPtr) \
267+
TEMPLATE_PARAMETER_LINKAGE char name##NodeName[] = #NodeName; \
268+
class NodeName : public LogicalNode<AttrType, NodeName, name##NodeName, FuncPtr> {};
269+
270+
LOGICAL_NODE(bool, AndBool, &logical_and);
271+
LOGICAL_NODE(bool, OrBool, &logical_or);
272+
LOGICAL_NODE(bool, XorBool, &logical_xor);
273+
LOGICAL_NODE(int, AndInt, &logical_and);
274+
LOGICAL_NODE(int, OrInt, &logical_or);
275+
LOGICAL_NODE(int, XorInt, &logical_xor);

src/Plugin.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,17 @@ initializePlugin(MObject pluginObj)
121121
VectorLengthSquared::registerNode(pluginFn, typeId++);
122122

123123
// 1.1.0
124+
AndBool::registerNode(pluginFn, typeId++);
125+
AndInt::registerNode(pluginFn, typeId++);
124126
Average::registerNode(pluginFn, typeId++);
125127
AverageAngle::registerNode(pluginFn, typeId++);
126128
AverageInt::registerNode(pluginFn, typeId++);
127129
AverageMatrix::registerNode(pluginFn, typeId++);
128130
AverageRotation::registerNode(pluginFn, typeId++);
129131
AverageVector::registerNode(pluginFn, typeId++);
130132
AverageQuaternion::registerNode(pluginFn, typeId++);
133+
OrBool::registerNode(pluginFn, typeId++);
134+
OrInt::registerNode(pluginFn, typeId++);
131135
Sum::registerNode(pluginFn, typeId++);
132136
SumAngle::registerNode(pluginFn, typeId++);
133137
SumInt::registerNode(pluginFn, typeId++);
@@ -139,6 +143,8 @@ initializePlugin(MObject pluginObj)
139143
WeightedAverageQuaternion::registerNode(pluginFn, typeId++);
140144
WeightedAverageRotation::registerNode(pluginFn, typeId++);
141145
WeightedAverageVector::registerNode(pluginFn, typeId++);
146+
XorBool::registerNode(pluginFn, typeId++);
147+
XorInt::registerNode(pluginFn, typeId++);
142148

143149
return MS::kSuccess;
144150
}
@@ -238,13 +244,17 @@ uninitializePlugin(MObject pluginObj)
238244
VectorLength::deregisterNode(pluginFn);
239245
VectorLengthSquared::deregisterNode(pluginFn);
240246

247+
AndBool::deregisterNode(pluginFn);
248+
AndInt::deregisterNode(pluginFn);
241249
Average::deregisterNode(pluginFn);
242250
AverageAngle::deregisterNode(pluginFn);
243251
AverageInt::deregisterNode(pluginFn);
244252
AverageMatrix::deregisterNode(pluginFn);
245253
AverageRotation::deregisterNode(pluginFn);
246254
AverageVector::deregisterNode(pluginFn);
247255
AverageQuaternion::deregisterNode(pluginFn);
256+
OrBool::deregisterNode(pluginFn);
257+
OrInt::deregisterNode(pluginFn);
248258
Sum::deregisterNode(pluginFn);
249259
SumAngle::deregisterNode(pluginFn);
250260
SumInt::deregisterNode(pluginFn);
@@ -256,6 +266,8 @@ uninitializePlugin(MObject pluginObj)
256266
WeightedAverageQuaternion::deregisterNode(pluginFn);
257267
WeightedAverageRotation::deregisterNode(pluginFn);
258268
WeightedAverageVector::deregisterNode(pluginFn);
269+
XorBool::deregisterNode(pluginFn);
270+
XorInt::deregisterNode(pluginFn);
259271

260272
return MS::kSuccess;
261273
}

tests/test_condition.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,21 @@ def test_select_matrix(self):
5454

5555
def test_select_quaternion(self):
5656
self.create_node('SelectQuaternion', {'input2': [1.0, 0.0, 0.0, 1.0], 'condition': True}, [1.0, 0.0, 0.0, 1.0])
57+
58+
def test_and_bool(self):
59+
self.create_node('AndBool', {'input1': True, 'input2': True}, True)
60+
61+
def test_and_int(self):
62+
self.create_node('AndInt', {'input1': 1, 'input2': 0}, False)
63+
64+
def test_or_bool(self):
65+
self.create_node('OrBool', {'input1': True, 'input2': True}, True)
66+
67+
def test_or_int(self):
68+
self.create_node('OrInt', {'input1': 0, 'input2': 0}, False)
69+
70+
def test_xor_bool(self):
71+
self.create_node('XorBool', {'input1': True, 'input2': True}, False)
72+
73+
def test_xor_int(self):
74+
self.create_node('XorInt', {'input1': 1, 'input2': 0}, True)

0 commit comments

Comments
 (0)