Notifications
Clear all

[Closed] Work With Uvw Mapping

hi all, in maxscript ‘s help i don’t understand very well now max work with TVerts Array…
In this code i create two metod, the first is simple and it’s wrong, the second export correctly the mapping but NOT the normals… someone can tell me now create a very quickly function to export the Vertex, Faces and UVW arrays ???


 (
 
 
 fn	metodo1 obj=
 (
 	for f=1 to obj.numFaces do append FacesArray (getFace obj f)
 	for v=1 to obj.numVerts do append VertexArray (getVert obj v)
 	for t=1 to obj.numVerts do append UVArray (getTvert obj t)
 	UVArray.count
 	VertexArray.count
 	obj = mesh faces:FacesArray vertices:VertexArray tverts:UVArray
 	buildTVFaces obj
 	for j = 1 to obj.numfaces do (setTVFace obj j (getFace obj j))
 	update obj
 	obj.material = meditmaterials[1]
 	obj.pos+=[40,0,0]
 	obj.name= "algo1_" + obj.name
 )
 fn	metodo2 obj=
 (
 	FacesArray = #()
 	UVArray = #()
 	VertexArray=#()
 	FacesArray[obj.numFaces]=undefined
 	UVArray[obj.numVerts] = undefined
 	VertexArray[obj.numVerts] = undefined
 	for i=1 to obj.numFaces do FacesArray[i] = (getFace obj i)
 	for i=1 to obj.numVerts do
 	(
 		VertexArray[i] = (getVert obj i)
 		facearr = (meshop.getFacesUsingVert obj i) as array
 		face			  = getFace obj facearr[1]
 		tface			 = getTVFace obj facearr[1]
 		--format "vert:% > facearr:% > face:% > tface:%
" i facearr face tface
 		idx = case i of
 		(
 			(face.x): tface.x
 			(face.y): tface.y
 			(face.z): tface.z
 			default: (messageBox ("error in get uvw algorithm for obj: " + obj.name) ; error.e)
 		)
 		UVArray[i]=(getTVert obj idx)
 	)
 	obj = mesh faces:FacesArray vertices:VertexArray tverts:UVArray
 	buildTVFaces obj
 	for j = 1 to obj.numfaces do (setTVFace obj j (getFace obj j))
 	update obj
 	obj.pivot=obj.center
 	obj.material = meditmaterials[1]
 	obj.pos+=[20,0,0]
 	obj.name= "algo2_" + obj.name
 )
 clearListener()
 st = timeStamp()
 for obj in  selection do metodo1 obj
 print ("calculated 1 in ms: " + (timestamp()-st) as string)
 st = timeStamp()
 for obj in  selection do metodo2 obj
 "calculated 2 in ms: " + (timestamp()-st) as string
 )
9 Replies

example try this script:

