# Align and Size a Plane() to EPoly Quads...

 10 October 2012 #1 wallworm Shawn Olson   portfolio Shawn Olson Wall Worm Columbus, USA   Join Date: Jul 2011 Posts: 222 Align and Size a Plane() to EPoly Quads... I have a MXS function that is supposed to create Plane() primitives that align with rectangular quads on EPoly objects and make the Plane match the size of the quad. My problem is determining the the Length/Width of the Plane--I can get the correct values for length and width I cannot figure out how to determine which is actually the length and the width (for example, the value I get for width sometimes belongs to length and vice versa). Here is the function: Code: ``` function wallworm_create_plane_from_polygon polynode faceId forceQuad:true power:2 = ( if ww_wwdt_control_mesh == undefined then ( in coordsys world ( if classOf polynode == editable_poly then ( --verts = polyop.getVertsUsingFace polynode #{faceId} verts = polyop.getFaceVerts polynode faceId if verts.count == 4 OR forceQuad==false then ( v1 = polyop.getVert polynode verts[1] node:polynode v2 = polyop.getVert polynode verts[2] node:polynode v3 = polyop.getVert polynode verts[3] node:polynode v4 = polyop.getVert polynode verts[4] node:polynode d1 = distance (v1) (v2) d2 = distance (v2) (v3) --segs = ww_wwdt_vmfpowertosegs power --func not present in sample... assign manually segs = 4 l = d2 w=d1 faceNormal = in coordsys polynode (polyop.getFaceNormal polynode faceId node:polynode) local brsh = Plane length:l width:w isSelected:off lengthsegs:1 widthsegs:1 pos:(polyop.getSafeFaceCenter polynode faceId node:polynode) /* worldUpVector = [0,0,1] rightVector = normalize (cross worldUpVector faceNormal) upVector = normalize ( cross rightVector faceNormal ) theMatrix = matrix3 rightVector upVector faceNormal [0,0,0] brsh.transform = theMatrix */ --Move the new mesh to the center of the face. brsh.pos = (polyop.getSafeFaceCenter polynode faceId node:polynode) --Make the new mesh face in the direction of the face brsh.dir = faceNormal --make a copy of the new mesh to determine if the verts of the mesh are aligned to verts of the original face. --This does assume rectangular faces. tmp = copy brsh convertToPoly tmp tmpverts = polyop.getFaceVerts tmp 1 tmpv1 = polyop.getVert tmp tmpverts[1] node:tmp nverts = #(v1,v2,v3,v4) format "\n###############\nFace Verts: % % % %\n" v1 v2 v3 v4 format "New Verts: %\n" tmpv1 /* See if the first vert in the tmp mesh aligns with a vert in the original face. If none, swap the length and width. */ if findItem nverts tmpv1 == 0 then ( print "changing l/w" brsh.length = w brsh.width = l ) delete tmp brsh.lengthsegs = segs brsh.widthsegs = segs if polynode.mat != undefined then brsh.mat = polynode.mat return brsh ) else ( format "The selected face % has % verts!\n" faceId verts.count ) ) else ( ) ) ) undefined ) ``` I have assumed that the following code would determine if the plane dimensions match the face... but it simply fails sometimes: Code: ``` if findItem nverts tmpv1 == 0 then ( print "changing l/w" brsh.length = w brsh.width = l ) ``` What is odd is that the findItem sometimes (but not always) fails when the values look identical to me... for example, here is a line in the listener from a failure: Code: ``` ############### Face Verts: [-70,146,128] [-70,146,256] [-70,274,256] [-70,274,128] New Verts: [-70,274,256] "changing l/w" ``` But as you can see, the Point in New Verts [-70,274,256] does exist in the Face Verts... but the findItem function returns 0 (and the script fails). Maybe I should try another approach altogehter... but I still want to know how that fails. Question 2: Also, while discussing this, which of the following two methods is best for the orientation? I always see docs mentioning the first but the second seems to produce the same results: Method 1: Code: ``` worldUpVector = [0,0,1] rightVector = normalize (cross worldUpVector faceNormal) upVector = normalize ( cross rightVector faceNormal ) theMatrix = matrix3 rightVector upVector faceNormal [0,0,0] brsh.transform = theMatrix --Move the new mesh to the center of the face. brsh.pos = (polyop.getSafeFaceCenter polynode faceId node:polynode) ``` Method 2: Code: ``` --Move the new mesh to the center of the face. brsh.pos = (polyop.getSafeFaceCenter polynode faceId node:polynode) --Make the new mesh face in the direction of the face brsh.dir = faceNormal``` __________________ Shawn Olson Autodesk Expert Elite 3ds Max Charter Member Developer of: Wall Worm Tools for the Source Game Engine CorVex Level Design Plugin Last edited by wallworm : 10 October 2012 at 07:40 PM. Reason: clarification share quote
