Skip to content

Commit

Permalink
Merge pull request #14 from yantor3d/rporter/MPlug
Browse files Browse the repository at this point in the history
Implement MPlug getter/setter methods
  • Loading branch information
mottosso committed May 10, 2021
2 parents 1cdef7e + 26fde24 commit edca428
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 31 deletions.
110 changes: 81 additions & 29 deletions src/MPlug.inl
Original file line number Diff line number Diff line change
Expand Up @@ -23,51 +23,75 @@ plug.def(py::init<>())
}, R"pbdoc(Returns a plug for the array of plugs of which this plug is an element.)pbdoc")

.def("asBool", [](MPlug & self) -> bool {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asBool();
}, R"pbdoc(Retrieves the plug's value, as a boolean.)pbdoc")

.def("asChar", [](MPlug & self) -> char {
throw std::logic_error{"Function not yet implemented."};
.def("asChar", [](MPlug & self) -> int {
plug::assert_not_null(self);

return (self.asChar());
}, R"pbdoc(Retrieves the plug's value, as a single-byte integer.)pbdoc")

.def("asDouble", [](MPlug & self) -> double {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asDouble();
}, R"pbdoc(Retrieves the plug's value, as a double-precision float.)pbdoc")

.def("asFloat", [](MPlug & self) -> float {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asFloat();
}, R"pbdoc(Retrieves the plug's value, as a single-precision float.)pbdoc")

.def("asInt", [](MPlug & self) -> int {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asInt();
}, R"pbdoc(Retrieves the plug's value, as a regular integer.)pbdoc")

.def("asMAngle", [](MPlug & self) -> MAngle {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asMAngle();
}, R"pbdoc(Retrieves the plug's value, as an MAngle.)pbdoc")

.def("asMDataHandle", [](MPlug & self) -> MDataHandle {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asMDataHandle();
}, R"pbdoc(Retrieve the current value of the attribute this plug references.)pbdoc")

.def("asMDistance", [](MPlug & self) -> MDistance {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asMDistance();
}, R"pbdoc(Retrieves the plug's value, as an MDistance.)pbdoc")

.def("asMObject", [](MPlug & self) -> MObject {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asMObject();
}, R"pbdoc(Retrieves the plug's value, as as an MObject containing a direct reference to the plug's data.)pbdoc")

.def("asMTime", [](MPlug & self) -> MTime {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asMTime();
}, R"pbdoc(Retrieves the plug's value, as an MTime.)pbdoc")

.def("asShort", [](MPlug & self) -> short {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

return self.asShort();
}, R"pbdoc(Retrieves the plug's value, as a short integer.)pbdoc")

.def("asString", [](MPlug & self) -> MString {
throw std::logic_error{"Function not yet implemented."};
.def("asString", [](MPlug & self) -> std::string {
plug::assert_not_null(self);

return std::string(self.asString().asChar());
}, R"pbdoc(Retrieves the plug's value, as a string.)pbdoc")

.def("attribute", [](MPlug & self) -> MObject {
Expand Down Expand Up @@ -418,59 +442,87 @@ Note that the behavior of connectedTo() is identical to destinationsWithConversi
}, R"pbdoc(Switches the plug to reference the given attribute of the same node as the previously referenced attribute.)pbdoc")

.def("setBool", [](MPlug & self, bool value) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setBool(value);
}, R"pbdoc(Sets the plug's value as a boolean.)pbdoc")

.def("setChar", [](MPlug & self, char value) {
throw std::logic_error{"Function not yet implemented."};
.def("setChar", [](MPlug & self, int value) {
plug::assert_not_null(self);

self.setChar(char(value));
}, R"pbdoc(Sets the plug's value as a single-byte integer.)pbdoc")

.def("setDouble", [](MPlug & self, double value) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setDouble(value);
}, R"pbdoc(Sets the plug's value as a double-precision float.)pbdoc")

.def("setFloat", [](MPlug & self, float value) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setFloat(value);
}, R"pbdoc(Sets the plug's value as a single-precision float.)pbdoc")

.def("setInt", [](MPlug & self, int value) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setInt(value);
}, R"pbdoc(Sets the plug's value as a regular integer.)pbdoc")

.def("setMAngle", [](MPlug & self, MAngle angle) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setMAngle(angle);
}, R"pbdoc(Sets the plug's value as an MAngle.)pbdoc")

.def("setMDataHandle", [](MPlug & self, MDataHandle dataHandle) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setMDataHandle(dataHandle);
}, R"pbdoc(Sets the plug's value as a data handle.)pbdoc")

