Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Aligning Planar Mapping to Roof Slopes

12 REPLIES 12
Reply
Message 1 of 13
kenc
590 Views, 12 Replies

Aligning Planar Mapping to Roof Slopes

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.

kenc_0-1723206381362.png

 

TIA

12 REPLIES 12
Message 2 of 13
denisT.MaxDoctor
in reply to: kenc

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?

Message 3 of 13
kenc
in reply to: denisT.MaxDoctor

@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.

Message 4 of 13
kenc
in reply to: kenc

@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

Message 5 of 13
har1sf0x
in reply to: kenc

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.

har1sf0x_0-1723487903700.png

p.s. there is also the FIT option on the modifier

 

Message 6 of 13
kenc
in reply to: har1sf0x

@har1sf0x unfortunately there can not be any manual work, it must be automatic by script.

Message 7 of 13
dmitriy.shpilevoy
in reply to: kenc

You can still automate it.

Select random face, check if it has 3 or more vertices and if true, pick 3 of them.

Message 8 of 13
denisT.MaxDoctor
in reply to: kenc

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 
)
Message 9 of 13
kenc
in reply to: kenc

@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

Message 10 of 13
dmitriy.shpilevoy
in reply to: kenc

Looks like you have hardcoded 1 here, try i
GetVerts = polyop.getFaceVerts $ 1
Message 11 of 13
har1sf0x
in reply to: kenc

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)).

Message 12 of 13
har1sf0x
in reply to: kenc

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!

Message 13 of 13
har1sf0x
in reply to: denisT.MaxDoctor

Respect! Always learning something new from guys like you!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report