10 October 2012   #2
Hi, Shawn!
This
Quote:
 findItem sometimes (but not always) fails

happens to me sometimes. I think(but I am not sure) that max prints
[-70,274,256], but the real values is
[-70.0001,274,256] or something like this. And when two point3 values are compared, the findItem fails.
The maxscript Pro guys will give you the best advice, but you can try to compare values, using
close_enough
__________________

 10 October 2012 #3 miauu Expert   portfolio Kostadin Kotev Blagoevgrad, Bulgaria   Join Date: Sep 2009 Posts: 856 Another stupid idea - convert the positions of the verts to strings and then use findItem. __________________ share quote
10 October 2012   #4
Quote:
 Originally Posted by wallworm I have a MXS function that is supposed to create Plane() primitives that align with rectangular quads on EPoly objects and make the Plane match the size of the quad.

what if the quad is not a perfect rectangle (not-flat or oblique-angled)? how should the plane be aligned in this case? what priorities are?

 10 October 2012 #5 wallworm Shawn Olson   portfolio Shawn Olson Wall Worm Columbus, USA   Join Date: Jul 2011 Posts: 222 @Kostadin ... thanks for those ideas. I started to use the close_enough() approach but while doing it I thought of just checking to see if the distance is closer than 0.5 ... so in the example above, I used this: Code: ``` if distance v1 tmpv1 < 0.1 OR distance v2 tmpv1 < 0.1 OR distance v3 tmpv1 < 0.1 OR distance v4 tmpv1 < 0.1 then ( --the length and width are correct ) else ( --the length and width need to be swapped )``` Of course, it makes assumptions. For example... if the length and width are within 0.1 units it will probably fail. But for the moment it meets my needs. @Denis ... I'm not really certain about what to do in the case of a non-flat surface. But I do want to find a way to get the Plane object to match the shape of the underlying face (but always remain planar). Off the top of my head, I might apply a FFD2x2x2 and make the corners align. The reason I am starting with a Plane primitive is that the target geometry needs to always be a plane with 4, 8 or 16 widthsegs and lengthsegs ... and I think it will be easier to make a plane and deform the outline to a quad face with FFD than to try and calculate where the positions of the verts would be for an object created from scratch; plus... all of the functions used for this geometry all assume a certain ordering of the verts--which matches that of a Plane converted to EPoly. __________________ Shawn Olson Autodesk Expert Elite 3ds Max Charter Member Developer of: Wall Worm Tools for the Source Game Engine CorVex Level Design Plugin Last edited by wallworm : 10 October 2012 at 12:26 AM. Reason: fixed typo share quote
 10 October 2012 #6 Kickflipkid687 Art and Music are Life   portfolio Matthew Lichy%2B 3D Artist United%2BStates   Join Date: Jan 2005 Posts: 1,640 Yeah, FFD sounds like a good idea/approach. If u did it that way, Length and Width might not matter as much, but then its more of just putting the FFD points in the right spots/getting the plane facing the right direction. __________________ http://matthewlichy.com share quote
10 October 2012   #7
Quote:
 Originally Posted by Kickflipkid687 Yeah, FFD sounds like a good idea/approach. If u did it that way, Length and Width might not matter as much, but then its more of just putting the FFD points in the right spots/getting the plane facing the right direction.

Yeah... that's what I'm thinking. I played with it a little earlier today and think it should be straight forward.
__________________
Shawn Olson
Autodesk Expert Elite
3ds Max Charter Member

Developer of:
Wall Worm Tools for the Source Game Engine
CorVex Level Design Plugin

 10 October 2012 #8 Kickflipkid687 Art and Music are Life   portfolio Matthew Lichy%2B 3D Artist United%2BStates   Join Date: Jan 2005 Posts: 1,640 The hard part, maybe, might be getting the points to form a square/rectangle and not criss-cross at the end and form an X. I had this issue before when trying to create new polys from verts. I'm not sure how u can easily fix that, but maybe you know. __________________ http://matthewlichy.com share quote
 10 October 2012 #9 wallworm Shawn Olson   portfolio Shawn Olson Wall Worm Columbus, USA   Join Date: Jul 2011 Posts: 222 Using the FFD concept has become a little trickier than I thought. I found this nifty set of functions ( http://forums.cgsociety.org/archive...p/t-704392.html ) to help along the project, and I see that there is already a script on SP called FFD2Quad that has the functionality that I want generally. After looking through the code for FFD2Quad I see he used the functions linked above also. FFD2Quad has a lot more going on that what I need... so I'm trying to filter it down to the simplest form. But I cannot seem to figure it out... Here is the sample code I have so far (warning ... script deletes all object in current scene): Code: ``` -- these functions from http://forums.cgsociety.org/archive...p/t-704392.html -- convert world coordinates to FFD local (normalized) coordinates -- obj = object containing the modifier -- ffdmod = the actual modifier -- pos = the world coordinate fn wallworm_ffdWorldToLocalPos obj ffdmod pos = ( objTM = obj.objecttransform modTM = (getModContextTM obj ffdmod) * ffdmod.lattice_transform.value modBBMin = getModContextBBoxMin obj ffdmod modBBMax = getModContextBBoxMax obj ffdmod (pos - modBBMin) * (inverse objTM) * inverse modTM / (modBBMax-modBBMin) ) -- set an FFD mod's control point's world coordinate -- obj = object containing the modifier -- ffdmod = the actual modifier -- i = control point index -- pos = new world position fn wallworm_ffdSetWorldPos obj ffdmod i pos = ( cp = ffdmod["Master"][i] ps = wallworm_ffdWorldToLocalPos obj ffdmod pos cp.value = ps ) /*End funcs from ZeBoxx2*/ actionMan.executeAction 0 "40021" -- Selection: Select All delete \$ clearlistener() a = Box length: 64 width:64 height:64 tp = Taper amount:-0.7 addmodifier a tp convertToPoly a for f = 1 to a.numfaces do ( pos = polyop.getFaceCenter a f node:a b=Plane pos:pos mapCoords:true lengthsegs:4 widthsegs:4 b.dir = polyop.getFaceNormal a f node:a ffd=FFD2x2x2 () addModifier b ffd --conformToShape ffd --ffd.deformType = 1 animateVertex ffd #all face = polyop.getFaceVerts a f in coordsys world ( v1 = polyop.getVert a face[1] node:a v2 = polyop.getVert a face[2] node:a v3 = polyop.getVert a face[3] node:a v4 = polyop.getVert a face[4] node:a ) format "############\nFace %\t%\nv1\t%\nv2\t%\nv3\t%\nv4\t%\n\n" f face v1 v2 v3 v4 wallworm_ffdSetWorldPos b ffd 1 v1 /* wallworm_ffdSetWorldPos b ffd 1 v2 wallworm_ffdSetWorldPos b ffd 1 v3 wallworm_ffdSetWorldPos b ffd 1 v4 */ format "Control Points\n1\t%\n2\t%\n3\t%\n4\t%\n5\t%\n6\t%\n7\t%\n 8\t%\n" ffd.control_point_1 ffd.control_point_2 ffd.control_point_3 ffd.control_point_4 ffd.control_point_5 ffd.control_point_6 ffd.control_point_7 ffd.control_point_8 ) ``` No matter which FFD control point I choose, it never aligns to the verts (v1, v2, v3 and v4). Any input? __________________ Shawn Olson Autodesk Expert Elite 3ds Max Charter Member Developer of: Wall Worm Tools for the Source Game Engine CorVex Level Design Plugin share quote
 10 October 2012 #10 denisT MAX Doctor   portfolio Denis Trofimov CA, USA   Join Date: Jul 2009 Posts: 9,945 i really don't understand the idea with FFD. everything seems overcomplicated. here is how i see it: Code: ``` fn alignToQuad node:selection[1] face:undefined = if iskindof node Editable_Poly do ( if face == undefined and node.selectedfaces.count > 0 do face = node.selectedfaces[1].index if face != undefined and (vv = polyop.getfaceverts node face).count == 4 do ( v1 = polyop.getvert node vv[1] v2 = polyop.getvert node vv[2] v3 = polyop.getvert node vv[3] front = normalize (v1-v2) side = normalize (v2-v3) up = normalize (cross front side) side = normalize (cross up front) tm = matrix3 front side up v1 w = (v2*(inverse tm)).x l = (v3*(inverse tm)).y tm = pretranslate tm [w/2, l/2, 0] p = plane width:w length:l widthsegs:1 lengthsegs:1 transform:tm ) ) /* delete objects b = box length:64 width:64 height:32 addmodifier b (taper amount:-0.7) convertToPoly b for f in b.faces do alignToQuad node:b face:f.index */ ``` you can add some extra logic... let's say the width is always shorter than length. in this case you have to check distances between v1,v2,v3. Last edited by denisT : 10 October 2012 at 03:23 PM. share quote
 10 October 2012 #11 denisT MAX Doctor   portfolio Denis Trofimov CA, USA   Join Date: Jul 2009 Posts: 9,945 but the correct way is to find the best BBOX around the quad and use its min/max as values for width/length share quote
 10 October 2012 #12 wallworm Shawn Olson   portfolio Shawn Olson Wall Worm Columbus, USA   Join Date: Jul 2011 Posts: 222 Denis, Thanks for responding. Aligning the planes isn't the issue now... I am trying to take it a step further and force the plane to match the shape of the quad too. That is where the FFD comes in. __________________ Shawn Olson Autodesk Expert Elite 3ds Max Charter Member Developer of: Wall Worm Tools for the Source Game Engine CorVex Level Design Plugin share quote
