Showing posts with label Technical Art. Show all posts
Showing posts with label Technical Art. Show all posts

P4Python

#Needs p4python installed
#P4Utility
import os
import sys
from P4 import P4

class P4Utils:
    def __init__(self,user,port,client):
        self.p4 = P4()
        self.p4.user = user
        self.p4.port = port
        self.p4.client = client
    def connectToP4(self):
        try:
            self.p4.connect()
        except:
            print "Error in Connecting to P4"
    def do_sync(self,depot):
        try:
            output = self.p4.run("sync",depot)
            return output
        except:
            output = "Files up-to-date"
            return output
    def do_changes(self,depot):
        output = self.p4.run("changes",depot)
        return output

Microsoft Excel + Python

# excelWin32ReadWrite
from win32com.client import Dispatch

class excelWin32ReadWrite:
    def __init__(self,filename = None):
        self.xlApp = Dispatch('Excel.Application')
        if filename:
            self.filename = filename
            self.xlBook = self.xlApp.Workbooks.Open(filename)
        else:
            self.xlBook = self.xlApp.Workbooks.Add()
            self.filename = ''
    def save(self,newfilename = None):
        if newfilename:
            self.filename = newfilename
            self.xlBook.SaveAs(newfilename)
        else:
            self.xlBook.Save()
    def setCell(self,sheet,row,col,value):
        sht = self.xlBook.Worksheets(sheet)
        sht.Cells(row,col).Value = value
    def getCell(self,sheet,row,col):
        sht = self.xlBook.Worksheets(sheet)
        return sht.Cells(row,col).Value
    def getContiguosRange(self,sheet,row,col):
        sht = self.xlBook.Worksheets(sheet)
        bottom = row
        while sht.Cells(bottom+1, col).Value not in [None,'']:
            bottom = bottom+1
        right = col
        while sht.Cells(row, right+1).Value not in [None,'']:
            right = right+1
        return sht.Range(sht.Cells(row,col), sht.Cells(bottom,right)).Value
    def renameSheet(self,sheet,newname):
        self.xlBook.Worksheets(sheet).Name = newname
    def deleteSheet(self,sheet):
        self.xlBook.Worksheets(sheet).Delete
    def returnAllSheetNames(self):
        allSheets = self.xlBook.Sheets
        sheetNames = []
        for i in range(0,len(allSheets)):
            sheetNames.append(self.xlBook.Sheets[i].Name)
        return sheetNames
    def close(self):
        self.xlBook.Close(SaveChanges = 0)
        del self.xlApp

Add user modules path to system path in Python

import os
import sys
#
pyModulesPath = os.path.join(os.getcwd(),"pyModules")
sys.path.append(pyModulesPath)
#

Parse XML Document in Python

