Sunday, December 21, 2014

Maya API: Setup Maya Plugin Wizard

I always got trouble to setup my Visual Studio for Maya C++ API. I saw couple different tutorials teaching how to setup, but some are over complex.

So, here I introduce a simple way. Hope it will help you step into Maya API world.
  • Go to your Maya directory, there is a pluginwizard fold underneath devkit folder, inside you should have MayaPluginWizard2.0.zip and MayaWizardReadme.txt

  • Extract MayaPluginWizard2.0.zip, you will get a MayaPluginWizard folder, inside of the folder, you should have MayaPluginWizard folder, MayaPluginWizard.ico,  MayaPluginWizard.vsdirMayaPluginWizard.vsz


  • Go to your Visual Studio directory, there is VCWizards folder underneath VC folder, copy the top MayaPluginWizard folder to here


  • Go to vcprojects folder, which is also underneath VC folder, copy MayaPluginWizard.ico,  MayaPluginWizard.vsdirMayaPluginWizard.vsz to here.

  • Use text editor to open MayaPluginWizard.vsz, and make sure the VsWizardEngine version number matches your Visual Studio version number. The default is 10.0. For example, my Visual Studio is 11.0, so I need to change here.

  • Once these all set up, you should be ready to go. Open your Visual Studio, and create a new C++ project, you will see Maya Plug-in Wizard

Saturday, December 20, 2014

Research & Study: Skin Weights

Here are a comparison by using different Maya smooth skin bind methods(default settings) to bind a character:
  • Closest distance
    • Ignores joint hierarchy
    • Using distance between vertexes and joint to bind
    • Causes inappropriate influences on nearby discontinuous area
    • Over falloff covers inappropriate area
  • Closest in hierarchy
    • Joint influence is based on skeleton hierarchy
    • Prevent inappropriate influences like closest distance method
    • Over falloff covers inappropriate area
  • Heat Map
    • Polygon mesh only
    • May fail when finding bad faces
    • Long time calculate to generate influences
    • Better falloff but a little bit rigid for organic rigging


Another comparison on complex shoulder part:



According to above comparison, none of the skin bind methods can provide 80-90% well-done skin influences. Less or more, they have different disadvantages. As well as, none of them provides interactive skin bind method, or easy and quick setup method, instead of traditional painting skin weights, which has already been using in over 20 years.


Maya also has Interactive Skin Bind, a good idea, but not good to use at all.
  • Interactive Skin Bind
    • Cannot be used on NURBS
    • Not accurate at initial setup, also hard to get accurate result by adjusting its manipulator
    • manipulator is not user-friendly, like hard to rotate or translate the manipulator
    • Increase the influences by dragging or changing the size of interactive skin bind manipulator. The manipulator may affect to discontinuous area, like legs or fingers, and causes inappropriate influences
    • Linear workflow with painting skin weights, which means user can use interactive skin bind to breakdown or initialize skin influences, then paint skin weights to get accurate result, but if goes back to use interactive skin bind manipulator to adjust the skin weights, user will lose what just painted skin weights.

Saturday, December 13, 2014

PyQt (5): QIcon & QPixmap

QIcon is used to create icons, and QPixmap is used to attach image on widget.

Case 1: 
touch image on a button.

Example:
from PyQt4 import QtGui, QtCore

# create icon and load image
icon = QtGui.QIcon('C:\icons\myIcon.png')
# create a button
button = QtGui.QPushButton()
# set icon to button
button.setIcon(icon)
# set the size of the icon
button.setIconSize(QtCore.QSize(200,200))
# show the button
button.show()
Case 2: 
set window icon.

Example:
from PyQt4 import QtGui, QtCore

# create icon and load image
icon = QtGui.QIcon('C:\icons\myIcon.png')
# create a widget
widget = QtGui.QWidget()
# set the icon as widget window icon
widget.setWindowIcon(icon)
# show the widget
widget.show()
Case 3: 
touch image to widget.

Example:
from PyQt4 import QtGui, QtCore

# create label widget, which is used to carry the image
label = QtGui.QLabel()
# create QPixmap and load the image
myPixmap = QtGui.QPixmap('C:\icons\myIcon.png')
# set pixmap to the label widget
label.setPixmap(myPixmap)
# show the widget
label.show()

