maya.cmds and dummyFuncs

298 views
Skip to first unread message

Chadrik

unread,
Oct 6, 2008, 9:39:47 PM10/6/08
to python_inside_maya
today i discovered a bug that escaped me for some time. this post is
more an an FYI than anything else.

from what i can gather from peeking around the maya package, maya
loads a bunch of dummy functions which, when called, trigger the
dynamic loading of the actual function. the problem is that the first
call to the function returns None instead of the actual result ( the
command still does what it should ).

>>> import maya.standalone as ms
>>> ms.initialize()
>>> import maya.cmds as cmds
>>> cmds.shadingNode.__module__
'maya.app.commands'
>>> cmds.shadingNode.__name__
'dummyFunc'
>>> cmds.shadingNode('lambert', asUtility=1) # first time, no result
>>> cmds.shadingNode('lambert', asUtility=1) # second time, we get a result
u'lambert3'
>>> cmds.shadingNode.__module__
'maya.cmds'
>>> cmds.shadingNode.__name__
'shadingNode'

not all commands operate this way, but there's a lot. i'll paste the
list at the bottom of this post. so, anyway, i'll go ahead an send
this to Autodesk support. not sure what other solutions there are for
this.

-chad


alignCtx
allNodeTypes
angleBetween
animCurveEditor
animView
annotate
applyTake
arcLenDimContext
arcLengthDimension
art3dPaintCtx
artAttrCtx
artAttrPaintVertexCtx
artAttrSkinPaintCtx
artAttrTool
artBaseCtx
artFluidAttr
artFluidAttrCtx
artPuttyCtx
artSelectCtx
artSetPaintCtx
artUserPaintCtx
assignInputDevice
attachDeviceAttr
attributeMenu
blendCtx
blendShapeEditor
blendShapePanel
buildBookmarkMenu
buildKeyframeMenu
buttonManip
canCreateManip
changeSubdivComponentDisplayLevel
changeSubdivRegion
channelBox
characterOutlineEditor
clipEditor
clipEditorCurrentTimeCtx
clipSchedulerOutliner
coarsenSubdivSelectionList
createDrawCtx
createLayeredPsdFile
createNurbsCircleCtx
createNurbsConeCtx
createNurbsCubeCtx
createNurbsCylinderCtx
createNurbsPlaneCtx
createNurbsSphereCtx
createNurbsSquareCtx
createNurbsTorusCtx
createPolyConeCtx
createPolyCubeCtx
createPolyCylinderCtx
createPolyHelixCtx
createPolyPipeCtx
createPolyPlaneCtx
createPolyPlatonicSolidCtx
createPolyPrismCtx
createPolyPyramidCtx
createPolySoccerBallCtx
createPolySphereCtx
createPolyTorusCtx
createSubdivRegion
currentTimeCtx
curveAddPtCtx
curveCVCtx
curveEPCtx
curveEditorCtx
curveMoveEPCtx
curveSketchCtx
dagObjectCompare
dbtrace
debug
debugNamespace
debugVar
defaultLightListCheckBox
defineDataServer
defineVirtualDevice
detachDeviceAttr
deviceEditor
devicePanel
dgControl
dgPerformance
dgcount
dgdebug
dgfilter
dgfootprint
dgmodified
dgstats
directKeyCtx
distanceDimContext
distanceDimension
dopeSheetEditor
dpBirailCtx
drawExtrudeFacetCtx
dynPaintCtx
dynPaintEditor
dynParticleCtx
dynRelEdPanel
dynRelEditor
dynSelectCtx
dynWireCtx
enableDevice
eval
exclusiveLightCheckBox
fileBrowserDialog
filter
findType
floatSlider2
flushThumbnailCache
getDefaultBrush
getInputDeviceRange
glRender
glRenderEditor
graphDollyCtx
graphSelectContext
graphTrackCtx
hardwareRenderPanel
headsUpMessage
hyperGraph
hyperPanel
hyperShade
ikHandleCtx
ikHandleDisplayScale
ikSplineHandleCtx
imageWindowEditor
insertJointCtx
insertKeyCtx
iprEngine
itemFilterRenderOld
iterOnNurbs
jointCtx
keyframeOutliner
keyframeRegionCurrentTimeCtx
keyframeRegionDirectKeyCtx
keyframeRegionDollyCtx
keyframeRegionInsertKeyCtx
keyframeRegionMoveKeyCtx
keyframeRegionScaleKeyCtx
keyframeRegionSelectKeyCtx
keyframeRegionSetKeyCtx
keyframeRegionTrackCtx
keyframeStats
latticeDeformKeyCtx
layeredShaderPort
layeredTexturePort
lightListEditor
lightListPanel
listDeviceAttachments
listInputDeviceAxes
listInputDeviceButtons
listInputDevices
listerEditor
loadPlugin
manipMoveContext
manipMoveLimitsCtx
manipOptions
manipRotateContext
manipRotateLimitsCtx
manipScaleContext
manipScaleLimitsCtx
mateCtx
meshIntersectTest
modelCurrentTimeCtx
mouldMesh
mouldSubdiv
moveKeyCtx
movieCompressor
mpBirailCtx
myTestCmd
nop
objstats
openMayaPref
overrideModifier
paintEffectsDisplay
paramDimContext
paramDimension
particleRenderInfo
pfxstrokes
playblast
pluginInfo
polyAppendFacetCtx
polyColorBlindData
polyCreaseCtx
polyCreateFacetCtx
polyCutCtx
polyGeoSampler
polyInstallAction
polyIterOnPoly
polyMergeEdgeCtx
polyMergeFacetCtx
polyOptions
polyPrimitiveMisc
polySelectConstraintMonitor
polySelectCtx
polySelectEditCtx
polySelectEditCtxDataCmd
polyShortestPathCtx
polySlideEdgeCtx
polySplitCtx
polySuperCtx
polyTestPop
polyVertexNormalCtx
preloadRefEd
projFileViewer
projectionContext
projectionManip
propModCtx
psdChannelOutliner
psdConvSolidTxOptions
psdEditTextureFile
psdExport
psdTextureFile
querySubdiv
rampColorPort
rampWidget
rampWidgetAttrless
readTake
recordAttr
recordDevice
refineSubdivSelectionList
renderManip
renderSettings
renderThumbnailUpdate
renderWindowEditor
renderWindowSelectContext
roundCRCtx
sampleImage
saveImage
scaleKeyCtx
sceneEditor
sceneViewer
scriptCtx
selectKeyCtx
selectKeyframe
selectKeyframeRegionCtx
setAttrMapping
setInputDeviceMapping
setKeyCtx
setXformManip
shadingGeometryRelCtx
shadingLightRelCtx
shadingNode
showManipCtx
showShadingGroupAttrEditor
softModContext
soundControl
spBirailCtx
spotLightPreviewPort
srtContext
stitchSurfaceCtx
stroke
subdDisplayMode
subdListComponentConversion
subdToBlind
subdiv
subdivCrease
subdivDisplaySmoothness
subgraph
surfaceSampler
swatchDisplayPort
switchTable
texLatticeDeformContext
texManipContext
texMoveContext
texMoveUVShellContext
texRotateContext
texScaleContext
texSelectContext
texSelectShortestPathCtx
texSmudgeUVContext
texWinToolCtx
textManip
textureLassoContext
texturePlacementContext
textureWindow
threePointArcCtx
timeControl
timePort
timer
transferAttributes
trimCtx
twoPointArcCtx
unassignInputDevice
unloadPlugin
uvSnapshot
view2dToolCtx
viewManip
visor
wireContext
wrinkleContext
writeTake