from xml.etree import ElementTree
#------------------------------------------------------------------------------------------------
# function to parse XML in dictionary
def readConfigFile(filename):
    '''Reads config XLS and returns dictionary of all variables'''
    dictree = ElementTree.parse(filename).getroot()
    global_params = {}
    listCtrl_values = []
    tmpList = []
    relative_paths = ["relativepath”]
    print "Reading Global Parameters..."
    for entry in dictree:
        relative_switch = 0
        tmpList = []
        key = re.sub('[\t\n\r\f\v]','',str(entry.tag))
        value = re.sub('[\t\n\r\f\v]','',str(entry.text))
        for item in relative_paths:
            if key == item:
                relative_switch = 1
        if relative_switch == 1:
            value = os.path.join(os.getcwd(),value)
        global_params[key] = value
        tmpList.append(key)
        tmpList.append(value)
        listCtrl_values.append(tmpList)
    return global_params,listCtrl_values

#------------------------------------------------------------------------------------------------

Open Maya as separate thread from Python

# Maya thread
class maya_thread(threading.Thread):
    def run(self):
        ''' Opens Maya as a seperate Thread '''
        maya_cmd = ('maya -command "runCommandPortInMaya"')
        #print 'Maya Running...'
        maya_process = subprocess.call(maya_cmd,shell=True)
        return maya_process

#------------------------------------------------------------------------------------------------
# Establish connection with maya
def connectWithMaya(port):
    ''' connects to Maya using socket '''
    maya_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    maya_socket.connect(("10.88.162.46", port))
    maya_socket.send(r'print"\nConnected to Python ...\n";')
    return maya_socket

#------------------------------ Connecting to Maya and sending Mel Commands -------------------
        # Maya Thread
        maya_process = maya_thread().start()
        # Maya Socket
        maya_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #---------------------------------------------------------------
        # Loop to wait till Maya is Invoked
        # Port specified in runCommandPortInMaya.mel file
        port = 5055
        while 1:
            try:
                maya_socket.connect((socket.gethostname(), port))
                break
            except:
                continue

# Loop to wait till Maya is up and fully running
        while 1:
            #maya can only send 4096 bytes through socket
            data = maya_socket.recv(4096)
            data = data.replace("\n","")
            #print data
            tokens = data.split(" : ")
            # if preferences are saved in maya, then Maya is fully loaded with all plugins
            if re.search("Preferences saved.",data):
                break
        #---------------------------------------------------------------
        #("Maya is Running...\n")

C++ / C# Interop

Here is code for basic dllExport in C++  and dllImport in C#
C++
#include <windows.h>
#define EXPORT __declspec(dllexport)
extern "C"
{
EXPORT int dllStartClient()
{
return (WinMain((HINSTANCE)0x500000,(HINSTANCE)0x500000,"",0));
}
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
MessageBox(NULL,L"Hello",L"Hello",MB_ICONEXCLAMATION | MB_OK);
return 0;
}
--------------------------------------------------------------------------------------------
C#
using System.Runtime.InteropServices;
namespace Test1
{
public partial class Form1 : Form
{
[DllImport("Client.dll")]
private static extern int dllStartClient();

public Form1()
{
InitializeComponent();
}

private void BtnStartClient_Click(object sender, EventArgs e)
{
StartClient();
}
private void StartClient()
{
dllStartClient();
}
}
}


Maya API : nodeFromName

MStatus pluginCmd::nodeFromName(MString name, MObject & obj)
{
    MSelectionList templist;
    templist.add(name);
    if(templist.length() > 0)
    {
        templist.getDependNode(0,obj);
        return MS::kSuccess;
    }
    return MS::kFailure;
}

Processes in C#

Start new process in C#  
Process mayaProcess = new Process();
mayaProcess.StartInfo.FileName = "wordpad.exe";
mayaProcess.StartInfo.Arguments = mayaScenePath;
mayaProcess.Start();
mayaProcess.WaitForExit();

Add a folder with all files and subfolders to Perforce

Files will be added to default changelist,

dir /b /s /a-d | p4 -x - add

Create a new Camera Node

M3dView view;
MObject camera;
MDagPath cameraPath;
// create new camera
view = M3dView::active3dView(&status);
MFnCamera fnCamera;
fnCamera.create(camera,NULL);

Maya Plugin Development Primer

Here are few steps for developing plugins from scratch and not using the wizard, thanks to Rob Bateman for most of the info,

1. Create dll project
2. add a c++ file to it
3. change the output extension to mll
4. change project settings->C/C++->Code generation to Multi-threaded or Multi-threaded-debug
5. add NT_PLUGIN & REQUIRE_IOSTREAM to the C/C++ -> pre-processor defines in the project settings
6. set the library and include paths to the maya API (additional include directories, and additional lib directories (Foundation.lib, OpenMaya.lib)

in the cpp file:
//
#include <maya/MFnPlugin.h>
#include <maya/MPxCommand.h>
//
// link libs under VisualC++/Win32
#ifdef WIN32
#pragma comment(lib,"Foundation.lib")
#pragma comment(lib,"OpenMaya.lib")
#pragma comment(lib,"OpenMayaFx.lib")
#pragma comment(lib,"OpenMayaUi.lib")
#pragma comment(lib,"Image.lib")
#pragma comment(lib,"OpenMayaAnim.lib")
#pragma comment(lib,"OpenGl32.lib")
#pragma comment(lib,"glu32.lib")
#endif

#ifdef WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
//--------------------------------------------------------------------------------------------------
class helloCmd : public MPxCommand{
public:
virtual MStatus doIt(const MArgList&);
static void *creator(){
return new helloCmd;
}
};
//--------------------------------------------------------------------------------------------------
MStatus helloCmd::doIt(const MArgList& args){
MStatus status = MS::kSuccess;
MGlobal::displayInfo("Hello\n");
setResult("initialized");
return status;
}
//--------------------------------------------------------------------------------------------------
EXPORT MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin pluginFn( obj, "Vishang Shah", "1.0");
status = pluginFn.registerCommand("helloCmd",helloCmd::creator);
if(!status)
  status.perror("registerCommand Failed");
return status;
}
EXPORT MStatus uninitializePlugin( MObject obj)
{
MFnPlugin pluginFn( obj );
MStatus status;
status = pluginFn.deregisterCommand("helloCmd");
if(!status)
  status.perror("deregister failed");
return status;
}
//--------------------------------------------------------------------------------------------------

C#

First C# Code, to search all tga files in given directory and its subdirectories

static class FileSearch{
public static List<string> GetFilesRecursive(string parentDir){
List<string> result = new List<string>();
//
Stack<string> stack = new Stack<string>();
//
stack.Push(parentDir);
while (stack.Count > 0)
{
string dir = stack.Pop();
try
{
result.AddRange(Directory.GetFiles(dir, "*.tga"));
foreach (string subdir in Directory.GetDirectories(dir))
{
stack.Push(subdir);
}
}
catch (System.Exception e)
{
Console.WriteLine(e);
}
}
return result;
}
}

commandPort

Its been long long time since I posted anything on my blog.

So here is a way to send data from Python to Maya and vice versa,

------------------------------------------------------------------------------------------------------------------------------

#echoFromMaya.py

import socket
import re

port = 3033

maya_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
maya_socket.connect((socket.gethostname(), port))
maya_socket.send(r'print"\nConnected to Python ...\n";')

while 1:
    data = maya_socket.recv(4096)
    data = data.replace("\n","")
    if re.search("callPythonSocketServer",data):
        print "Closing..."
        break

print "Socket closed"

------------------------------------------------------------------------------------------------------------------------------

in Maya,

commandPort -eo -n ":3033";   to connect to python socket

then,

print "Hi from Maya\n";   will print the string in command line, where python server is listening

and then finally, we are using this string "callPythonSocketServer" to tell python server to quit,

print "callPythonSocketServer";

 

Enjoy

:-)

