Monday, December 2, 2013

Voxels part 2. MAYA .NET API and MFnMesh::allIntersections.

In part one we created a simple script, which generates voxels for a selected mesh object using
MFnMesh::allIntersections function. In this part we are going to write a VoxelGenerator node using Maya .NET API. Why node? Because we want to update our voxel on mesh changes. Actually I believe this node can be created using Maya python API, but i did it using C# in order to learn it, and check how usefull it is.

Let's define node attributes. Number and position of voxels depend on a grid density and a base object position in 3D space. So the input attributes should be: input - (short) "density", (kMesh) "inputGeometry", and output - (int) "voxelsNumber".

I use Microsoft Visual Studio 2013 and Autodesk Maya 2014. For easy start download and install Maya C# Wizards for Visual Studio. You can find it in Cyrille Fauvel blog. After the installation create a new maya plugin in the Visual Studio and let's begin!


Tuesday, November 5, 2013

Creating voxels in Maya, or how to work with MFnMesh::allIntersections. Part 1

Hello everyone,
I would like to share with you some interesting stuff.

Let's fill an object with voxels. In order to do it we need to determine if voxel point is inside the mesh. And it's true, if a ray started at this point in any direction, intersects mesh triangles and number of intersections are even.

Wednesday, May 29, 2013

MAYA: Snippet for curve knot vector.

In order to create curve by CVs we need to construct knot vector. It should have numberOfCVs + degree - 1 knot values. This small snippet takes number of CV and degree of the curve, and returns knot vector values as list. Maybe it will be useful for somebody.
def createKnotVectorString(cvNum, degree):
    """
    @param int cvNum: number of CVs in constructing curve.
    @param int degree: degree of constructing curve.
    @return list
    """
    if cvNum <= degree:
        print "warning, number of CVs can't be less than degree + 1"
        return None
    tailsSize = degree
    knotsNum = cvNum + degree - 1
    knotsArray = [0]*knotsNum
    for i in range(0, len(knotsArray)-degree+1):
        knotsArray[i + degree-1] = i
    tailValue = knotsArray[-tailsSize-1] + 1
    for i in range(1,tailsSize):
        knotsArray[-i] = tailValue
    return knotsArray

print  createKnotVectorString(4, 3)

Tuesday, March 19, 2013

Open MAYA API: Working with iterators (part 2)

As a part of tools for work with polygon hairs i created small script to select cap edges of poly stripes. The task was: create script which converts any selection (poly object, poly vertices, poly edges or poly faces) to edges which lie on the caps of poly stripes.


Wednesday, March 13, 2013

Open MAYA API: Working with iterators (part 1)

Iterators are special classes which have methods to  navigate through objects or components.
MItSelectionList- navigate through selected objects
MItDependencyNodes - navigate through all maya nodes. Especially useful to navigate through specific type of maya objects. For example to traverse all cameras, or lights, or meshes.
MItMeshPolygonMItMeshVertexMItMeshEdgeMItMeshFaceVertex to navigate through specific components of the poly object.

Monday, February 4, 2013

Allow only one instance of python script.

What if you need to run python script only if it's not already running? Or kill old copy before run new one? One of the way is:

  • Check if special file exists. If it's true, one copy of script is already running. Now kill it or exit from second copy.
  • Create temporary file with PID of script process.
  • Delete pid-file at the end of the script.
Here is the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import tempfile
import ctypes
import os

# Path to file storing PID of running script process. 
# Place it outside of methods in the beggining, or make sure it visible for all methods, which use it.
pid_file = tempfile.gettempdir() + 'tmp_armor_pid.txt'   

# This method checks if file pid_file exists. 
#  If it was found, depends of mode - exit, or kill process which PID is stored in file.  
def scriptStarter(mode = 'force'):
    '''
        if mode  = force - kill runing script and run new one
        if mode != force - run script only if it's not already running
    '''
    if os.path.exists(pid_file):
        print 'old copy found'
        if mode == 'force':
            print 'running copy found, killing it'
            # reading PID from file and convert it to int
            pid = int((open(pid_file).read()))  
            print 'pid have been read:', pid
            # If you use pythton 2.7 or above just use os.kill to terminate PID process.
            # In case of python 2.6 run method killing selected PID
            kill(pid)         

        else:
            print 'running copy found, leaving'
            # not force mode. Just don't run new copy. Leaving.
            raise SystemExit           

 # If we are here, mode == force, old copy killed, writing PID for new script process 
    open(pid_file, 'w').write(str(os.getpid()))  


def kill(pid):
    """kill function for Win32"""
    kernel32 = ctypes.windll.kernel32
    handle = kernel32.OpenProcess(1, 0, pid)
    return (0 != kernel32.TerminateProcess(handle, 0))

# Delete pid-file befor script finish.  
# Dont forget to run this method at the end of the script
# If you use PyQt call it in overloaded closeEvent() 
def removePIDfile():
    print 'deleting pidfile'
    try:
        os.remove(pid_file)
    except OSError:
        pass
    return


def main():
 # check if script is already running 
    scriptStarter('force')    
 '''YOUR SCRIPT CODE HERE'''
 
 # remove pid-file before exit.
 removePIDfile()

if __name__=="__main__":
    main()

Sunday, February 3, 2013

Sublime Text editor customization.

Sublime Text - very powerful and flexible text editor. It has syntax highlight and auto-complete for different programming languages, including python. Also, you can find syntax highlighting files for maya MEL. One of the most useful thing in Sublime is multiline edit. This feature is awesome. Check official web site of this editor for more info and download. I'm sure you will like it.
Although it has nice look by default i want to tell you about two improvements i use to get look of it like on screenshot below:

Tuesday, January 15, 2013

Crease Edges to Hard, Hard Edges to Crease.

Hard edges are  the best way to represent crease edges on low poly model. But when modelling it can be difficult to keep these two edge properties in proper order, due to constantly changing of the model. This little script will help you to do it.
It works in two modes:
  • crease2Normal - makes crease edges hard (and vise versa, not crease edges - soft) 
  • normal2Crease - makes  hard edge crease.
Take a look at screenshots below to see how it works.