(
 
 fn	metodo1 obj=
 (
 	FacesArray = #()
 	UVArray = #()
 	VertexArray=#()
 	FacesArray[obj.numFaces]=undefined
 	UVArray[obj.numVerts] = undefined
 	VertexArray[obj.numVerts] = undefined
 	for f=1 to obj.numFaces do
 	(
 		face = getFace obj f
 		tface = getTVFace obj f
 		
 		FacesArray[f] = face--[face.z,face.y,face.x]
 		
 		VertexArray[face.x] = getVert obj face.x
 		VertexArray[face.y] = getVert obj face.y
 		VertexArray[face.z] = getVert obj face.z
 		
 		UVArray[face.x] = getTVert obj tface.x
 		UVArray[face.y] = getTVert obj tface.y
 		UVArray[face.z] = getTVert obj tface.z
 		
 	)
 	--for i=1 to obj.numFaces do format "%	%
" VertexArray[i] UVArray[i]
 	UVArray.count
 	VertexArray.count
 	obj = mesh faces:FacesArray vertices:VertexArray tverts:UVArray
 	buildTVFaces obj
 	for j = 1 to obj.numfaces do (setTVFace obj j (getFace obj j))
 	update obj
 	obj.material = meditmaterials[1]
 	obj.pos+=[40,0,0]
 	obj.name= "algo1_" + obj.name
 )
 fn	metodo2 obj=
 (
 	FacesArray = #()
 	UVArray = #()
 	VertexArray=#()
 	FacesArray[obj.numFaces]=undefined
 	UVArray[obj.numVerts] = undefined
 	VertexArray[obj.numVerts] = undefined
 	for i=1 to obj.numFaces do
 	(
 		FacesArray[i] = (getFace obj i)
 	)
 	for i=1 to obj.numVerts do
 	(
 		VertexArray[i] = (getVert obj i)
 		facearr = (meshop.getFacesUsingVert obj i) as array
 		face			  = getFace obj facearr[1]
 		tface			 = getTVFace obj facearr[1]
 		--format "vert:% > facearr:% > face:% > tface:%
" i facearr face tface
 		idx = case i of
 		(
 			(face.x): tface.x
 			(face.y): tface.y
 			(face.z): tface.z
 			default: (messageBox ("error in get uvw algorithm for obj: " + obj.name) ; error.e)
 		)
 		UVArray[i]=(getTVert obj idx)
 	)
 	obj = mesh faces:FacesArray vertices:VertexArray tverts:UVArray
 	buildTVFaces obj
 	for j = 1 to obj.numfaces do (setTVFace obj j (getFace obj j))
 	update obj
 	obj.pivot=obj.center
 	obj.material = meditmaterials[1]
 	obj.pos+=[20,0,0]
 	obj.name= "algo2_" + obj.name
 )
 clearListener()
 st = timeStamp()
 for obj in  selection do metodo1 obj
 print ("calculated 1 in ms: " + (timestamp()-st) as string)
 st = timeStamp()
 for obj in  selection do metodo2 obj
 "calculated 2 in ms: " + (timestamp()-st) as string
 )

and try this file, there are two objects with wrong orientation:
http://www.treddi.com/forum/index.php?app=core&module=attach&section=attach&attach_id=57811

here is my method:


 mapped fn denisT_method node rebuild:on shift:[0,0,0] = if iskindof node GeometryClass do
(
	local _mesh = copy node.mesh
	
	local faceIDs = #()
	local faceSGs = #()
	local tvfaces = #()
	local faces = for f=1 to _mesh.numfaces collect 
	(
		append faceIDs (getFaceMatID _mesh f)
		append faceSGs (getFaceSmoothGroup _mesh f)
		append tvfaces (getTVFace _mesh f)
		getFace _mesh f
	)
	local verts = for v=1 to _mesh.numverts collect (getVert _mesh v)
	local tverts = for v=1 to _mesh.numtverts collect getTVert _mesh v
		
	if rebuild do
	(
		new = mesh vertices:verts faces:faces materialIDs:faceIDs tverts:tverts name:(node.name + "_copy")
		buildTVFaces new off
		update new

		for f=1 to new.numfaces do
		(
			setFaceSmoothGroup new f faceSGs[f]
			setTVFace new f tvfaces[f]
		)

		new.transform = node.objecttransform
		new.center = node.center
		centerpivot new
		new.pos += shift
		new.material = meditmaterials[1]
		ok
	)
)

(
	gc light:on
	t = timeStamp()
	m = heapfree
	denisT_method $ shift:[-20,0,0]
	format "DENIST -> time:% leak:%
" (timeStamp() - t) (m - heapfree)
)
 

it must be correct.

Both your methods don’t work if the number of node’s geo verts is different then the number of map verts. Also you have to store face material ids and smoothing groups (that’s only way to rebuild the new mesh normals).

Thanks but you don’t understand that i must to do:

I’m creating a export-import script for a PCgame objects, the game want:

  1. a list of Faces
  2. a list of Vertices
  3. a list of UVWcoordinates
    all other informations aren’t utilized (example in the game there are only one smoothing group)
    but the problem is: the list of vertices and list of uvw are linked , so vertex[n] <=> uvw[n]

