View Full Version : reproduce the autogrid function using maxscript

10 October 2009, 05:03 PM
my problem is to reproduce the autogrid function using maxscript(applied to a face center).
I created a small script to show you my problem.
here it is:

fn createAPlane theName=(
thePlane=plane width:150 length:150 lengthsegs:1 widthsegs:1 name:theName
convertToPoly thePlane

fn fingAngleFrom3Points A B C =
acos(dot n1 n2)

fn findZorientation norm =
C=normalize C

if X!=0 then
((fingAngleFrom3Points A B C)*(X/abs X))
(fingAngleFrom3Points A B C)

fn generateTransformationMat obj =
theNormal=polyop.getFaceNormal obj 1

Zorientation=findZorientation (copy theNormal)

theNormalMatrix=matrixFromNormal theNormal

theFaceCenter=polyOp.getFaceCenter obj 1

theMat=matrix3 1

rotateZ theMat (Zorientation)

rotate theMat (theNormalMatrix.rotationpart )

translate theMat theFaceCenter


theFirstPlane=createAPlane "first plane"
theSecondPlane=createAPlane "Second plane"

move theFirstPlane [200,0,0]

rotate theFirstPlane (eulerangles 40 0 0)
rotate theSecondPlane(eulerangles 40 0 20)

theFirstBox=box name:"first box" width:14 lenght:25 height:12 transform:(generateTransformationMat theFirstPlane)

theSecondBox=box name:"second box" width:14 lenght:25 height:12 transform:(generateTransformationMat theSecondPlane)

execute the script, it create two planes with two boxes in the center(their orientation should be like the one obtained with the autogrid)

If you manually create a box in each plane(with the autogrid function) you should notice that the one on the plane named "second plane" has a different orientation than the one created by script.
I need do replicate the exact autogrid function ad I can't find were I am wrong.
Someone could help me?

p.s. sorry for my english

10 October 2009, 07:26 PM
No idea what you are apologizing for - both your English and your MAXScript are pretty good. In fact this is one of the best demonstrations of how to ask questions on a forum I have seen in a long time.

I suspect that the AutoGrid uses a fixed up vector to calculate the other vectors, with a special case handling for normals parallel to the up vector where the X is assumed instead.

Here is an attempt to get the same result:

fn generateTransformationMat obj =
local theFaceCenter=polyOp.getFaceCenter obj 1 --get the face center
local theNormal=polyop.getFaceNormal obj 1 --get the face normal

local theUp = [0,0,1] --define an up vector
local theX = if acos (dot theUp theNormal) < 0.001 then --if the normal is nearly pointing up,
[1,0,0] --assume the X to be the world X
normalize (cross theNormal theUp) --otherwise perpendicular to the up vector and the normal
local theY = normalize (cross theNormal theX) --the Y will be perpendicular to both N and X
matrix3 theX theY theNormal theFaceCenter --the matrix will use the 3 axes and the center

10 October 2009, 12:00 AM
it seams like you want to align object to a face of another object using face's normal as UP vector for the aligning object...

here is my approach:

fn alignToFace source target face:1 = if isvalidnode source and iskindof target Editable_Poly do
center = polyop.getfacecenter target face
normal = polyop.getfacenormal target face

source.transform = translate (arbmatrix normal) center

but... this arbitrary matrix is OK if you don't care about spin around UP axis. If you want specifically orient the source object you have to add some rule...

#1: Use vector from face's vert 1 to vert 2 as FRONT

verts = polyop.getfaceverts target face
up_vector = polyop.getfacenormal target face
front_direction = normalize ((polyop.getvert target verts[1]) - (polyop.getvert target verts[2]))
right_vector = normalize (cross up_vector front_direction)
-- re-calculate front_vector to be 100% sure that it's orthogonal to UP and RIGHT
front_vector = normalize (cross right_vector up_vector)
-- create new matrix using three vectors and face's center position
source.transform = matrix3 front_vector right_vector up_vector center

#2: You can define any vector to use its direction as FRONT
sample - Y world as FRONT:

front_direction = [0,1,0] ... --- after that make the same calculations as above

PS. i could be wrong with vector directions... please double-check it and change direction of RIGHT or FRONT vector of final matrix to negative if it's necessary.

10 October 2009, 01:45 PM
thanks for replies!!
I tried both version and I think I'll use the one posted by bobo.
The reason is that it's vertex independent and since my script works on n-side faces it's the best solution.
I never thought to build a matrix with the three vector axis and the translation part, It's a really interesting way.

thanks again


CGTalk Moderation
10 October 2009, 01:45 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.