Notifications
Clear all

[Closed] Align uvw map to vertex and edge

I’m trying to build a script which aligns a fixed size uvw planar map to the face of a poly, where the top of the uvw gizmo faces an edge that a user selects and it it would align the side of the gizmo to a vertex that a user can also select.

I already have the script in place that lets the user quickly select the edge and vertex. From that I’ve tryed building upon the script from this thread http://forums.cgsociety.org/showthread.php?f=98&t=425252
But that doesn’t always seem to align the gizmo to the selected edge when the object has some kind of rotation.

I don’t have a lot of knowledge on transforms and matrices so i figured I would just align the gizmo to a vertex by taking the position of the gizmo and putting it on the position of the vertex, but that doesn’t work properly since the gizmo is in object space.

Is there a way to figure out the transform of a vertex so that you can get the position of it in object space (or is that even the right way to go about this).

This is what I had so far, script from that thread, the last lines were mine, which obviously don’t work.


fn getLocalFaceBounds theObj theFace = (
local bigNum = 999999.9
local bbMin = [bigNum, bigNum, bigNum]
local bbMax = [-bigNum, -bigNum, -bigNum]
local verts = (polyOp.getVertsUsingFace theObj theFace) as Array
for vIndex in verts do (
local v = in coordsys theObj (polyOp.getVert theObj vIndex)
if v.x < bbMin.x do bbMin.x = v.x
if v.y < bbMin.y do bbMin.y = v.y
if v.z < bbMin.z do bbMin.z = v.z
if v.x > bbMax.x do bbMax.x = v.x
if v.y > bbMax.y do bbMax.y = v.y
if v.z > bbMax.z do bbMax.z = v.z
)
return #(bbMin, bbMax)
)
 
fn alignUVGizmo theObj theFace theEdge theVertex gizmoLength gizmoWidth = 
(
gizmoLengthOver2 = float(gizmoLength) / 2.0
case (classof theObj) of (
editable_mesh: (
faceNormal = in coordsys theObj (getFaceNormal theObj theFace)		
verts = (meshop.getVertsUsingEdge theObj theEdge) as array
v2 = in coordsys theObj (getVert theObj verts[2])
v1 = in coordsys theObj (getVert theObj verts[1])
)
editable_poly: (
faceNormal = in coordsys theObj (polyop.getFaceNormal theObj theFace)
verts = in coordsys theObj (polyop.getVertsUsingEdge theObj theEdge) as array
v2 = in coordsys theObj (polyop.getVert theObj verts[2])
v1 = in coordsys theObj (polyop.getVert theObj verts[1])
)
)
bounds = getLocalFaceBounds theObj theFace
bbMin = bounds[1]
bbMax = bounds[2]
bbCenter = (bbMin + bbMax) / 2
faceNormal = normalize faceNormal
edgeVector = normalize (v2 - v1)
rightVector = normalize (cross edgeVector faceNormal)
 
edgeCenter = (v1 + v2) / 2.0
gizmoEdgeCenter = bbCenter + rightVector * gizmoLengthOver2
bbCenterToEdgeCenter = edgeCenter - bbCenter
bbCenterToGizmoEdgeCenter = gizmoEdgeCenter - bbCenter
offset = bbCenterToEdgeCenter - bbCenterToGizmoEdgeCenter
if (dot rightVector (normalize bbCenterToEdgeCenter)) > 0 do (
rightVector = -rightVector
)
theMatrix = matrix3 edgeVector rightVector faceNormal offset
 
undo "Align Gizmo" on (
theMap = Uvwmap()
modPanel.addModToSelection theMap ui:on
theMap.maptype = 0
theMap.length = gizmoLength
theMap.width = gizmoWidth
theMap.mapChannel = 2
theMap.gizmo.transform = theMatrix
 
--in coordsys #local theMap.gizmo.pos = polyop.getVert theObj theVertex
--in coordsys #local theMap.gizmo.pos += [(gizmoWidth / 2),(gizmoLength / 2),0]
)
)

2 Replies

Ok I’m a bit further on where i want to be, I actually don’t need all the stuff that I posted earlier, but rather I only need the uwvmap to align to a vertex. This works well with this from the max help:


fn alignUVGizmo theObj theFace theVertex =
(
 faceNormal = in coordsys theObj (polyop.getFaceNormal theObj theFace) 
 worldUpVector = [0,0,1] 
 rightVector = normalize (cross worldUpVector faceNormal) 
 upVector = normalize ( cross rightVector faceNormal )
 theMatrix = matrix3 rightVector upVector faceNormal [0,0,0] 
 theMap = Uvwmap()
 theMap.length = 300
 theMap.width = 200
 theMap.mapchannel = 2
 modPanel.addModToSelection theMap ui:on
 theMap.gizmo.transform = theMatrix 
 in coordsys #local theMap.gizmo.pos = polyop.getVert theObj theVertex
)
alignUVGizmo $ 1 1

This aligns the center of the gizmo to the selected vertex, in this example 1, and I just had the material that I apply have an offset of 0.5, this actually works out better for scaling control.

I’m building this to quickly apply a rooftile to a roof surface.

However what happens with this is that the uvw map follows the rotation of the selected face (the poly object is always a flat polygonal object so face 1 can always be used as its the same as any others) but what I want is for the UVW gizmo to always face upwards, I think the UVW up vector is Y. The face rotation doesn’t always have the Y facing upwards.

So how do I make the UVW gizmo always face upwards, but still align to the face normals rotation in the other axis. I’ve attached a screenshots to illustrate what goes wrong and how i actually want it to be.

Well I figured out a workaround in my case. I just had to do a resetxform and then convert it back to editable poly for this to work.