Sunday, December 7, 2014

PyQt (4): QLineEdit

QLineEdit is a widget using to create a one-line text editor.

Case 1: 
The QLineEdit is used to be a user input area

Example:
from PyQt4 import QtGui, QtCore

# create main widget and its layout
mainWidget = QtGui.QWidget()
mainLayout = QtGui.QHBoxLayout()
mainWidget.setLayout(mainLayout)

# create a label
label = QtGui.QLabel('PrintOut Button: ')
# fine-tune the appearance of aligned text
label.setAlignment(QtCore.Qt.AlignCenter)

# create text area
textLine = QtGui.QLineEdit()
# set text when the text area is not activated
textLine.setPlaceholderText('please input something here!')

# create a button
btn = QtGui.QPushButton('Print')

# create button click function to print out what input in text line
def clickFunc():
    print str(textLine.text())

# create signal for the button
# when click the button, excute the click function
btn.clicked.connect(clickFunc)

# add ui elements to the main layout
mainLayout.addWidget(label)
mainLayout.addWidget(textLine)
mainLayout.addWidget(btn)

# show the main widget
mainWidget.show()
Case 2: 
The QLineEdit is used to be a display area and do not allow user to edit

Example:
from PyQt4 import QtGui, QtCore
import maya.cmds as mc

mainWidget = QtGui.QWidget()
mainLayout = QtGui.QHBoxLayout()
mainWidget.setLayout(mainLayout)

# create a label
label = QtGui.QLabel('File Path: ')
# fine-tune the appearance of aligned text
label.setAlignment(QtCore.Qt.AlignCenter)

# create text area
textLine = QtGui.QLineEdit()
# set text when the text area is not activated
textLine.setText('C:/test/test.py')
# set the text is read only, so that user still can copy text from text area
textLine.setReadOnly(True)

# add ui elements to the main layout
mainLayout.addWidget(label)
mainLayout.addWidget(textLine)

# show the main widget
mainWidget.show()

PyQt (3): QLabel

QLabel is a widget using to display text or image.

QtCore.Qt.AlignmentFlag provides flags to fine-tune the apperance of aligned text:

QtCore.Qt.QtAlignTop
QtCore.Qt.AlignBottom
QtCore.Qt.AlignRight
QtCore.Qt.AlignLeft
QtCore.Qt.AlignVCenter
QtCore.Qt.AlignHCenter
QtCore.Qt.AlignCenter

Example:
from PyQt4 import QtGui, QtCore

# create main widget and its layout
mainWidget = QtGui.QWidget()
mainLayout = QtGui.QHBoxLayout()
mainWidget.setLayout(mainLayout)

# create a label
label = QtGui.QLabel('PrintOut Button: ')
# fine-tune the appearance of aligned text
label.setAlignment(QtCore.Qt.AlignCenter)

# create a button
btn = QtGui.QPushButton('Button')

# create button click function
def clickFunc():
    print 'This is a button!'

# create signal for the button
# when click the button, excute the click function
btn.clicked.connect(clickFunc)

# add label and button to the main layout
mainLayout.addWidget(label)
mainLayout.addWidget(btn)

# show the main widget
mainWidget.show()

PyQt (2): QPushButton

QPushButton is a widget using to create a button.

Example:
from PyQt4 import QtGui
# create a button
btn = QtGui.QPushButton('Button')

# create button click function
def clickFunc():
    print 'This is a button!'

# create signal for the button
# when click the button, excute the click function
btn.clicked.connect(clickFunc)

# show the button ui
btn.show()

Thursday, December 4, 2014

Trick & Tip: Flat Dictionary and List

Case 1: flat a dictionary
Sometimes, we may have a dictionary which may have other dictionaries as its values.

Here is a method to flat the complex dictionary to a list, whose first item is the Key from dictionary and rest of items are the Value from dictionary.

Example:
# flat dictionary function
def flatDict(dic):
    def _flatDict(dic, list=[]):
        for k, v in dic.iteritems():
            if isinstance(v, type(dic)):
                _flatDict(v, list)
            else:
                list.append((k, v))
        return list
    return _flatDict(dic)

# create a dictionary
dic = {1:{'a':'red', 'b':'green', 'c':'blue'}, 2:{'L1':[1,2,3], 'L2':[10,20,30], 'L3': [100, 200, 300]}, 3:'this is a test!'}