.def("setMDistance", [](MPlug & self, MDistance distance) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setMDistance(distance);
}, R"pbdoc(Sets the plug's value as an MDistance.)pbdoc")

.def("setMObject", [](MPlug & self, MObject object) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setMObject(object);
}, R"pbdoc(Sets the plug's value as an MObject.)pbdoc")

.def("setMPxData", [](MPlug & self, MPxData *data) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setMPxData(data);
}, R"pbdoc(Sets the plug's value using custom plug-in data.)pbdoc")

.def("setMTime", [](MPlug & self, MTime time) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setMTime(time);
}, R"pbdoc(Sets the plug's value as an MTime.)pbdoc")

.def("setNumElements", [](MPlug & self, unsigned int num_elements) {
throw std::logic_error{"Function not yet implemented."};
}, R"pbdoc(Pre-allocates space for count elements in an array of plugs.)pbdoc")

.def("setShort", [](MPlug & self, short value) {
throw std::logic_error{"Function not yet implemented."};
plug::assert_not_null(self);

self.setShort(value);
}, R"pbdoc(Sets the plug's value as a short integer.)pbdoc")

.def("setString", [](MPlug & self, MString value) {
throw std::logic_error{"Function not yet implemented."};
.def("setString", [](MPlug & self, std::string value) {
plug::assert_not_null(self);

MString string(value.c_str());

self.setString(string);
}, R"pbdoc(Sets the plug's value as a string.)pbdoc")

.def("source", [](MPlug & self) -> MPlug {
Expand Down
2 changes: 1 addition & 1 deletion test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ if (-not $args.count) {
$directory = $args[0]
}

."$env:MAYA_LOCATION/bin/mayapy.exe" -m nose -xv $directory
."$env:MAYA_LOCATION/bin/mayapy.exe" -B -m nose -xv $directory
152 changes: 151 additions & 1 deletion tests/test_MPlug.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Test suite for MPlug bindings."""

import copy
import nose.tools
import six
import unittest
Expand All @@ -9,6 +10,7 @@

import cmdc


def p(base, *args):
"""Construct a plug string from the given attributes."""

Expand Down Expand Up @@ -53,7 +55,7 @@ def test_info(self):

# You would think it would return the full plug path, but it doesn't...
assert plug.info() == p(self.node, 'branch', 0, 'leaf')


class TestArrayMethods(unittest.TestCase):
"""Tests for MPlug methods bindings for array/element plugs."""
Expand Down Expand Up @@ -378,3 +380,151 @@ def test_sourceWithConversion(self):
assert tgt_plug.sourceWithConversion().node().hasFn(cmdc.Fn.kUnitConversion), 'Plug.sourceWithConversion skipped over conversion node'

nose.tools.assert_raises(ValueError, cmdc.Plug().sourceWithConversion)


def test_asType_methods():
"""Test for MPlug::as* bindings."""

for (method_name, value, add_attr_kwargs, set_attr_kwargs) in [
('asBool', True, {'at': 'bool'}, {}),
('asChar', ord('A'), {'at': 'char'}, {}),
('asDouble', 1.0, {'at': 'double'}, {}),
('asFloat', 1.0, {'at': 'float'}, {}),
('asInt', 5, {'at': 'long'}, {}),
# asMAngle - not yet implemented
# asMDataHandle - not yet implemented
# asMDistance - not yet implemented
# asMObject - custom test (see below)
# asMTime - not yet implemented
('asShort', 3, {'at': 'enum', 'enumName': 'a:b:c:d'}, {}),
('asString', 'hello', {'dt': 'string'}, {'type': 'string'}),
]:
# Somehow, this works
test_asType_methods.__doc__ = """Test for MPlug::{} bindings.""".format(method_name)

yield check_asType_method, method_name, value, add_attr_kwargs, set_attr_kwargs


def check_asType_method(method_name, value, add_attr_kwargs, set_attr_kwargs):
"""Test for MPlug::as* bindings."""

node = cmds.createNode('network')

attr = p(node, 'attr')

cmds.addAttr(node, ln='attr', **add_attr_kwargs)
cmds.setAttr(attr, value, **set_attr_kwargs)

plug = cmdc.SelectionList().add(attr).getPlug(0)

method = getattr(plug, method_name)

expected = value
actual = method()

error_message = (
'Plug method {} returned the wrong value - expected: {}, actual: {}'
.format(
method_name, expected, actual
)
)

if isinstance(expected, float):
assert abs(expected - actual) <= 1e-5, error_message
else:
assert expected == actual, error_message


def test_asMObject():
"""Test for MPlug::asMObject bindings."""

cube, = cmds.polyCube(constructionHistory=False)
mesh, = cmds.listRelatives(cube, children=True, type='mesh')

plug = cmdc.SelectionList().add(p(mesh, 'worldMesh')).getPlug(0)

value = plug.asMObject()

assert value is not None, 'Plug.asMObject returned a null'
assert not value.isNull(), 'Plug.asMObject returned a null MObject'
assert value.hasFn(cmdc.Fn.kMesh), \
'Plug.asMObject returned an object of type {} instead of kMesh'.format(value.apiTypeStr())


def test_setType_methods():
"""Test for MPlug::as* bindings."""

for (method_name, value, add_attr_kwargs) in [
('setBool', True, {'at': 'bool'}),
('setChar', ord('A'), {'at': 'char'}),
('setDouble', 1.0, {'at': 'double'}),
('setFloat', 1.0, {'at': 'float'}),
('setInt', 5, {'at': 'long'}),
# setMAngle - not yet implemented
# setMDataHandle - not yet implemented
# setMDistance - not yet implemented
# setMObject - custom test (see below)
# setMPxData - not yet implemented
# setMTime - not yet implemented
('setShort', 3, {'at': 'enum', 'enumName': 'a:b:c:d'}),
('setString', 'hello', {'dt': 'string'}),
]:
# Somehow, this works
test_setType_methods.__doc__ = """Test for MPlug::{} bindings.""".format(method_name)

yield check_setType_method, method_name, value, add_attr_kwargs


def check_setType_method(method_name, value, add_attr_kwargs):
"""Test for MPlug::set* bindings."""

node = cmds.createNode('network')

attr = p(node, 'attr')

cmds.addAttr(node, ln='attr', **add_attr_kwargs)

plug = cmdc.SelectionList().add(attr).getPlug(0)

method = getattr(plug, method_name)
method(value)

expected = value
actual = cmds.getAttr(attr)

error_message = (
'Plug method {} set the wrong value - expected: {}, actual: {}'
.format(
method_name, expected, actual
)
)

if isinstance(expected, float):
assert abs(expected - actual) <= 1e-5, error_message
else:
assert expected == actual, error_message


def test_setMObject():
"""Test for MPlug::setMObject bindings."""

node = cmds.createNode('network')

cmds.addAttr(node, ln='attr', dt='mesh')

cube, = cmds.polyCube(constructionHistory=False)
mesh, = cmds.listRelatives(cube, children=True, type='mesh')

src_plug = cmdc.SelectionList().add(p(mesh, 'worldMesh')).getPlug(0)
dst_plug = cmdc.SelectionList().add(p(node, 'attr')).getPlug(0)

src_value = src_plug.asMObject()

dst_plug.setMObject(src_value)

dst_value = dst_plug.asMObject()

assert dst_value is not None, 'Plug.asMObject returned a null'
assert not dst_value.isNull(), 'Plug.asMObject returned a null MObject'
assert dst_value.hasFn(cmdc.Fn.kMesh), \
'Plug.asMObject returned an object of type {} instead of kMesh'.format(value.apiTypeStr())

0 comments on commit edca428

Please sign in to comment.