Releases: mottosso/cmdx
0.4.8
Node.dump()
now preserves the order in which attributes are present on a node #42- Added the MYPY token to avoid false positives in some static analyzers (eg Pylance from VsCode is Python3-only, so it doesn't know about Python2 types like
basestring
). #41 - Also imports
typing
to add support for type hinting (IDE-only astyping
is not included in Maya's Python distribution). #41
Thanks to @benblo for all of these!
0.4.7
Usability improvements and bug fixes.
- Added
time
argument toPlug.asDouble()
,Plug.asVector()
, andgetAttr()
. - Added
Plug.append(autofill)
to perform a search for the first unconnected value of an array to reuse potentially disconnected plugs and optimise space. - Implemented consistent default unit of
Seconds
for time plugs. - Added
AngleUiUnit()
,TimeUiUnit()
, andDistanceUiUnit()
. - Updated
DGContext
to useSeconds
by default. - Added
unit
argument toDGContext
to support evaluating in different time units.
DGContext
support two different syntaxes for passing in a time unit:
with cmdx.DGContext(1, cmdx.Minutes):
pass
# Or
with cmdx.DGContext(cmdx.Minutes(1)):
pass
0.4.6
A bunch of usability improvements.
- Removed unused
NODE_REUSE
andPLUG_REUSE
environment variables, these were initially proof-of-concept but it's safe to say they were a success and now a fundamental part of cmdx. - Added
Seconds
,Milliseconds
,Minutes
andUiUnit()
as units for plug reading.UiUnits
being a function, since the actual value changes when the user edits Maya's global preferences - Improved
cmdx.Divider
to actually let you control the attribute name (used to be automatic and clever) - Added
plug.writable
for a convenient way of spotting whether you can actually write to a plug - Added
plug.default
to fetch a plug's default value, taking attribute type into account. Similar tocmds.attributeQuery(listDefault=True)
- Added ability to write a 16-tuple as a matrix (rather than having to manually cast it to a
MMatrix
- Added
Node.reset()
andDGModifier.resetAttr()
to reset an attribute to its default value - Added
MatrixType
to handle indexing and future more-granular index manipulation. - Fixed
node["myTimeAttr"].read()
such that it returns a float rather than an int- NOTE: There is a still a discrepancy between what is read and written; read returns a value in the current UI-unit, whereas write takes a value in Seconds. Writing currently doesn't massage the values you put into it so it's a little harder to control at the moment. The same is true for reading of degrees, which takes radians as input. Luckily, both API and UI defaults to centimeters for distance-type attributes.
- Added
cmdx.DagNode.boundingBox
andBoundingBox.volume()
for computing the volume of any DagNode (approximate, based on whatever bounding box information Maya has already got about your object)
writable
# Before
if not node["tx"].connected and not node["tx"].locked:
node["tx"] = 5
# After
if node["tx]".writable:
node["tx"] = 5
reset
A much simplified manner in which to reset an attribute to whatever value was its default.
# Before
plug = node["myAttr"]._mplug
attr = plug.attribute()
type = attr.apiType()
assert type == om.MFn.kNumericAttribute
default = om.MFnNumericAttribute(attr).default
node["myAttr"] = default
# After
node["myAttr"].reset()
Also works with undo.
with cmdx.DGModifier() as mod:
mod.resetAttr(node["myAttr"])
0.4.5
cmdx.Context
Improved support for reading plugs at arbitrary times.
Say you have a node with an animated translateX
tx = cmdx.create_node("animCurveTL")
tx.keys(times=[1, 2, 3, 4], values=[0, 10, 20, 33], interpolation=cmdx.Smooth)
node = cmdx.create_node("transform")
node["tx"] << tx["output"]
And you wanted to know the value at frame 3. You could either..
cmds.currentTime(3)
assert node["tx"].read() == 20
cmds.currentTime(1) # Restore time
Which would alter the global timeline for everything in Maya, and provide you with the value for this one node.
Or you could..
assert node["tx"].read(time=3) == 20
Which is great for one-off reads, but once you get just a few of these, passing in an explicit time each time can get tedious, hard to read.
Since cmdx 0.4.5 and Maya 2018+ you can now leverage Maya's MDGContext
.
context = om.MDGContext(om.MTime(3, unit=om.MTime.uiUnit()))
context.makeCurrent()
assert node["tx"].read() == 20
om.MDGContext.kNormal.makeCurrent() # Restore "context"
On top of this, you can also leverage the new context manager, cmdx.DGContext
with the optional cmdx.Context
alias.
with cmdx.Context(3):
assert node["tx"].read() == 20
Thanks to @monkeez for this addition!
0.4.3
Add convenience aliases, to visually separate between what is an attribute, and what is a data type.
- Mat4 = MatrixType
- Matrix4 = MatrixType
matrix = cmdx.Matrix4()
node["myMatrixAttribute"] = cmdx.MatrixAttribute()
node["myMatrixAttribute"] = matrix
More
- EnumAttribute = Enum
- DividerAttribute = Divider
- StringAttribute = String
- MessageAttribute = Message
- MatrixAttribute = Matrix
- LongAttribute = Long
- DoubleAttribute = Double
- Double3Attribute = Double3
- BooleanAttribute = Boolean
- AbstractUnitAttribute = AbstractUnit
- AngleAttribute = Angle
- TimeAttribute = Time
- DistanceAttribute = Distance
- CompoundAttribute = Compound
- Double2Attribute = Double2
- Double4Attribute = Double4
- Angle2Attribute = Angle2
- Angle3Attribute = Angle3
- Distance2Attribute = Distance2
- Distance3Attribute = Distance3
- Distance4Attribute = Distance4
0.4.2
Added support for writing to Matrix plugs.
node = cmdx.createNode("transform")
node["translate"] = (1, 2, 3)
node["rotate", cmdx.Degrees] = (20, 30, 40)
# Create a new matrix attribute
node["myMatrix"] = cmdx.Matrix()
# Store current world matrix in this custom attribute
node["myMatrix"] = node["worldMatrix"][0].asMatrix()
- See #9 for details