[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]
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?
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.