I was trying to get this on my own and I know it has to be transformed. I still don't understand the transforming between world and local. Below is an image of 2 different roof slopes. I would like to apply 12" x 12" planar mapping but to match the slope of each roof slope.
TIA
We already did this in the thread about UVWMap's gizmo alignment. Did you figure it out?
Just out of curiosity... Do you want to learn MaxScripting or have someone do your work for you?
@denisT.MaxDoctor What you do for me was center the map on the center of the slope and it works.
I tried to figure out rotating the map gizmo to align with the roof slope but it doesn't work. When it comes to transforming I am stuck.
I've been working with maxscript for years but very simple scripts. I'm no where a guru like you.
@denisT.MaxDoctor so I tried with your code for centering and changed position to rotation.
tm = $.modifiers[uvwmap].Gizmo.transform
tm.rotation = $.rotation * (getModContextTM $ $.modifiers[uvwmap]) * (inverse $.objecttransform)
$.modifiers[uvwmap].Gizmo.transform = tm
Hi,
I think you should better get 3 vertices on each of your rectangular roofs and construct each matrix from scratch.
x cross y is z.
Best regards.
p.s. there is also the FIT option on the modifier
You can still automate it.
Select random face, check if it has 3 or more vertices and if true, pick 3 of them.
delete objects
seed 10
pp = for k=1 to 8 collect
(
plane widthsegs:(random 1 4) lengthsegs:(random 1 4) width:(random 10 100) length:(random 10 100) \
pos:(random -[50,50,50] [50,50,50]) rotation:(angleaxis (random 0 180) (normalize (random -[1,1,1] [1,1,1])))
)
converttomesh pp
p = pp[1]
for k=2 to pp.count do meshop.attach p pp[k]
p.name = #ROOF
p.wirecolor = green
p.backFaceCull = off
/*******************************************************************/
fn get_face_elem_data mesh elem =
(
face = elem[1]
verts = getface mesh face
vv = for k=1 to 3 collect (getvert mesh verts[k])
up = normalize (cross (vv[2] - vv[1]) (vv[3] - vv[1]))
side = normalize (cross (vv[2] - vv[1]) up)
front = cross side up
tm = matrix3 front side up [0,0,0] --vv[1]
pp = for v in meshop.getvertsusingface mesh elem[2] collect (getvert mesh v)
itm = inverse tm
bb = box3()
for p in pp do expandToInclude bb (p * itm)
#(tm, bb)
)
fn align_uvw_gizmo mesh modi elem node: =
(
nodeTM = node.objecttransform
modTM = getModContextTM node modi
data = get_face_elem_data mesh elem
tm = data[1] * (inverse modTM) * (inverse nodeTM) * node.transform
tm = pretranslate tm data[2].center
modi.gizmo.transform = tm
size = (data[2].max - data[2].min)
modi.width = size.x
modi.length = size.y
)
m = copy p.mesh
faces = #{1..m.numfaces}
elems = #()
while not faces.isempty do
(
f = (faces as array)[1]
elem = meshop.getElementsUsingFace m f
faces -= elem
append elems #(f, elem)
)
for elem in elems do
(
uvw = UVWMap name:("F_" + formattedprint elem[1] format:"02d") maptype:0
addmodifier p uvw
)
for k=1 to p.modifiers.count do
(
uvw = p.modifiers[k]
align_uvw_gizmo m uvw elems[k] node:p
)
@har1sf0x @dmitriy.shpilevoy I had a look at your code and I thank you.
This is my code based on a mod of yours
fn getTmFromVerts obj i1 i2 i3 =
(
v1 = meshop.getVert obj.mesh i1
v2 = meshop.getVert obj.mesh i2
v3 = meshop.getVert obj.mesh i3
xAxis = normalize (v2 - v1)
print xAxis
y = normalize (v3 - v1)
print y
zAxis = normalize (cross xAxis y)
print zAxis
yAxis = normalize (cross zAxis xAxis)
matrix3 xAxis yAxis zAxis [0,0,0]
)
addmodifier $ (Uvwmap ())
$.modifiers[1].maptype = 0
$.modifiers[1].length = 12
$.modifiers[1].width = 12
GetVerts = polyop.getFaceVerts $ 1
$.modifiers[1].gizmo.transform = getTmFromVerts $ GetVerts[1] GetVerts[2] GetVerts[3]
based on the attached max file of a slope, I can not just randomly select a face nor random order of vertices of that face. Polyquad 1 and 2 work but not the others
The code works but the result is not the expected one since it is not a plane but a box. You may go through every poly and choose the first one that has a normal looking upwards (dot with z_axis closer to 1.0). Also you might want to make sure that you know the vertex order and select the right ones in order for the normal of the map is ok and it is not flipped (maybe a mesh snapshot could be a better option). And lastly you might need the center of the roof for the position of the gizmo (matrix3 xAxis yAxis zAxis (obj.center*inverse obj.transform)).
Hi @kenc, check that one.
clearListener()
fn createGizmoTm obj =
(
if not (canConvertTo obj mesh) do return undefined
msh = snapshotAsMesh obj
verticesPos = for vIndex = 1 to meshop.getNumVerts msh collect meshop.getVert msh vIndex
axicesArray = for fIndex = 1 to meshop.getNumFaces msh collect
(
f = meshop.getFace msh fIndex
f = #(int f[1], int f[2], int f[3])
xAxis = normalize (verticesPos[f[3]] - verticesPos[f[2]])
yAxis = normalize (verticesPos[f[1]] - verticesPos[f[2]])
zAxis = normalize (cross xAxis yAxis)
yAxis = normalize (cross zAxis xAxis)
#(xAxis, yAxis, zAxis)
)
delete msh
dotProducts = for i = 1 to axicesArray.count collect dot z_axis axicesArray[i][3]
maxValueIndex = 1
maxValue = dotProducts[1]
for i = 2 to dotProducts.count do
(
if dotProducts[i] > maxValue do
(
maxValue = dotProducts[i]
maxValueIndex = i
)
)
axices = axicesArray[maxValueIndex]
matrix3 axices[1] axices[2] axices[3] (obj.center*inverse obj.transform)
)
addmodifier $ (Uvwmap ())
$.modifiers[1].maptype = 0
$.modifiers[1].length = 12
$.modifiers[1].width = 12
$.modifiers[1].gizmo.transform = createGizmoTm $
Enjoy!
Can't find what you're looking for? Ask the community or share your knowledge.