MaxScript – bake animation to vertex

Okay, so this was an attempt to transfer some animation into vertex positions and set key-frames on each vertex . Remove the animation at the end from the object itself, so that we  are left with “baked” vertices.  If you try to copy/paste and run this – probably a ton of errors will take place, but if you study this -> a lot of good can come out ( now this is mainly a personal note 😉 )

fn collectVertPosition geometryNode VertexList  = 
(
	for v=1 to (polyop.getNumVerts geometryNode) do
		(
			vertex = polyop.getVert geometryNode v
			append VertexList vertex
		)
)

fn getXYZlocation vertexList axis = 
(
	for v = 1 to vertexList.count do 
	(
		if (axis == "x" or axis == "X") then 
			(
				vertX = vertexList[v].x
				return vertX
			)
		if (axis == "y" or axis == "Y") then 
			(
				vertY = vertexList[v].y
				return vertY
			)
		if (axis == "z" or axis == "Z") then 
			(
				vertZ = vertexList[v].z
				return vertZ
			)
	)
)

fn updateXYZlocation vertList axis location = 
(
	for v = 1 to vertexList.count do 
	(
		if (axis == "x" or axis == "X") then 
			(
				vertexList[v].x = location
			)
		if (axis == "y" or axis == "Y") then 
			(
				vertexList[v].y = location
			)
		if (axis == "z" or axis == "Z") then 
			(
				vertexList[v].z = location
			)
	)
)

-------------------------
sliderTime = 0
--animateVertex $ #all
originalModel = $

------------------------------------------------------------
--Create TMP model and append to TMP Layer
targetMeshModel = copy originalModel
targetMeshModel.name = "baked_" + originalModel.name
targetAnimation = LayerManager.newLayer()
targetAnimation.setname "Baked_Animation"
targetAnimation.addnode targetMeshModel
----------------------------------------------------------
targetMeshModel = convertToMesh targetMeshModel
--targetMeshModel = convertToPoly targetMeshModel

sourceVertexList = #()
targetVertexList = #()

collectVertPosition originalModel sourceVertexList
collectVertPosition targetMeshModel targetVertexList

format "source Verts Count: %" sourceVertexList.count
format "target Verts Count: %" targetVertexList.count

--enable animation of the Vertex for Target Node
animateVertex targetMeshModel #all

--set keys to Target Node
with animate on
	(
		for frame=0 to 120 do 
		(
			for v = 1 to meshop.getNumVerts targetMeshModel do 
				(
					with animate on at time frame meshop.setVert targetMeshModel v sourceVertexList[v]
					x = getXYZlocation sourceVertexList "x"
					y = getXYZlocation sourceVertexList "y"
					z = getXYZlocation sourceVertexList "z"
					updateXYZlocation targetVertexList "x" x
					updateXYZlocation targetVertexList "y" y
					updateXYZlocation targetVertexList "z" z
				)
			sliderTime = frame
			sourceVertexList = #()
			collectVertPosition originalModel sourceVertexList
					
		)

	)
Advertisements

About that GDC talk i did while working in New Zealand

Okay, so at the time it was all calm and everything was just fine, i had been doing some routine work at the studio, making sure our deliverables were on time and that artists could talk to programmers 😉

When our PR had sent out email asking for volunteers to present at an upcoming New Zealand GDC… No real alarms had been going off in my head, and i safely ignored this email and carried on with my duties.

A little time later, i had to take a several interviews for Technical Artists positions that we had opened at the time, and most of the interviews where via Skype.  While being all confident with my skills and that my bosses recognized a TRUE ME in ME 🙂 (lol) , i made a huge list of tech-questions that i was using to “filter” the right candidate. To my surprise, most of the candidates failed… Very few were able to even come close to some of the tech questions i had. And as for me, those were quite standard, considering that position for a Senior Level too.

Now, let me get that email from PR-Lady again… and Listen – i want to do this talk, I have a great topic, is what i replied.

Here it is…

Go from Student to Technical Artist

MaxScript – Zero-out those controls

So for some time at the studio i was doing some coding for rigging, and had to experiment with a few things here and there.
Most of the controls in rigs, for those that don’t know, require relative transformation control, so that component, could look twisted, but is actually at Zero values on all axis in Local space, Often in rig you get this level of control using parenting and some Dummy() objects or Point() objects.
So here is a snipped from a bigger code that takes care of this in maxscript.

