Red9 StudioTools have been born out of frustration at Autodesks reluctancy to add some of these core features and workflows into Maya itself. Why OpenSource, well I want to give something back to the industry as I feel damn sorry for studios without the benefit of a large R&D department to craft pipelines around them. The Studio Pack is designed to speed up a modern animation pipeline. All comments and suggestions are welcomed. For more info mail me :)
Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts
Thursday, 20 September 2018
Red9 ProPack: Project and Perforce Handling
Red9 Consultancy Link
In this demo we go through our new Project Handlers, expose newly upgraded Perforce Integration and go through our r9File class object for all TDs out there wanting an easy life.
This is a hugely important concept for anybody running ProPack, especially within a large studio environment, if you’ve got a demo build of ProPack please ensure you watch at least the first 5 minutes of this video as its a CRUCIAL concept within the pipeline!
The Project Handlers manage all aspects of our systems, anything that requires a variable, a path, a class binding or a settings file they all inspect this system, allowing dependencies to be dynamically changed by simply switching the project mount.
More importantly the system now has deep Perforce integration, managing both server and workspace connection per project. Perforce is also exposed within the Red9 Browser, allowing you to seamlessly browser through your full P4 repository directly within Maya with options to checkout, revert, sync, add etc ..
Finally we go through the r9File handler, a high level file object that binds all of the project systems together, exposing both P4 handling and base OS management in a really simple python object for all TDs to use.
Please connect us for more details
Tuesday, 17 April 2018
Red9 ProPack : HealthManager
The Red9 Health Manager concept is a massive part of the Red9 ProPack Pipeline, designed to allow TD’s to sanity check files in a neat, clear API with full UI support. Write your own simple compounds either using our default tests or write your own from the ground up and use those to validate your files before pushing them out to production.
I can’t stress enough just how much this has saved our lives over the last few years, allowing us to ensure all our assets are solid before we send them out to clients. This demo first goes through the initial concepts and UI, then we cover some of the more complex tests. Finally we go through how to write your own tests and Validation classes.
Note: if you’re running blendshapes and having fbx index issues watch on!!
As always, please checkout the Red9 website for more details, and don't forget to subscribe to the new YouTube channel!
thanks
Mark
Saturday, 10 December 2016
Red9 ProPack : Animation Re-Director Update
I wanted to share this huge update to the Animation Re-Direction system in the Red9 ProPack. This new setup has been driven largely by the needs of one of our clients dealing with mass MoCap and needing to straighten out data shot in a tight volume, a really tough thing to do without a tool like this.
The new setup not only keeps all the power of the previous setups, allowing us to direct animations via curves, shaping animations, but also now un-wrap animation data.
As usual if anybody has any questions or is interested in talking about this or our ProPack pipeline drop me a mail!
Many thanks
Mark
The new setup not only keeps all the power of the previous setups, allowing us to direct animations via curves, shaping animations, but also now un-wrap animation data.
As usual if anybody has any questions or is interested in talking about this or our ProPack pipeline drop me a mail!
Many thanks
Mark
Monday, 9 February 2015
Red9 Language Packs!
Wow, it's been a while since I posted up, hopefully over the next few months we'll be showing a lot more of what we've been up to both with the pro-pack and the consultancy business. We we're recently involved in a number of TV commercials which we should be able to show very soon, one a full performance facial setup for a Toyota commercial so watch this space!
In the mean time, I wanted to talk about language packs and how much interest there may be out there for us shipping Red9 StudioPack in multiple languages?
We were talking to some Chinese clients earlier today and the topic came up again so, I've been busy switching all the menu text over to a mapper file that we can easily replace and get translated. It's basically just a Python module with all the text in it that we import on boot, all we'd have to do to change the language is change the binding.
So, who out there would like to see this, and if so, what languages, would you be interested in helping us translate the mapping file?
thanks
Mark
In the mean time, I wanted to talk about language packs and how much interest there may be out there for us shipping Red9 StudioPack in multiple languages?
We were talking to some Chinese clients earlier today and the topic came up again so, I've been busy switching all the menu text over to a mapper file that we can easily replace and get translated. It's basically just a Python module with all the text in it that we import on boot, all we'd have to do to change the language is change the binding.
So, who out there would like to see this, and if so, what languages, would you be interested in helping us translate the mapping file?
thanks
Mark
Wednesday, 17 April 2013
Red9 MetaData Part3
Red9 MetaData Part 3!
Third part in the MetaData series, this one starts to show you how to wire up a rig with the metaData backend
Any questions let me know
Mark
Sunday, 24 March 2013
Red9 MetaData Video Part2
Second installment of the MetaData API demo's.
This one gives you an overview of the factory aspect of meta, how it can be used to walk systems and how the attribute handlers are designed to return python objects rather than just Maya nodes.
I'll follow this up with a more detailed breakdown of the metaRig class and handlers, plus more code detail.
Any questions drop me a mail
cheers
Mark
Wednesday, 20 March 2013
PoseSaver - extensions ;)
I'm designing a new setup for the poseSaver to allow you to easily over-load and manage your own node handling within pose folders and was wanting to see if anybody had any feedback on this one...
So the idea is that any folder that the poseSaver points to, be that the main poseFolders or subfolders, can now have a python file in it that over-loads the main getNode handler in the pose function. Why??
Lets say you want to have a folder specifically for facial, and that facial in your rig is managed in a different way, or you would like to modify the filter used to find the nodes. You may even want to pass a node list directly in. At the moment it's hard work and would mean that for each folder/poseType you'd have to either change the rootNode (setRoot) or change the filter.cgf.
The new stuff will make folder type poses a doddle, if the code finds a python file in the folder then that file is passed and used pre the load or save calls. At the moment I expect 2 functions in there:
These functions are run before the pose handler so you also would have the opportunity to do any file modifications in order to get the scene into the correct state for the pose functions. I may also support a teardown() function just in case you needed to do temp modification's that needed returning after the save or load call.
Anybody got any further thoughts on this? I'm thinking this would give you full control and it would make the systems far more open and customization
cheers
Mark
So the idea is that any folder that the poseSaver points to, be that the main poseFolders or subfolders, can now have a python file in it that over-loads the main getNode handler in the pose function. Why??
Lets say you want to have a folder specifically for facial, and that facial in your rig is managed in a different way, or you would like to modify the filter used to find the nodes. You may even want to pass a node list directly in. At the moment it's hard work and would mean that for each folder/poseType you'd have to either change the rootNode (setRoot) or change the filter.cgf.
The new stuff will make folder type poses a doddle, if the code finds a python file in the folder then that file is passed and used pre the load or save calls. At the moment I expect 2 functions in there:
def poseGetNodesLoad(): #do your stuff and filtering return filteredNodes def poseGetNodesSave(): #do your stuff and filtering return filteredNodes
These functions are run before the pose handler so you also would have the opportunity to do any file modifications in order to get the scene into the correct state for the pose functions. I may also support a teardown() function just in case you needed to do temp modification's that needed returning after the save or load call.
Anybody got any further thoughts on this? I'm thinking this would give you full control and it would make the systems far more open and customization
cheers
Mark
Friday, 15 March 2013
Red9 MetaData API - Vimeo Part1
Red9 MetaData API Part1:
This is the first of what will be a series of videos that go through the MetaData API concepts in Red9. This first demo goes into the attribute management of the class, how it can be used to easily manage, add, set and get any attr for any node inside Maya in a completely seamless Python manor. The next few videos will delve into the more complex network structures designed with MetaRig and go through the factory class aspects of the api. The last in the series will show you how to subclass Meta for your own usage and why you'd want to..
Any questions fire away
cheers
Mark
Friday, 15 February 2013
MetaData....the what and the why?
Before I go and do a new set of Vimeo vid's on the MetaClass API in Red9 I thought I'd go through a few of the basics. This is kind of triggered from a few mails I've had from people asking what the concept behind the MetaData API is and how it might benefit them. MetaData is nothing more than an API, how you use it is down to you...
The factory part of meta goes like this:
So what???????? Well imagine you do getMetaNodes() on your rig scene that has an mRig node
mRig=r9meta.getMetaNodes(cmds.ls(sl=True)[0])[0]
Now mRig is a class object of type 'metaRig' and that is a subclass of Meta so has all the attribute handlers available. Basically that Maya node is now bound to a given class like Pymel does, you do pm.selected() on a transform you get back a pymel.Transform class object, you do the same on a light....etc. Well in the same way MetaClass does the same for any Maya nodes. More importantly by subclassing MetaClass you can bind your own classes up to your own nodes in any system.
So lets quickly look at the metaRig setup in the Red9 unitTests:
Note here that I can just use dot complete to actually walk the metaRig network. This is because by getting the attribute of type message the code looks at the linked nodes, if they too have the mClass attr they are returned as python metaClass objects too, so you can just keep walking down the tree. This makes finding nodes in complex systems like rigs an absolute doddle.
The attribute handlers in Meta seamlessly deal with getAttr, setAttr and addAttr, in fact addAttr manages all the flags for you, you can even add the attr without telling it the type, I derive it from the value you pass in if I can. Also you can pass ANY node into the MetaClass api, the node doesn't have to take advantage of the factory stuff, you can just use it as an attribute handler if you like.
Hint: When a node is passed into MetaClass all attributes show on the dot-compete in the script editor ;).
Currently I support:
Even better, and here's where it gets fun, if you pass a python dict, or complex structure to a string attr, it's serialized and stored via JSON for you. Here at work we store our zero pose, generated by the
poseSaver, actually on the mRig node itself as a json string. Same way that the SceneReview serializing all the comment data from an internal dict straight to the 'time1' node in Maya. The AttrMap is also doing this when you serializeToNode.
I've added a ton of hooks in there recently as I've been working with Josh Burton on the new Morpheus project. These all allow you to sub-class and register new types a lot easier. Most of the code we now write at work is based on Meta, either because it's so easy to get data and attributes back, or because we have many nodes for many reasons, facialRig, supportNodes, exportTags managing systems....
Hope that helps a little?
Have a read of the unitTests and examples folders in the Red9 pack, they're there for a reason and might shed some light on all of this ;)
Mark
Part1 -The Factory:
So in a nut shell, it's a factory class with very careful over-loading of some of the key Python calls. The factory stuff really isn't that complex. It's one of those concepts that sounds hard but actually it's really simple. The idea with mine is that any Maya node with an 'mClass' attribute on it, where that attr value matches a pre-registered class, will return that class in all the get() calls in the api ..... example:- 'myNode' has an attribute called 'mClass' who's value is 'metaRig'
- 'metaRig' is a registered class that inherits from r9Meta.MetaClass
- metaRig class is automatically registered to the systems by an internal function that maps all inheritances from MetaClass r9Meta.registerMClassInheritanceMapping()
The factory part of meta goes like this:
- r9Meta.getMetaNodes() or r9Meta.getConnectedMetaNodes() will look first for nodes that have the mClass attribute on them. The search is clamped to registered nodeTypes managed by a call that can be run to register any nodeType to the systems so you can expand as needed.
- resulting nodes are passed in to the __new__() of MetaClass
- the mClass attr 'metaRig' is matched to the registered class
- that class is instantiated and returned back to you
So what???????? Well imagine you do getMetaNodes() on your rig scene that has an mRig node
mRig=r9meta.getMetaNodes(cmds.ls(sl=True)[0])[0]
Now mRig is a class object of type 'metaRig' and that is a subclass of Meta so has all the attribute handlers available. Basically that Maya node is now bound to a given class like Pymel does, you do pm.selected() on a transform you get back a pymel.Transform class object, you do the same on a light....etc. Well in the same way MetaClass does the same for any Maya nodes. More importantly by subclassing MetaClass you can bind your own classes up to your own nodes in any system.
So lets quickly look at the metaRig setup in the Red9 unitTests:
#cast the MayaNode to a metaRig object
mRig=r9Meta.MetaClass('RED_Rig')
assert mRig.L_ArmSystem.L_ArmSupport.mNode=='L_ArmSupport'
assert mRig.L_ArmSystem.L_ArmSupport.SUP_IKHandle[0]=='|World_Ctrl|L_Wrist_Ctrl|ikHandle1'
Note here that I can just use dot complete to actually walk the metaRig network. This is because by getting the attribute of type message the code looks at the linked nodes, if they too have the mClass attr they are returned as python metaClass objects too, so you can just keep walking down the tree. This makes finding nodes in complex systems like rigs an absolute doddle.
Part2 -Attribute Handlers:
So above we saw that metaClass gives you the ability to turn any Maya node into a class bound to that node, so what? Well in the rigs case it means that we can get data dead easily. This is because I've also very carefully managed all attribute calls via the MetaClass api. In doing the mRig.L_ArmSystem call above the code first tests the type of attribute, in this case a message, and uses the listConnections call to get back the data.The attribute handlers in Meta seamlessly deal with getAttr, setAttr and addAttr, in fact addAttr manages all the flags for you, you can even add the attr without telling it the type, I derive it from the value you pass in if I can. Also you can pass ANY node into the MetaClass api, the node doesn't have to take advantage of the factory stuff, you can just use it as an attribute handler if you like.
Hint: When a node is passed into MetaClass all attributes show on the dot-compete in the script editor ;).
Currently I support:
- floats
- doubles
- ints
- bools
- strings ( automatically serializes and deserializes to JSON if the value is complex)
- enums ( allows you to set the data via the int or string representation )
- message ( get runs listConnections, returning mClass objects if found, set will automatically connect)
- doubleArrays (sets the structures up for you when adding)
- double3
- float3
Even better, and here's where it gets fun, if you pass a python dict, or complex structure to a string attr, it's serialized and stored via JSON for you. Here at work we store our zero pose, generated by the
poseSaver, actually on the mRig node itself as a json string. Same way that the SceneReview serializing all the comment data from an internal dict straight to the 'time1' node in Maya. The AttrMap is also doing this when you serializeToNode.
Part3 - The Big One!
The big one though is this..... any node in Maya that has the mClass attr, that is valid, will give you back the correct class automatically! You don't have to worry about what class to call, what function is in what class and if node==this do that, elif to this.... the node comes back as the correct Python object ready for you without any work. There is a direct correlation between the MayaNode and the class that manages it, like Pymel all the functions you may need, code in the class for that node. It keeps code clean and means that by subclassing you get all functionality for all similar node types for free, and get access to all the core stuff in Meta....which is expanding fast.I've added a ton of hooks in there recently as I've been working with Josh Burton on the new Morpheus project. These all allow you to sub-class and register new types a lot easier. Most of the code we now write at work is based on Meta, either because it's so easy to get data and attributes back, or because we have many nodes for many reasons, facialRig, supportNodes, exportTags managing systems....
Hope that helps a little?
Have a read of the unitTests and examples folders in the Red9 pack, they're there for a reason and might shed some light on all of this ;)
Mark
Friday, 11 January 2013
SceneRestoreContext context manager for your viewports
Thought I'd breifly go through the SceneRestoreContext manager in the Red9.General module as it's something that came up today at work. So what is it, well it's a context manager that 's designed to store, and restore all your viewport settings including:
Basically just about everything there is that makes that current session look as it does. Why?? Well sometimes when you're processing data you want to do things to the scene which you really want to restore afterwards. Lets say you're batching a ton of anim data, opening files, switching cameras etc and at the end of processing you want the scene to be set back to how it was. Now this isn't a scene load, this is a cache of all the main ui element settings.
This can be run in 2 ways, the best is to use it as designed, as a context manager:
Now anybody who's used context managers in Python will get the syntax here. The 'with' is doing all the work for you. On entering the call it runs the internal __enter__ call, then runs everything inside the tab (your code), then when complete runs the internal __exit__ call. The great thing about context managers is that even if your code bombs, the __exit__ will still get called and the scene restored to it's cached state.
You can of course use it as you want, so you can take an instance of the object, run the store then when you need to, run the restore:
it's just a function call at the end of the day and might prove useful to others whilst designing tools. If you find anything that you think this is not catching let me know. There's also an AnimationContext thats used in all the animation tools and a HIKContext for managing the set state of HIK rig nodes.
cheers
Mark
- all viewport display options and shading states(for all 4 modelPanels)
- playbackOptions including units, times, timeranges and settings
- scene units
- current audio set in the timeline and it's active state
- current main camera settings (tranforms)
- cameras active in all the modelPanels
Basically just about everything there is that makes that current session look as it does. Why?? Well sometimes when you're processing data you want to do things to the scene which you really want to restore afterwards. Lets say you're batching a ton of anim data, opening files, switching cameras etc and at the end of processing you want the scene to be set back to how it was. Now this isn't a scene load, this is a cache of all the main ui element settings.
This can be run in 2 ways, the best is to use it as designed, as a context manager:
import Red9_General as r9Gen
with r9Gen.SceneRestoreContext:
do your code here
Now anybody who's used context managers in Python will get the syntax here. The 'with' is doing all the work for you. On entering the call it runs the internal __enter__ call, then runs everything inside the tab (your code), then when complete runs the internal __exit__ call. The great thing about context managers is that even if your code bombs, the __exit__ will still get called and the scene restored to it's cached state.
You can of course use it as you want, so you can take an instance of the object, run the store then when you need to, run the restore:
store=r9General.SceneRestoreContext() store.storeSettings() do your code here store.restoreSettings()
it's just a function call at the end of the day and might prove useful to others whilst designing tools. If you find anything that you think this is not catching let me know. There's also an AnimationContext thats used in all the animation tools and a HIKContext for managing the set state of HIK rig nodes.
cheers
Mark
Wednesday, 12 December 2012
More MetaData goodness
I've just been adding to the MetaClass addAttr() call such that it now supports 2 important new features:
Firstly I've wrapped it so you can pass in any of the standard cmds.addAttr keywords which means you can set min, max values etc whilst adding, something that's been requested a few times now.
I've also added double3/float3 support to the call so in one go you can do this:
Still thinking if there's maybe a neater way to pass the value data but we'll see. It's all pretty well documented in the code anyway.
cheers
Mark
Firstly I've wrapped it so you can pass in any of the standard cmds.addAttr keywords which means you can set min, max values etc whilst adding, something that's been requested a few times now.
I've also added double3/float3 support to the call so in one go you can do this:
self.addAttr(attr='attrName',type='double3',value=((subAttr1,subAttr2,subAttr3),(value1,value2,value3)),hidden=False, min=0,max=10)Which will add a new compound double3 attribute 'attrName' with chuild attributes subAttr1 2,3, set their values to value1,2,3. It'll also push the min and max to these subAttrs and set the whole lot keyable and exposed to the channel box :)
Still thinking if there's maybe a neater way to pass the value data but we'll see. It's all pretty well documented in the code anyway.
cheers
Mark
Thursday, 29 November 2012
The power of the FilterSettings class
One of the guys from work asked me about this today and I thought I'd post it up here to show you just how you can use the power of the settings object to filter and organize nodes in Maya. In this example we have 2 rigs in the scene and I want to run a function that will scan both hierarchies for nurbsCurves who's name contains 'Ctrl' and match the nodes, then process the matches in pairs. filterSettings is a class designed specifically just to hold a set of args to be passed into the main filters, it's what the presets in the Hierarchy tab use and store for you.
Here we have the 2 Top nodes of both hierarchies selected. This is the CORE FUNCTION of the entire AnimationUI, it's how it processes matched pairs into something usable for the code:
cheers
Red
Here we have the 2 Top nodes of both hierarchies selected. This is the CORE FUNCTION of the entire AnimationUI, it's how it processes matched pairs into something usable for the code:
import Red9.core.Red9_CoreUtils as r9Core #make a settings object and set the internal filter types filter=r9Core.FilterNode_Settings() filter.nodeTypes='nurbsCurve' filter.searchPattern='Ctrl' #use the processMatchedNodes call to do all the work for you! matched=r9Core.processMatchedNodes(cmds.ls(sl=True),filterSettings=filter) #matched is an object which contains MatchedPairs, a list of tuples in #the form [(source, destination)] This in turn lets us unpack the #data in one go for processing for source,dest in matched.MatchedPairs: print source print destThe same filter can be passed into most of the Red9 functions and is used extensively across all the code. For example the above code is filtering hierarchies, so if we just wanted to search a single hierarchy we can pass the same filter to the FilterNode class:
filterNode=r9Core.FilterNode(cmds.ls(sl=True),filterSettings=fSet) filterNode.ProcessFilter()This is again a key concept in the entire pack so worth looking at if you're intending to use the code.
cheers
Red
Friday, 9 November 2012
Using MetaClass in your own classes
So in Red9 you have the power of a full MetaData api but how do you then expand and use that outside of the Red9 package? This came up recently with somebody inheriting from r9Meta.MetaClass in their own module outside of Red9. So I thought I give you a few pointers.
The first thing to note is that Red9_Meta builds up a global list of registered classes which inherit from MetaClass. Basically I need to know, when a node is passed into the MetaClass.__new__(), whether it's mClass attr (the string pointer that holds what class to instantiate on create) is in the known inheritance mapping. Think about it, I initialize the correct class object for you but the code needs to know if that class is available and registered in Python, otherwise I can't instantiate it for you.
This data is stored in global RED9_META_REGISTERY and in the Red9 pack that's setup in the Red9.core.__init__ by calling registerMClassInheritanceMapping()
All following!
Ok so Red9 is up and Meta knows about classes which have MetaClass as a base. By the way, this is found using the cls.__subclasses__(). But now you have a class outside of Red9 which is also using MetaClass and inorder for it to work correctly, you need to get that little bugger picked up and inside the RED9_META_REGISTERY!
This is all down to the order in which the modules are initialized. Lets say that you've booted Maya and Red9 is up. But you have a module in scripts which imports and uses Red9_Meta and it's not showing up in the meta registry. This is because until you import that module it won't show up in the subclasses cmd, and when you do import it, Red9 won't have it in the registry as it was imported after Red9 booted. So you need to first import your module, then force it into the RED9_META_REGISTERY by doing the following:
The first thing to note is that Red9_Meta builds up a global list of registered classes which inherit from MetaClass. Basically I need to know, when a node is passed into the MetaClass.__new__(), whether it's mClass attr (the string pointer that holds what class to instantiate on create) is in the known inheritance mapping. Think about it, I initialize the correct class object for you but the code needs to know if that class is available and registered in Python, otherwise I can't instantiate it for you.
This data is stored in global RED9_META_REGISTERY and in the Red9 pack that's setup in the Red9.core.__init__ by calling registerMClassInheritanceMapping()
All following!
Ok so Red9 is up and Meta knows about classes which have MetaClass as a base. By the way, this is found using the cls.__subclasses__(). But now you have a class outside of Red9 which is also using MetaClass and inorder for it to work correctly, you need to get that little bugger picked up and inside the RED9_META_REGISTERY!
This is all down to the order in which the modules are initialized. Lets say that you've booted Maya and Red9 is up. But you have a module in scripts which imports and uses Red9_Meta and it's not showing up in the meta registry. This is because until you import that module it won't show up in the subclasses cmd, and when you do import it, Red9 won't have it in the registry as it was imported after Red9 booted. So you need to first import your module, then force it into the RED9_META_REGISTERY by doing the following:
#=========================================================================
# Because we're now inheriting from Red9_Meta any reload on any module that
# is instantiated from Meta will invalidate the RED9_META_REGISTERY. Here
# we force the update on the Red9 internal registry
#=========================================================================
from Red9.core import Red9_Meta as r9Meta
r9Meta.registerMClassInheritanceMapping()
print '============================================='
r9Meta.printSubClassRegistry()
print '============================================='
Hope that makes sense, if not drop me a mail and I'll point you in the right direction!
Red
Tuesday, 16 October 2012
MetaClass - extra candy for complex Json attributes
Ok here's an interesting question. At the moment with the MetaClass stuff you can serialize a complex python structure, like a dictionary, to a string attribute on the MClass Maya node which then means you can do something like this:
So I've been thinking, what if the mClass.__getAttribute__ call that returns that dict actually returned a managed dict of my own type with an overloaded __setitem__ which would then push the changes back to the original mClass attribute? Well it works in testing, not sure if there's an easier way of linking these but I couldn't think of one. The beauty now is that you can do the following and this will pass the value back to the mClass and reserialize it back to the actual Maya string Json Attribute
thoughts?
Red
#make an r9Meta.mClass node with an attribute managed by the JSON handler
mClass=r9Meta.MetaClass('myNode')
mClass.addAttr('newDict',{'A':2.0,'New':'hello'})
#return the original dict back from the Maya Node
mClass.newDict
all goodness so far, but what if the user then does the following?
mClass.newDict['A']=5.0 mClass.newDict['A'] #2.0 ??????You expect that would then modify the mClass attribute you added, wouldn't you? Well no, as the mClass.newDict returns a standard dict (by deserializing the Json string, which is then out of the scope of the metaClass code, it's just a dict and has no knowledge of the mClass itself.
So I've been thinking, what if the mClass.__getAttribute__ call that returns that dict actually returned a managed dict of my own type with an overloaded __setitem__ which would then push the changes back to the original mClass attribute? Well it works in testing, not sure if there's an easier way of linking these but I couldn't think of one. The beauty now is that you can do the following and this will pass the value back to the mClass and reserialize it back to the actual Maya string Json Attribute
mClass.newDict['A']='fooBar' mClass.newDict['A'] #fooBarI'm still looking into this but it certainly makes the code side a hell of a lot more manageable and flexible when you're using this class
thoughts?
Red
Friday, 28 September 2012
MetaClass : More attribute handlers added
I'm expanding the attribute Handling in the base MetaClass as some of the examples in the unittests made no sense to me. For example if I did the following I'd get the color values back from the compound float3 attribute but I couldn't set them:
Also in the new build, v1.26 the messageLink handling in the base class was upgraded so that setting message links, either multi or non-multi is now a simple case of:
Oh and in the current build of v1.26 the presets in the AnimationUI fail to manage the metaRig checkbox and are a little bit flaky, this is fixed, just got to update the server.
cheers
Red
mLambert=r9Meta.MetaClass('lambert1')
mLambert.color #Result [(1.0, 1.0, 0.0)]
In fact the whole way Maya cmds wraps the handling of compound attributes is crap! So I've wrapped them in the latest dev build and to me, they make a lot more sense than default Maya, you can now simply do:
mLambert.color=(1,0.2,0.2)and the compound3 attribute will be set correctly, the value accepts either a list or tuple with 3 values, any less will raise a managed ValueError.
Also in the new build, v1.26 the messageLink handling in the base class was upgraded so that setting message links, either multi or non-multi is now a simple case of:
mNode.myMessageAttr=['newLinkA','newLinkB']If the attribute already has connections those are disconnected and the relevant attrs deleted on the old connected nodes. Again as I'm going through this and more people are feeding back I'm gradually expanding the MetaClass base. If you find any more issues with the attribute handlers let me know
Oh and in the current build of v1.26 the presets in the AnimationUI fail to manage the metaRig checkbox and are a little bit flaky, this is fixed, just got to update the server.
cheers
Red
Thursday, 16 August 2012
More Meta Fun!
import Red9_Meta as r9Meta
import maya.cmds as cmds
mRig=r9Meta.MetaRig(name='MRIG')
mRig.select()
mRig.addRigCtrl('Chest_Ctr','Chest',boundData={'Side':'Centre'})
mRig.addRigCtrl('UpChest_Ctr','UpperChest',boundData={'Side':'Centre'})
mRig.addRigCtrl('Head_Ctr','Head',boundData={'Side':'Centre'})
mRig.addRigCtrl('Root_Ctr','Root',boundData={'Side':'Centre'})
mRig.addRigCtrl('L_Foot_Ctr','L_Foot',boundData={'Side':'Left'})
mRig.addRigCtrl('Hip_Ctr','Hips',boundData={'Side':'Centre'})
support=mRig.addSubMetaNode(nodeName='SupportNode',attr='Support')
support.connectChild(node='Settings_Node',attr='ExportData')
facial=support.addSubMetaNode(nodeName='FacialNode',attr='Facial')
facial.connectChild(node='Lips_Ctr',attr='Lips')
Now the beauty of this is that because the MetaClass base wraps all the Maya attrs and autofills the python objects dicts, we can lituarally walk the dag graph with dot complete!
So to get to the Lips we can simply do the following, all of which autocompletes in the Maya scriptEditor for you ;)
mRig.Support.Facial.LipsAlso because of the way the mRig manages the Controls all of the controllers added above show up in the autocomplete on the mRig node. So you can just go MRig.Head to get the headCtrl back. I'm trying not to restrict this stuff, I'd rather make this as open as I can.
Again, the thing to bear in mind is that the main python objects __getattr__, __setattribute__ have been modified so that getting and setting all data types from Maya nodes is automatic. This includes getting and setting Emums and Message links.
I'll up the latest build of this module is now up on my Google Drive, see download link in the Tags
cheers
Red
Monday, 23 July 2012
Maya Script Editor - Code Inspector
This is a neat little bit of integration to the script editor's popup
menu that's going into the latest build of the Red9 Pack, v1.24.
I've added a new menu item to the ScriptEditor RMB popup, "Red9_InspectFunction", which uses either the whatIs command for MEL or Python's inspect module to then lookup the source function file for the highlighted text, if found it will open up the mel or python module in the default editor on your system. Really handy for debugging!
Since this video I've also managed to get it to run from the history scroll as well as the editor itself which makes it even easier.
I've added a new menu item to the ScriptEditor RMB popup, "Red9_InspectFunction", which uses either the whatIs command for MEL or Python's inspect module to then lookup the source function file for the highlighted text, if found it will open up the mel or python module in the default editor on your system. Really handy for debugging!
Since this video I've also managed to get it to run from the history scroll as well as the editor itself which makes it even easier.
Subscribe to:
Posts (Atom)
