[PyMel] - Weird behavior with pm.artUserPaintCtx "duringStrokeCmd"

Hey folks,

Not sure if im going mad / discovered a Maya bug or am generally just failing epically.

But… can someone try running the code below in Maya 2011 or greater. [ I’m using 2012 ]


myBrush = pm.artUserPaintCtx()
pm.artUserPaintCtx(myBrush, edit=True, duringStrokeCmd='print "During!";', afterStrokeCmd='print "After!";', beforeStrokeCmd='print "Before!";')
pm.setToolTo(myBrush)

print pm.artUserPaintCtx(myBrush, query=True, beforeStrokeCmd=True)
print pm.artUserPaintCtx(myBrush, query=True, duringStrokeCmd=True)
print pm.artUserPaintCtx(myBrush, query=True, afterStrokeCmd=True)


Is it just me whos having the during command returned as a list / reason why it never prints “During!” when stroking.

Cheers

~ Pirate Joe :slight_smile:

The returned values i get are:

print "Before!";
[u'print "During!";']
print "After!";

I get the same results in 2012

Ok… least I’m not going mad, i assume you cant get the during command to work either then?

Ok being a stubborn git, just tried being cheeky and setting the command via mel.eval

import pymel.core as pm
import maya.mel as mel

myBrush = pm.artUserPaintCtx()
pm.artUserPaintCtx(myBrush, edit=True, duringStrokeCmd='print "During!";', afterStrokeCmd='print "After!!";', beforeStrokeCmd='print "Before!!";')
printCommand = "\"print \\\"test\\\";\" "
setDSK = "artUserPaintCtx -e -dsk "+printCommand+myBrush+";"
mel.eval(setDSK)
print pm.artUserPaintCtx(myBrush, query=True, beforeStrokeCmd=True)
print pm.artUserPaintCtx(myBrush, query=True, duringStrokeCmd=True)
print pm.artUserPaintCtx(myBrush, query=True, afterStrokeCmd=True)
pm.setToolTo(myBrush)

sadly same result :frowning:

[u'print "test";']

I guess next thing to try is to set the whole artUserPaintCtx in mel as the duringStrokeCmd seems to work when being used in a mel script… will report back my findings assuming noone else can find a solution first!

edit: Same / even more insane result:


AnotherTest = mel.eval("artUserPaintCtx testme3")
print pm.artUserPaintCtx(AnotherTest, query=True, beforeStrokeCmd=True)
print pm.artUserPaintCtx(AnotherTest, query=True, duringStrokeCmd=True)
print pm.artUserPaintCtx(AnotherTest, query=True, afterStrokeCmd=True)

which gave me




[u'']


facepalm

Any suggestions? :frowning: [ Other than creating the brush itself as a seperate mel script and hooking it back to my Pymel script where relevent ]

My guess as to why it’s returning a list is that the assumption is you might be making multiple strokes, so it’s returning a value per stroke…

Aye i did wonder if that was the case myself, but if that were the case why would it be adding the command you feed into it as an entry in the list?

Anyway, my boss has raised it with AutoDesk along with some other things that have been driving us spare, I’ll post the official responce when it comes :slight_smile:

I think it might be because you are using query=True.

“The passed string is executed as a MEL command immediately after the end of a stroke. C: Default is no command. Q: When queried, it returns the current command

When I use edit=True it returns:

artUserPaintCtx6
artUserPaintCtx6
artUserPaintCtx6

I’ve never used this command, so I don’t know what you do expect as output, but does this help?

[edit: oops, I see you want it to print the strings. Posted too quickly.]

Ha ultimatly i just want it to work :slight_smile:

My current opinion is that the duringStroke command is broken / failing because once its been set, internally the command gets changed to a list not a string unlike the before / after stroke commands.

I have since posting this thread written a mel script to try and set the brush up, but i couldnt get the during stroke command to work in mel either :-/

Has anyone had any success creating a paintBrush tool in general?

[ My original tool used the before / after stroke commands on the vertex selection brush, I’m trying to improve that tool by applying values to the selected verts “live” as the user strokes across a mesh rather than after completion of a stroke, which is how i came to be looking at the paint scripts tool because it had the duringStroke event command, I’m open to other ways of acheiving the same goal though if anyone has one! :slight_smile: ]

Word back from Autodesk:

"
Thanks for logging this with us. I see the same thing and can’t think of an explanation why duringStrokeCmd returns an array instead of the string. You’d expect to see the same result for all three …StrokeCmd’s.

I’ve passed this to our developers.
"

edit: had an idea, but didn’t understand what was going on. Sorry.

No worries, though what was your idea? :smiley: curious anyway

I was trying to pass the artUserPaintCtx through a function using decorators which would give you some feedback for when the function entered and exited. I was trying to rebuild the functionality that way.

Referencing this: Stumbling Toward 'Awesomeness'Python: Simple Decorator Example - Stumbling Toward 'Awesomeness'

Cool, never seen those before - I’ll read up :slight_smile:

Cheers - even if it dosent help with this problem :smiley:

Yeah this is still broken in Maya 2015.

And it’s also still broken in Maya 2017

<sigh>

And it’s broken in straight mel, too.

<long sigh>

This is a very old topic, but the issue is still there, at least in Maya 2019… However, this seems to work for some reason :smiley: :

from maya.mel import eval as mel
import pymel.core as pm

def afterStrokeCmd():
    print("After Stroke")
    
def beforeStrokeCmd():
    print("Before Stroke")
    
def duringStrokeCmd():
    print("During Stroke")
    return True
    
def initializeCmd(name):
    return ""

def setValueCmd():
    print("Set Value")

mel('ScriptPaintTool;')
myBrush = pm.currentCtx()
pm.artUserPaintCtx(myBrush, edit=True, toolSetupCmd='python("initializeCmd(myBrush)")')
pm.artUserPaintCtx(myBrush, edit=True, initializeCmd='python("initializeCmd(myBrush)")', setValueCommand='python("setValueCmd()")', toolCleanupCmd="", getSurfaceCommand="", getArrayAttrCommand="", chunkCommand="", duringStrokeCmd='python("duringStrokeCmd()")', afterStrokeCmd='python("afterStrokeCmd()")', beforeStrokeCmd='python("beforeStrokeCmd()")')

print pm.artUserPaintCtx(myBrush, query=True, beforeStrokeCmd=True)
print pm.artUserPaintCtx(myBrush, query=True, duringStrokeCmd=True)
print pm.artUserPaintCtx(myBrush, query=True, afterStrokeCmd=True)

Thought I would share, maybe it will be useful for someone.

Nevermind, it works if the tool is set to ‘userPaint’, but not the other ones like ‘colorPerVertex’ :expressionless: