MPxDeformer::deform() triggering MPxLocatorNode::draw() at runtime

153 views
Skip to first unread message

vince touache

unread,
Dec 14, 2021, 5:51:42 AM12/14/21
to Python Programming for Autodesk Maya
hi folks, 

I'm building an MPxLocatorNode to use in combination with an MPxDeformerNode for debugging purpose (i.e. Deformer sends custom data to Locator that will in turn draw those data, thanks to Marcus' repo)
My problem is with evaluation; I would like to update Locator everytime Deformer::deform() is called, but instead, Locator's evaluation is hooked to Deformer::compute(), whose triggering is not in sync with Deformer::deform()
I'm a bit rusty when it comes to nodes evaluations, so I tried to play with attributeAffects but falls into a loop (e.g. if Deformer.inputGeom affects Deformer.outputData, I get a crash (from an evaluation loop, I suppose)

What would be a clean way to make sure my Locator::draw() is triggered when my Deformer::deform() is called?

Side question, is it a good approach to link 2 nodes, with one for debugging ? It sounds clean and maya-friendly to me, but I'd be curious to know if there are other valid approaches?

Thank you

Marcus Ottosson

unread,
Dec 14, 2021, 6:31:57 AM12/14/21
to python_in...@googlegroups.com

Happy to see it coming in handy xD Not sure how you found it though, maybe Google?

I can’t help you with MPxLocatorNode::draw other than to say “don’t use it”. That’s Legacy Viewport stuff.

If you absolutely have to use it - some are still stuck on Legacy Viewport unfortunately - then read no further as this only applies to Viewport 2.

  1. Implement a MPxDrawOverride for your MPxLocatorNode
  2. In that subclass, implement addUIDrawables
  3. Use MUIDrawManager for your debug draw

The draw manager has a fantastic and simple API for drawing the basic stuff you need for debugging, like lines, spheres, HUD elements, you name it.

Just look at this API, it’s great. Especially compared to drawing with barebones OpenGL.

MColor red(1.0f, 0.0f, 0.0f);
painter.beginDrawable();
painter.setColor( red );
painter.line( MPoint(0, 0, 0), MPoint(1, 1, 1) );
painter.line( MPoint(0, 0, 0), MPoint(-1, -1, 5) );
painter.endDrawable();

With this, your the addUIDrawables function is called under 3 conditions.

  1. It’s set to be always dirty
  2. It’s told to be dirty
  3. Maya’s viewport is force refreshed, or otherwise force dirtied

You can tell it to always be dirty, in which case it’ll update alongside any update to the viewport. See isAlwaysDirty

Without that, you can tell it to be dirty from within itself or another node, by calling:

MHWRender::MRenderer::setGeometryDrawDirty(thisMObject());

This should be what you’re looking for. Ideally it would happen in your MPxLocatorNode::compute, whereby your locator has an attribute that is affected by your deformer. E.g. MyDeformer::deformed -> MyLocator::wasDeformed. Then your deformed could just MPlug::setBool() on that attribute, and your locator would oblige.

Side question, is it a good approach to link 2 nodes, with one for debugging ? It sounds clean and maya-friendly to me, but I’d be curious to know if there are other valid approaches?

Totally reasonable. Draw nodes for drawing things, deform nodes for deforming things. You’d normally wrap these up in a command that creates, names and connects these as appropriate. Also mark one of the nodes as automatically deleted once the connections between them is removed.


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/9be7e4ae-1108-4f8e-901d-ad2d7e591010n%40googlegroups.com.

vince touache

unread,
Dec 14, 2021, 4:06:42 PM12/14/21
to Python Programming for Autodesk Maya
hi Marcus! 
Thanks for the answer. I was totally unclear in my first post, but I am indeed using addUiIDrawable, not the legacy draw! It was more a misuse of language.

I tried turning on the isAlwaysDirty for debugging purpose (I'll see keep optimization for later!), and it does call the drawing part correctly! So it seems my issue comes from transferring data b/w the deformer and the locator.
My chain of evaluation is happening in this order (afaik):
1. deformer.deform()
2.a deformer.compute()
2.b deformer.computeOutputData() (called from inside compute, populates data into my custom object passed via attribute)
3. locator.addUiDrawables() (which will query what has been put into my custom data)

The drawing part is now called constantly (thanks to you Marcus), but deformer.compute(), responsible for updating the data object to draw, is not called when the mesh deforms. I would be tempted to set something like
attributeAffects(any_input, my_custom_output_data)
but that results in a crash every single time and I can't find any good reason, so I was thinking MPxDeformers were following a different logic from MPxNodes?

Wrapping my deformer/locator into a single command is what I had in mind (that's how we were working in a previous studio where I was doing RnD), but I had no idea deleting nodes on disconnection was something the user had control over! Do you remember which command is involved in this mechanism?

Thank you

vince touache

unread,
Dec 14, 2021, 5:33:19 PM12/14/21
to Python Programming for Autodesk Maya
weird, looks like I found what was causing the crash.
In my computeOutputData, I was accessing the inputValue, which was causing (I suppose) a cycle. But this was actually not used at all later in the method, so I just removed it and now it's evaluating correctly, my attributeAffects doesn't create any crash, and the drawing doesn't even have to be always dirty!
Thank you Marcus, I learnt not even one thing, but several, today! (I'm still interested to know if there is a command to tag/untag a maya node for deletion if we disconnect its inputs!)

cheers


Screen Shot 2021-12-14 at 23.30.38.png

Marcus Ottosson

unread,
Dec 23, 2021, 4:29:01 AM12/23/21
to python_in...@googlegroups.com

Remembered there was another question at the end of your last message, have a look at existWithoutInConnections.

Best,
Marcus


vince touache

unread,
Dec 26, 2021, 6:43:08 AM12/26/21
to Python Programming for Autodesk Maya
awesome, I didn't know about it! Thanks so much Marcus!!
Reply all
Reply to author
Forward
0 new messages