fn getParentRoot theNode = 
(
	theParent = theNode
	while (isValidNode theParent.parent) do
	( theParent = theParent.parent )
	return theParent
)
	
fn childildExists obj = 
(
	if obj.childildren.count != undefined then
	( return True )		
)

my_obj = getNodeByName "Box002"
root_bone = getParentRoot my_obj
	
if (childildExists root_bone) then 
(
	root_point = Point()
	root_point.pos = root_bone.pos
	for child in root_bone.childildren do 
		(
			if (childildExists child) then (
				print child.name )
			else
			(
				point_ = Point()
				point_.pos = child.pos
				point_.parent = root_point
			)
		)
)

Open and add text to image in Python

Here i found an oldrer code snipped that served as my RnD for a thumbnail application that i made for my studio. This code snipped uses very simple.  here is what this snippet does:

We create a new Canvas 512×512, and open another image from our HDD, Resizing the image to desired size, in my case it was 128×128, and i am sure i had a good reason for all these sizes :), we also set the Font that we want to use, here i explicitly copied font file to so opened location, just to avoid some security troubles with Windows folder and all that, we combine our canvas and image together and add text at some location, in red, and as a last step – save this new image somewhere on the disk.

Now, why is this here, often , in production i come about really frequently repeated actions, of assembling some sort of Daily report or something similar, so, if this code is adapted into a very simple structure, you can have a pretty powerful application that allows to save a lot of time in assembly of these assets… really up to your imagination how one could use it.

i want to have this code here for my own reference, and for anyone who is after some ideas for automation.. or what not 🙂
 

from PIL import Image, ImageFont, ImageDraw
font = ImageFont.truetype("C:/arial.ttf", 22)
im = Image.new("RGB", (512, 512), "black")
im2 = Image.open("c:/1.png")
im2 = im2.resize((128,128))
draw = ImageDraw.Draw(im)
im.paste(im2, (10,10))
draw.text((100,100), "Hello", font=font, fill=(255,0,0))
im.save("C:/test.jpg")

MaxScript – Standard Material Ops

This is a short code snippet that shows how to create and set material instance for an object using maxscript. this can be wrapped into a function or struct-method. i thought i would post it here so that i can get to this later when or if i will ever need this.

--Making dummy object
b=box()
--creating material instance
b.material = Standardmaterial()
--assigning BitmapTextures to specific channels
b.material.diffuseMap = Bitmaptexture()
b.material.specularMap = Bitmaptexture()
b.material.bumpmap = Bitmaptexture()
--specify files for bitmaps
b.material.diffuseMap.filename = @"D:\Diffuse_D.bmp"
b.material.specularMap.filename  = @"D:\Specular_M.bmp"
b.material.bumpmap.filename = @"D:\Normal_N.bmp"
--let material be visible in viewport
b.material.showinViewport = True

Maya Open/Close CommandPort

This is a pretty popular code snippet that i am rather reposting for my own sake, as i always have to google for it online, and i find some of the code being modified here and there, so i am posting my own version on my own blog. that i have modified for my own purposes 🙂 and if anyone happens to see this: enjoy 🙂
 

import maya.cmds as cmds
# Close ports if they were already open
try: cmds.commandPort(name=":7001", close=True)
except: cmds.warning('Could not close port 7001')
try: cmds.commandPort(name=":7002", close=True)
except: cmds.warning('Could not close port 7002')
# Open ports
try: cmds.commandPort(name=":7002", sourceType="python")
except: cmds.warning('Could not Open port 7002')	
try: cmds.commandPort(name=":7001", sourceType="mel")
except: cmds.warning('Could not close port 7001')

Clean code

In a desperate search for advanced programming tutorials , my co-worker Igor had suggest a great reading material, by Robert C. Martin – “Clean Code”.

While this book is based around Java, it does not stop me from applying the same principles for my python development.

So far,  am almost at the end of the book, around chapter 12, but already had used an saw great improvement with my current projects. I now look back at my old code, and think GOSH… how could i even write that ? But we had all been there before, and this is a great way to see progress.