riggyheji
riggyheji
Riggy Heji
29 posts
Waddup! I post documentation of rigging techniques to help myself remember.
Don't wanna be here? Send us removal request.
riggyheji · 5 years ago
Text
Composite
A common coding pattern involves nesting objects inside each other to build up composite.
It is when you use another class’ method inside a class, without inheriting it, and embed a class. 
###########
Class Person:
>>>>def __init__(self, name, job, pay):
>>>>>>>>blablabla
Class Manager:
>>> def __init__(self):
>>>>>>>self.person = Person(name, ‘mgr’, pay)   #embed a person object
########### 
A GUI might similarly use inheritance to customise the behaviour or appearance of labels and buttons, but also composition to build up larger packages of embedded widgets such as input forms, calculators and text editors. 
Composition is well suited to scenarios where multiple objects are aggregated into a whole and directed by a controller layer class. 
1 note · View note
riggyheji · 5 years ago
Text
Development Testing Modules
A handy bit of code to put in a module for testing purposes is 
if __name__ = ‘__main__’:
>>>> testing code
This means that the code is being run on the main console, where you’d have the module imported (ideally) for proper use. 
0 notes
riggyheji · 5 years ago
Text
Developer Class attributes
Here are some handy attributes for development!
instance.__class__ ==> returns class of instance
class.__bases__  ==> returns all super classes of class
object.__dict__ ==> returns a dictionary of key/value pairs for every attribute attached to namespace of the object (includes module, instances and class).
dir(instance) ==> The built in dir call method returns a list of inherited attributes on an instance.
0 notes
riggyheji · 5 years ago
Text
Classy Concepts- Code Re-usability and Customization
•One of OOP’s main functionality is to lessen code redundancy, and this can be practised through good method code maintaining. 
•When augmenting methods in a class (especially if it is inherited), do not copy and paste code, as much as possible. If you have to tweak the functionality of an inherited method, try to call the super class’ method, and then add to it in the inherited method. 
•To call a super class method, be wary that you must provide the instance. For example;
Let’s say you want to make two classes, Cake and Pie.
###########
Class Cake():
>>>>def readIngredients(self):
>>>>>>>>print (’Items in a cake include: flour, eggs, biscuit.’)
###########
Pie will  inherit from Cake, but say that you want one of the methods, getIngredients, print something different for Pie than Cake. Let’s say you want it to print out what it does for cake, and then print out something more. You could do it this way. 
###########
Class Pie(Cake):   #The Pie class inherits from Cake
>>>>def readIngredients(self):
>>>>>>>>print (’Items in a cake include: flour, eggs, biscuit.’)
>>>>>>>>print (’Items in a pie also include: flour, eggs, biscuit.’)
  ###########
This will work for what you want, but notice that you’re copying and pasting code. It may not be obvious in this case, but this creates an extra step in code maintenance, which is not great. 
Instead, you could do this 
###########
Class Pie(Cake):   #The Pie class inherits from Cake
>>>>def readIngredients(self):
>>>>>>>>Cake.readIngredients(self)   # calls Cake method
>>>>>>>> print (’Items in a pie also include: flour, eggs, biscuit.’)
 ###########
This calls the super class’ method, and then you can add extra code after that. That way, when you change the method’s original code in Cake, it gets propagated to all the other inherited classes. Again, make sure you pass the instance as an argument to a class’ method. 
You can use this to customise an inherited class’ constructor function.
###########
class Manager(Person):
>>>>def __init__(self):
>>>>>>>>Person.init(self)
########### 
This act is known as redefining an inherited class constructor.  
A class’ method can always be called either through an instance(the usual way, where Python sends the instance to the self argument automatically) or through the class (the less common scheme, where you must pass the instance manually).
Usual method;
instance.method(args)
gets translated to
class.method(instance, args)
The method always needs a subject instance one way or another. Python only passes it automatically if the method is called through an instance. For calls made through the class name, you need to send an instance to self yourself. 
0 notes
riggyheji · 5 years ago
Text
Some Polevector mathy flexxy!
Here are two tutorials to help experiment with OpenMaya’s MVeector classes. 
https://vimeo.com/240328348
https://vimeo.com/66015036
0 notes
riggyheji · 5 years ago
Text
Soft IK Tutorial
https://vimeo.com/168185968
0 notes
riggyheji · 5 years ago
Text
Python Search Path
Python stores a finite list of paths that python uses to search for for importing modules. You can access this list by 
import os, sys;
for p in sys.path:
    print(p)
