Notifications
Clear all

[Closed] Maxscript – orienting a cube to imported mesh

Hello!

  Currently I'm working on a simple custom import plugin for 3ds Max in Maxscript. I'm importing some geometry from another application, with some custom helpers that I've implemented there (three cubes - middle, front and side).
  
  What I need to achieve is to snap an on-scene point helper to the middle one (easy part) and later orient it in 3d space to overlap with the middle cube. Earlier I was doing it manually, but not only is it time consuming but also there's plenty of room for human error. I tried to use the look-at constraint and point my point (hah!) to the "front" cube, but that still leaves one axis to correct. After a couple of hours fiddling around I decided to ask you beautiful people for some advice or a new direction.
  
 Any and all help much appreciated!

[b]Edit:[/b] I'm currently looking into protractors and trying to figure out a way to calculate proper rotation, based on angles between the middle cube and two smaller ones.

Edit2: Okay, so tinkering with angles is a no-go, too complex and wonky. Instead I started working on normals and two simple cubes (get normal of one of targetCube, calculate position, transformation matrix and apply it to the fitCube), but it still produces a weird effect. Here’s the code:

objNormal = polyOp.getFaceNormal $targetCube 1
   objCenter = $targetCube.pos
   objMatrix = matrix3 (cross objNormal [0,0,1]) [0,0,1] objNormal objCenter
   $fitCube.transform = objMatrix

  Some screen shots to better visualize my problem (three-point version):
  [img] http://i.imgur.com/lPTlZTS.jpg [/img]
  [img] http://i.imgur.com/etVssih.jpg [/img]
5 Replies

Well, it seems that after MUCH trail and error I managed to make something that works… Don’t know if it’s up to standards, but heck, it does what it needs to. I knew I need to use a face normal to get the orientation, but I never checked the two other axis (X and Y) – they became skewed while the targetObject was been rotated. So I thought to myself – “it’s a cube, I’ll get those two axis from edges!”. And… to my astonishment it worked!

If anyone is interested / might have something to improve in this code, here it is:

fn fitHelper targetObj helperObj =
  (
  	--RESET helperObj ROTATION
  	oldTranslateMtx = transMatrix helperObj.transform.pos
  	oldScaleMtx = scaleMatrix helperObj.transform.scale
  	helperObj.transform = oldScaleMtx * oldTranslateMtx
  	mtx = translate (matrixFromNormal (polyOp.getFaceNormal targetObj 3)) targetObj.pos
  	--TRY TO GET PROPER Y AXIS
  	newY = (polyOp.GetVert targetObj 5) - (polyOp.GetVert targetObj 1)
  	--TRY TO GET PROPER X AXIS
  	newX = (polyOp.GetVert targetObj 2) - (polyOp.GetVert targetObj 1)
  	mtx.row1 = normalize newX
  	mtx.row2 = normalize newY
  	helperObj.transform = mtx
  	helperObj.rotation = normalize (inverse mtx.rotationpart)
  	helperObj.pos = targetObj.center --MUST BE ON END
  )

is it not the same as

align a node to a face of a specified node?

OR

align a node to bounding box of a specified node?

1 Reply
(@shiroiei)
Joined: 11 months ago

Posts: 0

Well, it could be the first one (align a node to face of a specified node, later change its position to the center of specified node) but I don’t think aligning to bounding box would be of an help, as the bounding box of an imported node is the same as I would use reset Xform on a rotated cube.

hopefully i didn’t forget anything:

fn alignUsingFace source target face:1 vorder:[2,1] center:off relative:off = if iskindof target GeometryClass and isvalidnode source do
(
	mesh = snapshotasmesh target
	up = normalize (getfacenormal mesh face)
	vv = getface mesh face
	side = normalize (getvert mesh vv[vorder[1]] - getvert mesh vv[vorder[2]])
	front = normalize (cross side up)
	pos = if center then target.center else (meshop.getfacecenter mesh face)
	
	tm = matrix3 front side up pos 
	
	if relative then
	(
		source.transform *= tm 
	)
	else source.transform = translate (rotate (scalematrix source.transform.scale) tm.rotation) tm.pos 
	
	free mesh
	tm
)	

delete objects
--seed 0
target = box name:#target width:(random 10 20) length:(random 10 20) height:(random 10 20) wirecolor:green \
	pos:(random -[10,10,10] [10,10,10]) rotation:(angleaxis 60 (normalize (random -[1,1,1] [1,1,1])))
source = point name:#source scale:(random [1,1,1] [4,4,4]) cross:on axistripod:on wirecolor:orange isselected:on
alignUsingFace source target face:4 vorder:[3,2] 

Thank you, denisT! It’s really helpful to see how someone would solve my problem, definitely can learn a thing or two from that code. When I started battling with this problem I had no experience or knowledge how all of this works and now it looks a little bit clearer to me.