# print flatten dictionary
print flatDict(dic)


Case 2: flat a list
Also, sometimes, we may meet a list which contents multiple list inside.

Here is a method to flat the complex list to a simple 1-level list.

Example:
# flat list function
def flatList(list):
    def _flatList(list, output=[]):
        for i in list:
            if isinstance(i, type(list)):
                _flatList(i)
            else:
                output.append(i)
        return output
    return _flatList(list)

# create a list
l = [1,2,3, ['a', 'b', ['red', 'yellow', 'blue'], 'c'], 5, 6]

# print out flatten list
print flatList(l)

Sunday, November 30, 2014

PyQt (1): Widget & Layout

Note: 
Qt is a set of C++ libraries and is widely used in UI design on different OS platforms. 
PyQt4 implements most of parts of these classes as a set of Python modules.
Here we only discuss PyQt for Maya.

####################################################################

There are many different types of widgets and layouts in PyQt.

Widget is a house, containing all the UI elements.
Layout is the floor plan for the house, which controls how the UI looks like. 

Here only introduce the most basic widget, QWidget
and two most basic layouts, QVBoxLayout and QHBoxLayout.
(There is QLayout in Qt Library, but it is an abstract class and cannot be instantiated)

QVBoxLayout will vertically layout UI elements;
QHBoxLayout will horizontally layout UI elements.

Example:
# if user uses Maya2014 or above, import from PySide
# if Maya version is below 2014, then import from PyQt4 if PyQt4 Library installed
try:
    from PySide import QtGui
except:
    from PyQt4 import QtGui

# create widget and its layout
widget = QtGui.QWidget()
layout = QtGui.QHBoxLayout()
widget.setLayout(layout)

# create two buttons
button1 = QtGui.QPushButton('Button 1')
button2 = QtGui.QPushButton('Button 2')

# add buttons to layout
layout.addWidget(button1)
layout.addWidget(button2)

# show the window
widget.show()

Sunday, November 16, 2014

Python Module: time

Module time is my favorite module, usually use to test the speed of my code.

Example:
import time

# start time
start = time.time()

# run the code
for i in xrange(0, 100):
    print i

# end time
end = time.time()

# print the cost time (seconds)
print end - start

Python Module: shutil

Module shutil is usually used for copy files or folders

Example:
import shutil

# to copy file and change its name
shutil.copy2('c:/test/test.txt', 'c:/test.py')

# to copy entire directory
shutil.copytree('c:/test/', 'c:/test2/')

# to copy entire directory and ignore certain files
shutil.copytree('c:/test/', 'c:/test2/', ignore=shutil.ignore_patterns('*.pyc'))

# to copy entire directory and ignore both certain files and folders
import fnmatch
def ignorePatterns(patterns):
    def _ignorePatterns(path, names):
        ignoreList = []

        for i in os.walk(path):
            # to ignore all version folders (v0001, v0002, ...)
            folderName = i[0].rpartition('/')[2]
            if folderName.startswith('v') and folderName[1:].isdigit():
                ignoreList.append(folderName)
            else:
                # ignore files
                for pattern in patterns:
                    for f in fnmatch.filter(i[2], pattern):
                        ignoreList.append(f)
        ignoreList = list(set(ignoreList))
        return set(ignoreList)
    return _ignorePatterns
patterns = ['*.pyc', '*.py~']
shutil.copytree('c:/test/', 'c:/test2/', ignore = ignorePatterns(patterns))

Python Module: sys

Two very common and useful functions from module sys.

Case 1:  sys.path
if we want to load a module from a custom path instead of Maya default scripts directory

Example:
import sys

# add a new path to sys.path
# so Python will search the modules in the new path
# then you can import the module directly
sys.path.append('c:/test/testModule.py')

import testModule
Case 2: sys.modules
a dictionary mapping loaded modules and their names

Example:
# print out all modules and module names
for k,v in sys.modules.iteritems():
    print k, v

Python Module: os

Module os is the most common module to use operating system dependent functions.
Usually use to build up folder structure or get directory, as well as get environment variable values.

Case 1: 
common os functions

Example:
import os

# a dictionary to store string environment
os.environ

# to get environment value
os.getenv('HOME')
os.getenv('USERNAME')