In max script but the Tverts and Verts are different because you can have two UVW for one vertex…
The second metod in the only one solution, but i not resolve for normals issue, in fact the only metod is export the scene in the Game’s mesh, import with script, correct with “flip” the wrong normals’s faces, re-export the scene.
Do you understand now ? (thanks for answer )

It's probably [b]you[/b] don't understand. I do exactly same as in your methods but correct and two times faster. It doesn't matter how many [b]geo[/b] and [b]map [/b]vertices the mesh has. The function has to work  and not crash if the numbers are different.

You always talked about the normals (!). The normals do nothing to have your methods not working. You are using wrong vertex order for Map faces. The vertex order of a map face might not be the same as the order of the corresponded geo map.

No, i’m understand that do you do, but is not my objective, the objective of script is to EXTRACT only Face, Vertex and UVW arrays, it isn’t rebuild a objects so this code should not exist because I have to extract only those three Arrey !!!


 for f=1 to new.numfaces do
  (
    setFaceSmoothGroup new f faceSGs[f]
    setTVFace new f tvfaces[f]
  )

The game data are composed of a list of faces, Vertex and ONLY uvw coordinates, there aren’t Tfaces arrey.

I make new mesh with mesh() function only to test if the tree information are correct.

sorry, my english is bad…

my goal is to match the Vertex list with the Texture list so an arrey of Vertex.
The game utilize these data:
FACES

 numTri = [b]23[/b]
    47	 30	 29
    29	 48	 47
    27	 28	 26
    26	 25	 27
    36	 19	 46
    45	 44	 43
    41	 24	 23
    23	 42	 41
    37	 40	 39
    39	 38	 37
 ecc.....

VERTEX

numVerts = [b]368 [/b]  
  -16.0001221	  3.9999993	 -3.9999456
  -16.0001221	  5.0003319	 -3.9999456
  -16.0000496	  5.0003319	  0.0000364
  -16.5205078	  5.0003300	  0.0000364
  -16.5001221	  5.0003319	 -3.9999454
  -16.5205116	  5.5003295	  0.0000363
  -16.5001202	  5.5003314	 -3.9999456
  -16.0000229	  3.9999995	  0.0000365
  -12.0001097	  7.9999981	 -3.9999468
  -12.0000706	  6.8734770	  0.0000215
  -12.0000257	  4.0000005	  4.0000644
  -12.0000257	  5.0003328	  4.0000639
  -16.0000210	  5.0003324	  4.0000639
  -16.5409431	  5.0003290	  4.5000582
  -12.0000257	  5.0003333	  4.5000648
  -16.5409431	  5.5003285	  4.5000582
  -12.0000257	  5.5003328	  4.5000648
  -15.9999971	  4.0000000	  4.0001101
  -16.0000534	  5.0003304	 -7.9999280
 	ecc.....

UVW (not converted)

numUvw = [b]368 [/b]
  255  183  255  175
  255  191  255  175
  255  183  255  183
  255  191  255  183
  255  183  255  175
  255  183  255  183
  255  191  255  175
  255  191  255  183
  255  159  255  151
  255  167  255  151
  255  159  255  159
  255  175  255  151
  255  175  255  159
  249  167  255  152
 ecc...

So example the Vertex[5] have uvw coordinates UVW[5]

Thera aren’t Tface, smoothing, normals ecc… only these information

sorry, my english is bad…
my goal is to match the Vertex list with the Texture list so an arrey of Vertex.
The game utilize these data:
FACES

 numTri = [b]23[/b]
      47	 30	 29
      29	 48	 47
      27	 28	 26
      26	 25	 27
      36	 19	 46
      45	 44	 43
      41	 24	 23
      23	 42	 41
      37	 40	 39
      39	 38	 37
   ecc.....

VERTEX