Matthew Chapman

unread,
Oct 6, 2008, 11:23:00 PM10/6/08
to python_in...@googlegroups.com
It might be a poorly designed optimization they had built because they used one huge module dump for all their commands. dummyFunc would have one in memory code object that gets referenced multiple times. This would make it so functions with very large code object would not be loaded into memory until  the first call.

Olivier Renouard

unread,
Oct 7, 2008, 3:36:30 AM10/7/08
to python_in...@googlegroups.com
Hi,

It also has the effect of not allowing autocompletion in Python IDEs like Eclipse on Maya commands, which is annoying. It works on the api modules though.

-- 
Olivier Renouard

Paul Molodowitch

unread,
Oct 7, 2008, 10:54:04 AM10/7/08
to python_in...@googlegroups.com
Oh, awesome - yeah, I'd noticed that "dummyFunc" thing too, and had
been meaning to look into it.

So, if we want to get the 'actual' info, all we need to do is check if
we got a 'dummyFunc', and if so, call the function, and query it
again?

- Paul

Paul Molodowitch

unread,
Oct 7, 2008, 10:55:54 AM10/7/08
to python_in...@googlegroups.com
Follow up question - I noticed at some point that the list of
functions which are 'dummyFuncs' seems to vary depending on whether
you're in batch mode or not. Will all functions still get the 'real'
function loaded eventually, regardless of whether we're in batch
mode... or will some always stay 'dummies' if we're in batch?

- Paul

Olivier Renouard

unread,
Oct 7, 2008, 11:09:07 AM10/7/08
to python_in...@googlegroups.com
Hi Paul,

All the ui functions / api never get loaded (and actually can't be loaded) when in batch mode. There are some occasions where we test/used to test that in pymel using the about command, so that we don't try to load ui functions in batch mode.
-- 
Olivier Renouard

Chadrik

unread,
Oct 7, 2008, 11:37:44 AM10/7/08
to python_in...@googlegroups.com
>
> So, if we want to get the 'actual' info, all we need to do is check if
> we got a 'dummyFunc', and if so, call the function, and query it
> again?

for commands with a query mode, yes. but i'm afraid many of the
commands, like shadingNode, have no query mode.

we could try to run all the commands at startup to force the real
versions to load, but this would make starting pymel even slower.
plus, there's often not a boilerplate way of executing these commands
so we'd have to maintain a hardcoded list of kwargs for each command
-- could get cumbersome.

if you look at the list of commands, there's a lot that are seldomly
used. i think we should chose the most commonly used and force those
to load.

most common from the dummyFunc list:
subdiv
querySubdiv
shadingNode
channelBox
stroke
pluginInfo

we can filter this list by determining which of have query modes and
handle them elsewhere.

do you see any others that you think should be pre-loaded?


-chad

Paul Molodowitch

unread,
Oct 7, 2008, 1:46:48 PM10/7/08
to python_in...@googlegroups.com
Just a follow up for anyone who might be following this thread:

It looks like they get loaded even if it's an invalid invocation of
the command, so if you're trying to 'automate' their loading,
you don't need to worry about how to invoke them.
Ie, try this:

>>> import maya.standalone as ms
>>> ms.initialize()
>>> import maya.cmds as cmds

>>> cmds.shadingNode.__name__
'dummyFunc'
>>> try:
... cmds.shadingNode(fuzzyBucketsOfFun=None)
>>> except:
... pass
...
>>> cmds.shadingNode.__name__
'shadingNode'

Reply all
Reply to author
Forward
0 new messages