Delete Nodes having some Prefix

# To delete nodes starting with some prefix string
import os
from time import strftime,localtime

def del_p_999(fpath,str):
    print ('--------------------------------------------------------------------')
    print fpath
    print "Start Time : " + strftime("%H:%M:%S",localtime())
    filein = open(fpath,'r')
    inputstr = filein.read()
    filein.close()
    lines=inputstr.splitlines(1)
    sw = 0
    linecount = 0
    outputstr=''
    totalnodes = 0
    fileout=open(fpath,'w')
    for line in lines:
        if(line.startswith('createNode')):
            sw = 0
            if line.find(str) != -1:
                sw = 1
                totalnodes += 1
            else:
                fileout.write(line)
                sw = 0
        else:
            if sw==1:
                continue
            else:
                fileout.write(line)
                sw = 0
    fileout.close()
    print ("\nTotal Nodes Deleted : ")
    print totalnodes
    print ("\nEnd Time : " + strftime("%H:%M:%S",localtime())+'\n')

basedir=raw_input('Enter Root Path : ')
str=raw_input('Enter Node Prefix : ')

for root,dirs,files in os.walk(basedir):
    for f in files:
        fpath=os.path.join(root, f)
        if(f.endswith('.ma')):
            del_p_999(fpath,str)

Simple Object Oriented Program in Python

# Python Program to understand Classes

class base:
    def __init__(self,var):
        self.var = var
        print "Object Initiated"
    def printVar(self):
        print self.var
object = base("FirstObject")
object.printVar()

'''
First Line is definition of class named base,

In the world of Object Oriented Programming,a class means a datatype
which user can define.

second line is a Constructor, which is the function that gets executed
when an object of that class is created,

The need of constructor is basically to allocate the memory required to
newly created object.
There is no memory leaks in Python, so we dont have any destructors here.

I will explain this line : def __init__(self,var):
then name of constructor must be __init__,

self is like this pointer in C++, which points to the class itself,
each function in class will have one common argument : self
self.var = var will assign passed variable var to base's internal variable
self.var,

in second function printVar we are not passing any arguments but still self will remain.
now we already have base's own variable self.var defined in constructor __init__,we
can use it in printVar.

finally an object called "object" is created of type base,
and function printVar is called through object.printVar()

'''