this will print out the absolute paths for which the python interpreter will search through.
Tumblr media
Here, you can see a whole load of paths that python can import from. All paths that begin with ‘C:\Programs....’ are built-in paths, and are parallel to Maya’s Python installation. 
The final paths after those (those beginning with ‘C:\Users...’) are specific to Maya and are appended to the Python path when Maya is initialised. 
How to Temporarily add a Path
You can append a path like this
sys.path.append( #insert path here)
However, this only adds the path in the current maya session, and wont exist the next time Maya is loaded. Here are some more permanent options;
So here’s what paths actually get loaded into maya 
userSetup Scripts
A userScript is a script which Maya executes when it starts. The script must be names userScript.py or userScript.mel depending on the language being  used and can only be one of those two. It must also be located in the Documents/maya/<version>/script folder. 
However, these instructions are going to be executed before the scene is prepared. This is fine if you just want to add a search path using the userSetup. If you would like to have the script import something in the scene, like a module, then you would need to use the maya.utils.executeDeferred(’import lightplabe’) function as an example. 
The userScript is also no encapsulated like an ordinary module, all of its statements are executed in the __main__ module and therefore all imports made in the userScript appear in the globals table. 
Using a userSetup method may not be ideal, as artists may use their own custom set scripts and this could cause conflicts. Here’s another alternate;
sitecustomize Module
A sitecustomize module is similar to a userScript as in it is executed before a maya scene is prepped. However, whatever is executed within it is encapsulated like any other module, so it wont be appearing the globals table. 
To create a sitecustomize module, name a script called customizemodule.py and add in the code of appending the path required into sys.path.append(). This is typically saved in the site packages folder in Program Files by convention. 
Because a sitecustomizable module needs to be added in a folder where administrative rights might be requested, it isnt too convenient for large productions, especially if it gets updated a lot! 
That being said, here is another alternative to adding a search path
Setting Up a PYTHONPATH Environment Variable 
Maya-Specific Environment Variables with Maya.env
This is perhaps the easiest way to add a search path to your python system. Simply access your Maya.env file, available in MyDocuments\maya\<version>. By default this will be blank, you can then create a variable called PYTHONPATH and assign the path/s you want to add. Like this;
PYTHONPATH = C:\Asya\Desktop ; C:\AnotherDirectory
These paths will now be added to the sys.path, even before some of the built in python directories!
0 notes
riggyheji · 5 years ago
Text
from
If you’d like to simply bring in an attribute (variable/function) from another module into your current module, use the from keyword. This brings the attribute into the symbols table of the scope you are in (in module- local, in Maya main module- global). 
for example;
from math import degrees,acos;
This would import the degrees and acos functions into the module, from the math module. You would be able to reference these two without having to use a namespace (like math.degrees, or math.acos), provided there’s no naming conflicts. 
Additionally, you could import a whole module’s attributes too, using the asterisk character.
from math import *
However, take note that using a namespace actually protects your modules, you can still mutate/change definitions outside of module. By naming tradition, any attribute with a double underscore before and after it is deemed as private, a.k.a, don’t mess with it’s shit! I’m warning you!
This convention also stops the attribute(s) being imported when using the * operator. Phew, you’re safe.
0 notes
riggyheji · 5 years ago
Text
import
Using the import keyword is how you bring in modules into the __main__ module in Maya. Once a module is executed, a .pyc file is automatically created. This is a compiled translation of the code into bytecode for efficiency in execution. 
When a module is “imported”, if a bytecode/.pyc version of the module exists, this code will be run. While this helps with faster execution,this will cause issues if there has been a change done to the code since it was last compiled. 
To counter this, we use the reload() function. This basically recompiles the bytecode for the module that you pass as an argument. 
0 notes
riggyheji · 5 years ago
Text
Packages
What is a Package
A package is essential a folder containing python scripts (modules) that acts as one big module. Packages allow you to cleanly deploy suites of tools, rather than requiring to fill up one folder with a bunch of modules, or that you create a long module. 
You are able to avoid naming conflicts by nesting modules inside of packages, reducing the likelihood of butting heads with other tools. 
How to Create a Package
Simply create a folder containing your modules, and add a file called __init__.py . This file turnsthe folder into a package (like a magic word!). In the __init__.py file, 
import ### module names in the folder ### ; 
Now, you can simply import the name of the folder, and then use the folder.module.function() namespace convention (like you would use maya.cmds)
0 notes
riggyheji · 5 years ago
Text
A bit about Modules
The __main__ Module
Variables and functions defined in a module are known as a module’s attributes. (’Attributes’ is confusing, I know. But so it is!). Every module will have some default attributes created, and one of the is the __name__ attribute. This is a variable that typically holds a string that is the name of the module. If you print the __name__ attribute plainly in the Script Editor, you will see “__main__” as a result, indicating that the module currently worked on is the root module in Maya. 
Any scripts or modules we create and run in Maya cannot be called the __main__ module, as Maya is acting as it. All other modules branch from the __main__ module. 
Default Attributes
The __name__ attribute is an example of a module’s default attribute that is created even without defining it. Such attributes are typically prefixed and suffixed with a double underscore ‘__’ . Below is a definition of a few default attributes; 
__builtins__ ==> This attribute points to a module that contains all of Python’s built in functions such as print() and globals(). This module is always automatically loaded and does not require you to access it using a namespace. This is a type module. 
__file__ ==> This is a type string. Indicates the absolute filepath of the .py module currently run. 
__package__ ==> This attribute returns the name of the package to which the module belongs. Returns None if it is not part of a package. 
__doc__ ==> If you set your module properly, the first string in  a module can be used as a docstring. You can add commented help strings here. 
Using the help(module) function also gives the developed a list of the attributes in a module, such as the name, file path, functions, data amongst other things. 
0 notes
riggyheji · 5 years ago
Text
Python PySide tutorials and other Python Stuff
https://www.youtube.com/user/vfxpipeline/videos
0 notes
riggyheji · 5 years ago
Text
Error Trapping
Python can deal with numerous ways of exiting a function. One of the most common ways is through the return statement. You could also use some methods of returning errors to the developer in a useful way.
Triggering an exception or an error is known as raising. An example is
raise StandardError(’An Error Occured’)
raise
Here’s an example of raising a type error to check if a variable is a list. If it isn’t, then a type error is raised
if (isInstance(variable, list) ):
    continue
else:
    raise TypeError(’Argument passed was not a tuple or list.’) 
Note that these Errors raised are classes.
try, except and finally
A try clause contains the code to be tested in case an exception is raised.
Following a try statement, it must either be followed by an except or finally clause.
example bellow:
try: 
    # code to be tested
except: 
    # raise an exception
finally:
    # bit of code that is run regardless of errors
If you don’t want to use an except clause, you could use a try then finally, having the finally cause run some clean up.
Additionally, you could add an else clause to run in case the code tested passes without any exceptions or errors. 
try:
    #code to be tested
except Exception:
    # print the exception error to developer
else:
    # what to do if no exception 
finally:
    #code run in the end 
Printing out the TypeError
try:
    #function
except TypeError as e:
    print(e)
Helpful video- https://www.youtube.com/watch?v=NIWwJbo-9_8
0 notes
riggyheji · 5 years ago
Text
List Comprehensions
This often brains my blow. I personally find it hard to understand these expressions at first glance, but these list comprehensions can help squeeze a bunch of nested conditions and loops into one line. 
Take this block of code:
textures = []
for name in folder:
    if ‘_diff’ in name:
        textures.append( name.split(’.’)[0] );
This code goes through the names in a folder. If the string ‘_diff’ is in the name, then the name string is split by the ‘.’  and added to the textures list. 
Alternatively, you could express it as 
textures = [
    name.split(’.’)[0] for name in folder if ‘_diff’ in name
];
0 notes
riggyheji · 5 years ago
Text
Basic Iteration in Python and Other Things
The for Statement
collection = [1,2,3]
for item in collection:
    perform_task(item);
range()
print(range(2,6))
#Results: 2, 3, 4, 5
print( range(4, 20, 2)
#Results: 4, 6, 8, 10, 12, 14 , 16 , 18
The range function can accept three parameters. The lower bound, upper bound and step value. 
Because the range function returns a list, you can use it to apply a slice to reverse it
print( range(0,5) [::-1] )
isInstance() function
Useful function to find out what type of data a variable holds. 
isInstance(variable, list) returns 1 if variable is list
Branching
The use of if, elif and else conditions is called ‘branching’. 
if condition:
    #do something
elif another_condition:
    #do something else
else:
    #do default action
Implicit False
Using the “not” operator can be used to test against other False or empty values, such as 0, None, [] and ‘’. 
if statement as part of expression
result = ‘equal’ if value1 == value2 else ‘not equal’: ;
Result will be equal to ‘equal’ if value 1 = value 2
else, result = ‘not equal’
Using a dictionary based approach for a Switch
Here is some Python code for a switch
if func_test is ‘A’:
    exec_func_A()
elif func_test is ‘B’
    exec_func_B()
else:
    exec_default()
The code tests the func_test variable to see if it is A or B, and will respectively then execute either exec_func_A() or  exec_func_B() respectively. If neither of these cases are met, then the exec_default() function is called. 
You could use a shorter, more efficient block of code to do the same with 
func_dic = { ‘A’: exec_func_A() , ‘B’ : exec_func_B() }
func_dic.setdefault( func_test, exec_default) ()
continue and break
Using a break statement is used to exist a loop immediately. 
The continue statement is used to skip an element in a loop’s sequence. Once a continue statement is invoked, it will return to the beginning of the loop  and will ignore whatever code comes after it. 
The pass statement basically is a “do nothing”/filler statement. If invoked, it simply continues on with the rest of the code. Sweet. 
Here is a good video on explanation:
https://www.youtube.com/watch?v=2JsGiygzi5M
0 notes
riggyheji · 5 years ago
Text
OS Module for File paths
Here’s how to get the home directory in Python using the os module
import os
homeDirectory = os.getenv(’Home’)
https://www.geeksforgeeks.org/python-os-getenv-method/
To join file directories;
os.path.join( os.getenv(’Home’) , ‘cube.ma’ )
This creates a file path of the C:/HomeDirectory/cube.ma.
0 notes
riggyheji · 5 years ago
Text
Unpacking Returns from Functions in Python
This is something I did not know!
For instance, take the polySphere maya command.
Running the cmds.polySphere() function would give you two returns, a transform node and a shape node (kinda annoying tbh!). You could unpack these values into separate variables in one line like this
sphere_xform, sphere_shape = cmds.polySphere() ;
instead of doing it like this
uselessVar = cmds.polySphere() ; 
sphere_xform = uselessVar[0] ; 
sphere_shape = uselessVar[1] ;
Pretty neat, eh!
0 notes