numVerts = [b]368 [/b]  
    -16.0001221	  3.9999993	 -3.9999456
    -16.0001221	  5.0003319	 -3.9999456
    -16.0000496	  5.0003319	  0.0000364
    -16.5205078	  5.0003300	  0.0000364
    -16.5001221	  5.0003319	 -3.9999454
    -16.5205116	  5.5003295	  0.0000363
    -16.5001202	  5.5003314	 -3.9999456
    -16.0000229	  3.9999995	  0.0000365
    -12.0001097	  7.9999981	 -3.9999468
    -12.0000706	  6.8734770	  0.0000215
    -12.0000257	  4.0000005	  4.0000644
    -12.0000257	  5.0003328	  4.0000639
    -16.0000210	  5.0003324	  4.0000639
    -16.5409431	  5.0003290	  4.5000582
    -12.0000257	  5.0003333	  4.5000648
    -16.5409431	  5.5003285	  4.5000582
    -12.0000257	  5.5003328	  4.5000648
    -15.9999971	  4.0000000	  4.0001101
    -16.0000534	  5.0003304	 -7.9999280
   	ecc.....

UVW (not converted)

numUvw = [b]368 [/b]
    255  183  255  175
    255  191  255  175
    255  183  255  183
    255  191  255  183
    255  183  255  175
    255  183  255  183
    255  191  255  175
    255  191  255  183
    255  159  255  151
    255  167  255  151
    255  159  255  159
    255  175  255  151
    255  175  255  159
    249  167  255  152
   ecc...

So example the Vertex[5] have uvw coordinates UVW[5]
Thera aren’t Tface, smoothing, normals ecc… only these information, this is the reson of my script, i must re ordinate the Tverts so that they align with the vertices

follow you rules there are some meshes those can not be exported:
1. if the number of geo verts is not the same as the number of map verts
2. if any geo vert has more then 1 corresponded map verts

As I said the map face can be originally created on different then the geo face vertices (indexes might be different).
So, we have to collect map verts coordinates in order of geo verts.

see the code and my comments:


   mapped fn denisT_method node rebuild:on shift:[0,0,0] = if iskindof node GeometryClass do
   (
   	local _mesh = copy node.mesh
   	if _mesh.numverts == _mesh.numtverts then -- check that number of geo verts and map verts the same
   	(
   		local faceIDs = #()
   			faceIDs.count = _mesh.numfaces
   		local tvverts = #()
   			tvverts.count = _mesh.numtverts
   		
   		local one_to_one = on
   		local faces = for f=1 to _mesh.numfaces while one_to_one collect 
   		(
   			faceIDs[f] = getFaceMatID _mesh f
   			tv = getTVFace _mesh f
   			vv = getFace _mesh f
   			for k=1 to 3 while one_to_one do 
   			(
   				v = tv[k]
   				if tvverts[v] == undefined then tvverts[v] = vv[k]
   				else one_to_one = (tvverts[v] == vv[k]) -- check that only one map vert corresponds to the geo vert
   			)
   			vv
   		)
   		
   		if one_to_one then
   		(
   			local verts = for v=1 to _mesh.numverts collect (getVert _mesh v)
   			
   			local tverts = #()
   				tverts.count = _mesh.numtverts
   			
   			for v=1 to _mesh.numtverts do -- re-collect map verts in order of geo verts
   			(
   				tverts[tvverts[v]] = getTVert _mesh v
   			)
   			
   			if rebuild do
   			(
   				new = mesh vertices:verts faces:faces materialIDs:faceIDs tverts:tverts name:(node.name + "_copy")
   				buildTVFaces new off
   				update new
   
   				for f=1 to new.numfaces do setTVFace new f faces[f] -- use geo verts order to make map face
   
   				new.transform = node.objecttransform
   				new.center = node.center
   				centerpivot new
   				new.pos += shift
   				new.material = meditmaterials[1]
   				ok
   			)
   		)
   		else format "Warning:
	node:%
		one_to_one:%
" node.name one_to_one
   	)
   	else format "Warning:
	node:%
		verts:% tverts:%
" node.name _mesh.numverts _mesh.numtverts
   )
   
   (
   	gc light:on
   	t = timeStamp()
   	m = heapfree
   	denisT_method $ shift:[-20,0,0]
   	format "DENIST -> time:% leak:%
" (timeStamp() - t) (m - heapfree)
   )