# to list the file and subdirectory names underneath a path
os.listdir('c:/test/')

# to create a new directory/folder
os.mkdir('c:/test/subdir')

# to remove a file
os.remove('c:/test/test.txt')

# to remove empty folder
os.rmdir('c:/test/')

# to rename a file or folder
os.rename('c:/test/test.txt', 'c:/test/test.py')

# create symbolic link (Linux/Unix Only)
os.symlink('c:/test/test.txt', 'c:/test/symTest.txt')

# depth first iterate files and folders underneath the directory
for root, folders, files in os.walk('c:/test/'):
    print root, folders, files

Case 2: 
os.path is a very useful class to deal with directory path.

Example:
import os

# to get file base name only
os.path.basename('c:/test/test.txt')

# to split file name and its extension
os.path.splitext('test.txt')

# to get folder directory path only
os.path.dirname('c:/test/test.txt')

# to split file base name and directory
os.path.split('c:/test/test.txt')

# to check whether file or directory exists
os.path.exists('c:/test/test.txt')

# to check whether is a file
os.path.exists('c:/test/test.txt')

# to check whether is a directory
os.path.exists('c:/test/')

# to make a path by path components
os.path.join('c:/test', 'level_1', 'level_2')

Saturday, November 15, 2014

Python Module: filecmp

The module is used for comparing either files or directories.

Case 1: 
Compare two files

Example:
# if they have the same content, return True
import filecmp
filecmp.cmp("c:/testFolder1/test1.txt", "c:/testFolder1/test2.txt")

Case 2: 
Compare two directories

Example:
import filecmp
cmp = filecmp.dircmp('c:/testFolder1/', 'c:/testFolder2/')

# print out result
cmp.report()

# get the first directory
cmp.left

# get the second directory
cmp.right

# get the contents underneath the first directory
cmp.left_list

# get the contents underneath the second directory
cmp.right_list

# get the files or subdirectories in both directories.
cmp.common

# get common files only
cmp.common_files

# get common subdirectories only
cmp.common_dirs

Wednesday, November 12, 2014

Python Module: tempfile

A python built-in module, which generates temporary files and directories. It works on all supported platforms.

Example:
import tempfile
# to get temporary folder directory in current operation system
tempfile.gettempdir()

Sunday, November 2, 2014

Python Module: inspect


Always the first thing:
import inspect

Case 1: 
To know what arguments in one function.
use inspect.getargspec(functionName)
it will return a tuple type object, the first item contains a list of arguments of this function.

Example:
def myFunc(arg1, arg2, arg3):
    pass
inspect.getargspec(myFunc)[0]
#Result: ['arg1', 'arg2', 'arg3']


Case 2:
To find what members(functions, methods, classes) inside a module,
use following codes:

Example:
# get functions in a module
inspect.getmembers(ModuleName, predicate=inspect.isfunction)

# get classes in a module
inspect.getmembers(ModuleName, predicate=inspect.isclass)

# get methods in a class
inspect.getmembers(ClassName, predicate=inspect.ismethod)

# get built-in methods in a class
inspect.getmembers(ClassName, predicate=inspect.isbuiltin)


Case 3:
those will return a list of tuples.
For each tuple, first item is the name of the member, second item is its memory address.

Example:
import os

# get modules in os
inspect.getmembers(os, predicate = inspect.ismodule)

# get functions in os
inspect.getmembers(os, predicate=inspect.isfunction)

# get classes in os
inspect.getmembers(os, predicate=inspect.isclass)

# get built-in methods in os
inspect.getmembers(os, predicate=inspect.isbuiltin)

# get methods in a class in os
# get the a class
class = inspect.getmembers(os, predicate=inspect.isclass)[1][1]
inspect.getmembers(class, predicate=inspect.ismethod)


Case 4:
To find the class inherit tree hierarchy by inspect.getclasstree([ClassName, ClassName, ...])
it will return a list of all parents of each class.

Example:
# get two classes in os
firstClass = inspect.getmembers(os, predicate=inspect.isclass)[0][1]
secondClass = inspect.getmembers(os, predicate=inspect.isclass)[1][1]

inspect.getclasstree([firstClass, secondClass])

1st Post

不爽的时候还是来写点什么吧~
What's up, World!