10 October 2012   #13
Quote:
 Originally Posted by wallworm Aligning the planes isn't the issue now... I am trying to take it a step further and force the plane to match the shape of the quad too. That is where the FFD comes in.

could you post the image that shows how planes should be aligned and deformed in your sample?

10 October 2012   #14
Attached is an example ... on the left is where the planes are aligned to quads only... whereas on the right is how those planes should be.
Attached Images
__________________
Shawn Olson
Autodesk Expert Elite
3ds Max Charter Member

Developer of:
Wall Worm Tools for the Source Game Engine
CorVex Level Design Plugin

10 October 2012   #15
Quote:
 Originally Posted by wallworm Attached is an example ... on the left is where the planes are aligned to quads only... whereas on the right is how those planes should be.

is it not easier to equally divide the quad and flatten it?

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts vB code is On Smilies are On [IMG] code is On HTML code is Off CGSociety Society of Digital Artists www.cgsociety.org Powered by vBulletinCopyright ©2000 - 2006, Jelsoft Enterprises Ltd.
Forum Jump
 Please select one User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home -------------------- Gallery     Latest Entries     Featured Videos     Featured 3D     Featured 2D     CG Awards     Expose12 Call For Entries (closed) Main     News         Press Releases and Media     General Discussion         Legacy Threads     Off Topic     Recruitment     Education Software     Autodesk Maya         Maya Dynamics         Maya Rendering         Maya Character Setup         Maya Programming     Autodesk Miscellaneous         Autodesk MotionBuilder         Autodesk Mudbox         Autodesk Softimage             XSI: Programming             ICE: Interactive Creative Environment     Autodesk 3ds max         3dsMax SDK and MaxScript         3dsMax Tutorials & Tips         3dsMax Resources         Plugins & Add-ons         Particle Flow     Maxon Cinema 4D         Cinema 4D Resources     The Foundry Modo         The Foundry Time Travel Challenge     Pixologic ZBrush     Photoshop / Painter     Side Effects Houdini     Blender     Lightwave 3D         LW Resources         LW Tutorials     Allegorithmic Substance         Substance Painter         Substance Designer     E-on Software Vue     Compositing Software         The Foundry Nuke         Adobe After Effects         Autodesk Effects and Compositing         Eyeon Software Digital Fusion Challenges     Modeling Challenge         Member Model Collection     Digital Matte Painting Challenge         DMP Mini Challenge Collection     Sketch Challenge         Member SKETCH Collection     FXWARS Challenge         Member FXGallery     Lighting Challenges WIP     Professional Feedback     WIP/Critique: 3D     WIP/Critique: 2D         Speedpaints & Sketchbooks     WIP/Critique: Animation     Collaborative Projects Techniques     Art Techniques and Theories     Digital Matte Painting         Digital Matte Painting Mini-Challenge     Modeling     Texturing and Surfacing     Character Rigging     Animation     Lighting and Shaders     Compositing and Editing     Anatomy and Figurative Art         SPOTLIGHT: Best of the Artistic Anatomy and Figurative Art Forum         Tutorials and Workshops         Personal Anatomy & Sketchbook Threads         References, Resources, and Supplies Technical     Virtual Reality     Game Engine     Graphics Programming     Technical and Hardware
Miscellaneous

All times are GMT. The time now is 12:43 PM.