AnimalLogic / AL_omx

AL_omx is an open-source library that provides a thin wrapper around Maya OM2 which makes it easy to manipulate nodes, attributes and connections while retaining the API's performance.
https://animallogic.github.io/AL_omx/
Other
101 stars 6 forks source link

Join forces with cmdx? #3

Open chadrik opened 10 months ago

chadrik commented 10 months ago

I didn't find any examples in the docs for high level equivalents to key maya.cmds functions like ls. Does this exist? If not, you might consider having a look at https://github.com/mottosso/cmdx

chadrik commented 10 months ago

By the way, congrats on open sourcing this!

mottosso commented 10 months ago

Very excited to see this project!

My first dive was trying to learn more about how you manage undo/redo; that was hands down the most challenging aspect of working with OpenMaya. Would love to share notes on that, cmdx has a few years of experience now and spent the first few of those learning the hard way all of the ways in which undo can bite.

cmdx is currently what we use for Ragdoll Dynamics (which coincidentally is also used over there at AL!)

For example: ragdoll/commands.py

Performance is important and was one of the primary reasons for developing it, we generate hundreds of nodes and attributes in milliseconds, some performance graphs here:

Would love to explore whether omx can replace cmdx (or vice versa!)

valerie-bernard commented 10 months ago

Hi Chad and Marcus, thanks for your messages!

@chadrik OMX isn't trying to be an alternative to Maya commands so you won't find equivalents to every command. The ls command in particular we still use all the time, we just wrap the results in XNodes to further work with. These aren't queries we do much in performance critical code so it's not a bottleneck that would motivate us to use a faster alternative.

The goal of OMX is really to have users work with OM2 for performance, but make it easier with a simple explicit syntax for frequent use cases, like creating nodes, setting attributes, creating connections, which happens thousands of times in rigging code for instance. Adding undoability management was so we could always have undoable code without really needing to think about it. The only rule we have is that you should use OMX or OM2 for editing, you're free to use whatever you need (like Maya commands) for queries.

@mottosso You'll find info about OMX undoability here: https://animallogic.github.io/AL_omx/advanced/undoability.html We'll be happy to answer any question you have and update the docs with more information as needed!

mottosso commented 10 months ago

You'll find info about OMX undoability here

Thanks, but that looks like documentation for how to use undo as you have implemented it. It would be great to hear about your experience implementing it, what challenges you faced and what compromises you made whilst doing it. I can see from a brief glance at the source that MPxCommand is involved, which is what we use for cmdx too. But it certainly came with its own set of challenges and is still not perfect - the primary issue being vendoring of cmdx since it creates multiple instances of the MPxCommands that needs registering.

I'm also interested in what considerations were made prior to rolling your own wrapper. I don't expect everyone to know of cmdx - despite ending up 1st on Google with the quary "maya api 2.0 wrapper python" - but there is also:

I'll put together a little comparison of omx and cmdx to both learn and help others learn, it would be amazing to have an equivalent comparison from you!

mottosso commented 9 months ago

Ok! Got rather lengthy, but this was fun. Happy new year everyone!

I think I got it right, but do let me know if I got anything wrong; there's a lot in there.

https://learn.ragdolldynamics.com/blog/20240101_omx_vs_cmdx

mgland commented 8 months ago

Hi all, AL_omx is still in active development and there will be more features coming up, any feedback is appreciated.

Hi @mottosso Thanks for testing AL_omx and the detailed blog on the two! A lot of interesting comparison and technical details there. I didn't find a way to leave comments in the blog, so just regarding two things mentioned in the blog:

Whereby currentModifier will create a new modifier if there is no modifier. I was expecting this to keep returning the same modifier until I call newModifier, but this wasn't the case.

mod = omx.currentModifier()
assert mod is omx.currentModifier()
mod.createDagNode("joint")
assert mod is omx.currentModifier()  # AssertionError

That is not the case. Because by default omx.currentModifier() is getting the current XModifier, but if there is not then it will create one, in immediate mode. The immediate mode modifier will be submitted to MPXCommand for undo purpose then a new XModifier will be created next time needed. Thus, there will be two different modifier instances in this case.

Furthermore, the documentation states: If AL.omx.XModifier._immediate is True, whenever you call its method to edit Maya’s scene data, it will call doIt() to apply the edit to the scene immediately. On the other hand, if AL.omx.XModifier._immediate is False, then you’ll have to manually call AL.omx.doIt() or XModifier.doIt() to apply the edit. However this does not appear true.

mod = omx.XModifier(immediate=False)
assert not mod._immediate
mod.createDagNode("joint")  # Still creates the joint
# mod.doIt()

The document does state the exception for the node creation here .

This is the case except when it comes to node creation. You cannot have a valid om2.MObject immediately when creating a node using a modifier. So regardless of the immediate state, it will always call doIt() automatically after node creation.

mottosso commented 8 months ago

Happy to help, looking forward to future development!