Notifications
Clear all

[Closed] reproduce the autogrid function using maxscript

Hi
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
 	thePlane
 )
 
 fn fingAngleFrom3Points A B C =
 (
 	n1=normalize(B-A)
 	n2=normalize(C-A)
 	--return
 	acos(dot n1 n2)
 )	
 	
 fn findZorientation norm =
 (
 	A=[0,0,0]
 	B=[0,-1,0]
 	C=norm
 	C.z=0
 	C=normalize C
 
 	X=C.x
 	if X!=0 then
 		((fingAngleFrom3Points A B C)*(X/abs X))
 	else
 		(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
 
 	--ZORIENTATION
 	rotateZ theMat (Zorientation)
 
 	--INCLINATION
 	rotate theMat (theNormalMatrix.rotationpart )
 
 	--TRASLATION
 	translate theMat theFaceCenter					
 
 --		RETURN		
 	theMat
 )
 	
 
 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?
Thanks

p.s. sorry for my english

3 Replies

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
  	else 
  		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
   )

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.

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

cheers