Lord of the Mayas : The Two APIs

From 8.5, Maya introduced Python support for scripts and plug in development,
For people using older versions, they can use this :
http://cgkit.sourceforge.net/

So Maya has Two APIs now , Maya C++ API and Maya Python API,
Plug ins developed using Python API are called Scripted Plugins.

You can find example scripted plug ins at here:
C:\Program Files\Autodesk\Maya8.5\devkit\plug-ins\scripted

Code blocks in Both APIs are very similar,
Both kinds of plug ins need to be initialized and uninitialized,

If you are using Visual Studio .NET for Maya C++ Plug in Development then while creating API project through wizard , VS creates a Macro called declareSimpleCommand
This Macro takes care of initialize/uninitialized of Plug in.
While in Python we need to take care of this through separate functions

All computations will go in doIt function of class derived from Maya's Library,

Stand Alone applications can also be written using any of both APIs.

Here are some sites for Python development,
http://www.daniweb.com/forums/forum114.html
http://aspn.activestate.com/ASPN/

Happy Developing,
:-)

Maya API Development

Ok,

Here starting Maya API Development,

First some good resources,

http://www.robthebloke.org/
http://hohehohe2.hp.infoseek.co.jp/openMaya-eng/0mokuji.html
http://florian.loitsch.com/gpExport/

And Complete Maya Programming Vol 1 and 2 by David Gould,

:-)

Vishang Shah

ScanMayaFile.py

'''
This Python script will check for naming convention errors in
all mayaAscii files in given director path.
wxPython must be installed for GUI of the Script.
'''
# ScanMayaFile.py
import os
import wx
import re
from mayaFileScanBaseClass import mayaFileScanBaseClass

