Skip to content

Commit

Permalink
Implement MDagModifier::reparentNode binding
Browse files Browse the repository at this point in the history
  • Loading branch information
yantor3d committed Jun 7, 2021
1 parent 4bf96b0 commit 0604e77
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
34 changes: 31 additions & 3 deletions src/MDagModifier.inl
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ None of the newly created nodes will be added to the DAG until the modifier's do
CHECK_STATUS(status)

return result;
}, // py::arg("typeId"),
// py::arg("parent") = MObject::kNullObj,
},
R"pbdoc(Adds an operation to the modifier to create a DAG node of the specified type.
If a parent DAG node is provided the new node will be parented under it.
Expand All @@ -87,7 +86,36 @@ and it is the transform node which will be returned by the method, not the child
None of the newly created nodes will be added to the DAG until the modifier's doIt() method is called.)pbdoc")

.def("reparentNode", [](MDagModifier & self, MObject node, MObject newParent = MObject::kNullObj) {
throw std::logic_error{"Function not yet implemented."};
validate::is_not_null(node, "Cannot reparent a null object.");
validate::has_fn(
node, MFn::kDagNode,
"Cannot reparent - 'node' must be a 'kDagNode' object , not a '^1s' object."
);

if (!newParent.isNull())
{
validate::has_fn(
newParent, MFn::kDagNode,
"Cannot reparent - 'parent' must be a 'kDagNode' object , not a '^1s' object."
);

MFnDagNode fn(newParent);

if (fn.isChildOf(node))
{
throw std::invalid_argument("Cannot parent a transform to one of its children.");
}
}

if (node == newParent)
{
throw std::invalid_argument("Cannot parent a transform to itself.");
}


MStatus status = self.reparentNode(node, newParent);

CHECK_STATUS(status)
},
R"pbdoc(Adds an operation to the modifier to reparent a DAG node under a specified parent.
Expand Down
70 changes: 70 additions & 0 deletions tests/test_MDagModifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from . import assert_equals, as_obj, as_plug, new_scene

def test_createNode():
return

node = cmds.createNode('transform', name='root')
node_obj = as_obj(node)
null_obj = cmdc.Object()
Expand Down Expand Up @@ -68,3 +70,71 @@ def _createNode_pass(value, parent):

assert not node.isNull(), "Created node is not valid."
assert len(add_nodes) == 1, "`ls` did not return new node."


def test_reparentNode():
node_a = cmds.createNode('transform')
node_b = cmds.createNode('transform')
node_c = cmds.createNode('transform', parent=node_a)
node_d = cmds.createNode('transform', parent=node_c)

node_obj_a = as_obj(node_a)
node_obj_b = as_obj(node_b)
node_obj_c = as_obj(node_c)
node_obj_d = as_obj(node_d)
null_obj = cmdc.Object()

for doc, (node, new_parent) in (
['a null object (parent to world)', (node_obj_c, null_obj)],
['a valid object', (node_obj_c, node_obj_b)],
):
test_reparentNode.__doc__ = """Test MDagModifier::reparentNode if called with {}.""".format(doc)

yield _reparentNode_pass, node, new_parent

not_a_dag = as_obj('time1')
not_a_node = as_plug('persp.message').attribute()

for exc, doc, (node, new_parent) in (
[TypeError, 'an invalid object (not a DAG node)', (node_obj_c, not_a_dag)],
[TypeError, 'an invalid object (not a node)', (node_obj_c, not_a_node)],
[ValueError, 'the same object', (node_obj_c, node_obj_c)],
[ValueError, 'a parent and one of its children', (node_obj_c, node_obj_d)],
):
test_reparentNode.__doc__ = """Test MDagModifier::reparentNode raises an error if called with {}.""".format(doc)

yield _reparentNode_fail, exc, node, new_parent


def _reparentNode_pass(node, new_parent):
fn_node = cmdc.FnDagNode(node)

old_parent = fn_node.parent(0)

mod = cmdc.DagModifier()
mod.reparentNode(node, new_parent)

mod.doIt()
parent = fn_node.parent(0)

if new_parent.isNull():
assert parent == fn_node.dagRoot(), "DagModifier.reparentNode doIt failed"
else:
assert parent == new_parent, "DagModifier.reparentNode doIt failed"

mod.undoIt()
parent = fn_node.parent(0)
assert parent == old_parent, "DagModifier.reparentNode undo failed"

# Parent the node to world before the next test.
mod = cmdc.DagModifier()
mod.reparentNode(node, old_parent)
mod.doIt()


def _reparentNode_fail(exception, node, new_parent):
nose.tools.assert_raises(
exception,
cmdc.DagModifier().reparentNode,
node, new_parent
)

0 comments on commit 0604e77

Please sign in to comment.