class mayaScanUI(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(900, 700))
        self.SetIcon(wx.Icon('M:/212p-asset_lib/mel/icons/mickey_small.bmp',\
        wx.BITMAP_TYPE_ICO))
        panel = wx.Panel(self, -1)

        font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
        font.SetPointSize(9)

        vbox = wx.BoxSizer(wx.VERTICAL)

        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        st1 = wx.StaticText(panel, -1, 'Directory :')
        st1.SetFont(font)
        hbox1.Add(st1, 0, wx.RIGHT, 8)
        self.tc1 = wx.TextCtrl(panel, -1,size=(100,22))
        hbox1.Add(self.tc1, 2)
        btn1 = wx.Button(panel, 101, 'Browse', size=(50, 23))
        hbox1.Add(btn1,0)
        vbox.Add(hbox1, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10)

        #vbox.Add((-1, 2))

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        st2 = wx.StaticText(panel, -1, 'Log File  :')
        st2.SetFont(font)
        hbox2.Add(st2, 0, wx.RIGHT, 8)
        self.tc2 = wx.TextCtrl(panel, -1,size=(100,22))
        hbox2.Add(self.tc2, 2)
        btn2 = wx.Button(panel, 102, 'Browse', size=(50, 23))
        hbox2.Add(btn2,0)
        vbox.Add(hbox2, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10)

        vbox.Add((-1, 10))

        hbox4 = wx.BoxSizer(wx.HORIZONTAL)
        st3 = wx.StaticText(panel, -1, 'Error Log')
        st3.SetFont(font)
        hbox4.Add(st3, 0)
        vbox.Add(hbox4, 0, wx.LEFT | wx.TOP, 10)

        vbox.Add((-1, 10))

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.tc_txt = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
        hbox3.Add(self.tc_txt, 1, wx.EXPAND)
        vbox.Add(hbox3, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 10)

        vbox.Add((-1, 25))

        vbox.Add((-1, 25))

        hbox5 = wx.BoxSizer(wx.HORIZONTAL)
        btn_scn = wx.Button(panel, 104, 'Scan', size=(70, 30))
        hbox5.Add(btn_scn, 0)
        btn_cl = wx.Button(panel, 103, 'Close', size=(70, 30))
        hbox5.Add(btn_cl, 0, wx.LEFT | wx.BOTTOM , 5)
        vbox.Add(hbox5, 0, wx.ALIGN_RIGHT | wx.RIGHT, 10)

        panel.SetSizer(vbox)
        self.Centre()
        self.Show(True)
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=103)
        self.Bind(wx.EVT_BUTTON, self.opendir, id=101)
        self.Bind(wx.EVT_BUTTON, self.openfile,id=102)
        self.Bind(wx.EVT_BUTTON, self.scan_mayafile,id=104)

    def OnClose(self,event):
        self.Close()
    def opendir(self, event):
        dlg = wx.DirDialog(self, "Choose a directory:",\
        style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
        if dlg.ShowModal() == wx.ID_OK:
            self.tc1.AppendText(dlg.GetPath())
        dlg.Destroy()
    def openfile(self, event):
        dlg = wx.FileDialog(self, "Save Log File", os.getcwd(), "", "*.txt", wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            mypath = os.path.basename(path)
            self.tc2.AppendText(path)
        dlg.Destroy()
    def scan_mayafile(self,event):
        '''Scans All Maya Files'''
        basedir = self.tc1.GetValue()
        logfile = self.tc2.GetValue()
        epnames=['Prefix_']

        for root,dirs,files in os.walk(basedir):
            for f in files:
                if(f.endswith('.ma')):
                    st =('\n\n-------------------------------------------------------------\n'+\
                    'Scanning File : '+os.path.join(root,f)+'\n--------------------------------\
                    -----------------------------'+'\n\n')
                    self.tc_txt.AppendText(st)
                    file = mayaFileScanBaseClass(os.path.join(root,f))
                    nodenames = file.fileScan()
                    for n in nodenames:
                        st =('Incorrect Node Name : '+n+'\n')
                    ftnpaths = file.fileScan_ftn()
                    if len(ftnpaths) > 0:
                        for ftn in ftnpaths:
                            if os.path.exists(ftn):
                                sub = ftn.split('/')
                                substr = sub[len(sub)-1]
                                i = 0
                                for j in epnames:
                                    if substr.startswith(j):
                                        i = 1
                                        start = j
                                        break
                                if i==0:
                                    st =('File Name Wrong : '+substr+'\n')
                                    self.tc_txt.AppendText(st)
                                else:
                                    substr2 = substr.strip(start)
                                    if len(re.findall('\W',substr2[0:-4])) > 0:
                                        st =('Illegal Characters : '+substr+'\n')
                                        self.tc_txt.AppendText(st)
                            else:
                                st =('Missing File : '+ftn+'\n')
                                self.tc_txt.AppendText(st)
        #log.write('\n------------------------------------------------------------------\n')
        self.tc_txt.AppendText('\n--------------------End of Scanning\
        ----------------------------------------------\n')
        if logfile != '':
            log = open(logfile,'w')
            log.write(self.tc_txt.GetValue())
            log.close()

app = wx.App()
mayaScanUI(None, -1, 'Scan mayaFile for Shader/Texture Network')
app.MainLoop()

mayaFileScanBaseClass.py

# Definition of Class to scan given Maya Ascii File
import re
import os

class mayaFileScanBaseClass:
    def __init__(self,filename):
        self.filename = filename
    def fileScan(self):
        '''Scans File for 'createNode' and looks for shading nodes'''
        fid = open(self.filename)
        output = []
        epnames=['Prefix_']
        for line in fid:
            if line.startswith('createNode'):
                words = line.split(' ')
                nodeTypes = ['lambert','shadingEngine','materialInfo','bump2d',\
                'bump3d','blinn','file','place2dTexture','place3dTexture',\
                'anisotropic','rampShader','phong','ramp','blendColors',\
                'surfaceLuminance','clearCoat','layeredTexture','samplerInfo']
                for n in nodeTypes:
                    if words[1]==n:
                        names = line.split('-n ')
                        name = names[1].split('"')
                        namechk = name[1].replace(words[1],'')
                        if(not namechk.islower()):
                            output.append(name[1])
                        else:
                            i = 0
                            for j in epnames:
                                if(name[1].startswith(j)):
                                    i = 1
                                    break
                            if i==0:
                                output.append(name[1])
                            else:
                                if len(re.findall('\W',name[1])) > 0:
                                    output.append(name[1])
        fid.close()
        return output
    def fileScan_ftn(self):
        '''Scans File for ftn nodeType and does texture\
        name checking and check if texture file exists '''
        fid = open(self.filename)
        paths = []
        for line in fid:
            if re.compile('.ftn').search(line,1):
                path = line[32:-3]
                paths.append(path)
        return paths