Notifications
Clear all

[Closed] Export UV Data

 MZ1

How we can export UV data of a mesh to a text file (and import it back)?

5 Replies

You do it the same way you do for a mesh but using Mapping Methods.

1 Reply
 MZ1
(@mz1)
Joined: 1 year ago

Posts: 0

Actualy I’m looking for an example

Here is a simple example. It does not actually save the data to a file or stream but to variables, but the process is the same.

(
	local faces, verts, tfaces, tverts
	
	fn SaveGeometry node = with undo off
	(
		tmesh  = snapshotasmesh node
		faces  = for f = 1 to tmesh.numfaces  collect getface tmesh f
		verts  = for v = 1 to tmesh.numverts  collect getvert tmesh v
		tfaces = for f = 1 to tmesh.numfaces  collect gettvface tmesh f
		tverts = for v = 1 to tmesh.numtverts collect gettvert tmesh v
	)
	
	fn BuildGeometry = with undo off
	(
		tmesh = mesh vertices:verts faces:faces tverts:tverts
		buildtvfaces tmesh false
		for f = 1 to faces.count do settvface tmesh f tfaces[f]
		update tmesh
		return tmesh
	)

	-- TEST ----------------------------------------------------------
	gc()
	delete objects
	node = teapot mapcoords:on
		
	-- Save the object
	SaveGeometry node
	
	-- Build a copy of the object
	copy = BuildGeometry()

	#(node, copy).mat = standard diffusemap:(checker()) showInViewport:on
	------------------------------------------------------------------
)

I haven’t searched the forum, but I believe there are fully featured exporters here and in some other websites too, but if they have too many features, it is easy to get lost in the code, so I’ve coded a very simple Exporter/Importer for you.

It is by no means an optimized or fully featured exporter. It simply exports 1 selected object and hopefully will import it correctly.

Not implemented:
Multiple UV channels
Multiple Objects
Vertex Colors
Etc., etc., etc…

The exported file is a simple text file, similar to an .OBJ file (but much simpler), so you can open it up in a text editor and see how the data is stored.

I hope you find it useful.

(
 	
 	try (destroydialog ::RO_BASIC_EXPORTER) catch()
 	
 	rollout RO_BASIC_EXPORTER "Basic Mesh Exporter" width:164 height:88
 	(
 		button bt_export "Export" pos:[8,8] width:148 height:32
 		button bt_import "Import" pos:[8,48] width:148 height:32
 		
 		fn SaveMesh node filename = with undo off
 		(
 			tmesh = snapshotasmesh node
 			stream = openFile filename mode:"w"
 
 			-- Save Mesh Faces, Mat IDs, Smoothing Groups, Edge Visibility
 			--	faceverts  matID  sGroup  edgesVis
 			-- F  [7,23,16]	1	  1	  1 1 0
 			
 			for f = 1 to tmesh.numfaces do
 			(
 				face = getface tmesh f
 				matID = getfacematid tmesh f
 				sGroup = getfacesmoothgroup tmesh f
 				
 				format "F % % %" face matID sGroup to:stream
 				
 				for e = 1 to 3 do
 				(
 					case (getedgevis tmesh f e) of
 					(
 						 true: format " 1" to:stream
 						false: format " 0" to:stream
 					)
 				)
 				
 				format "
" to:stream
 			)
 			format "
" to:stream
 				
 			-- Save Mesh Vertices
 			for v = 1 to tmesh.numverts do
 			(
 				vert = getvert tmesh v
 				format "V %
" vert to:stream
 			)
 			format "
" to:stream
 			
 			-- Save Texture Faces (Channel 1 only)
 			for f = 1 to tmesh.numfaces do
 			(
 				tface = gettvface tmesh f
 				format "TF %
" tface to:stream
 			)
 			format "
" to:stream
 
 			-- Save Texture Vertices (Channel 1 only)
 			for v = 1 to tmesh.numtverts do
 			(
 				tvert = gettvert tmesh v
 				format "TV %
" tvert to:stream
 			)
 			
 			flush stream
 			close stream
 		)
 
 		fn LoadMesh filename = with undo off
 		(
 			local faces   = #()
 			local verts   = #()
 			local edgeVis = #()
 			local matIDs  = #()
 			local sGroups = #()
 			local tfaces  = #()
 			local tverts  = #()
 
 			stream = openFile filename mode:"r"
 			
 			while not eof stream do
 			(
 				l = readLine stream
 				filtered = filterString l "[], "
 				
 				case filtered[1] of
 				(
 					-- Mesh Faces
 					"F":
 					(
 						f1 = filtered[2] as integer
 						f2 = filtered[3] as integer
 						f3 = filtered[4] as integer
 						
 						matID  = filtered[5] as integer
 						sGroup = filtered[6] as integer
 						
 						e1 = filtered[7] as integer
 						e2 = filtered[8] as integer
 						e3 = filtered[9] as integer
 						
 						append faces [f1,f2,f3]
 						append matIDs matID
 						append sGroups sGroup
 						
 						append edgeVis #(e1==1, e2==1, e3==1)
 					)
 					-- Mesh Verts
 					"V":
 					(
 						vx = filtered[2] as float
 						vy = filtered[3] as float
 						vz = filtered[4] as float
 						
 						append verts [vx,vy,vz]
 					)
 					-- Texture Faces
 					"TF":
 					(
 						f1 = filtered[2] as integer
 						f2 = filtered[3] as integer
 						f3 = filtered[4] as integer
 						
 						append tfaces [f1,f2,f3]
 					)
 					-- Texture Vertices
 					"TV":
 					(
 						vx = filtered[2] as float
 						vy = filtered[3] as float
 						vz = filtered[4] as float
 						
 						append tverts [vx,vy,vz]
 					)
 				)
 			)
 			
 			tmesh = mesh vertices:verts faces:faces materialIDs:matIDs tverts:tverts
 			buildtvfaces tmesh false
 
 			for f = 1 to sGroups.count do setfacesmoothgroup tmesh f sGroups[f]
 			for f = 1 to faces.count do settvface tmesh f tfaces[f]
 			
 			for f = 1 to edgeVis.count do
 			(
 				for j = 1 to 3 do setedgevis tmesh f j edgeVis[f][j]
 			)
 			
 			update tmesh
 			
 			flush stream
 			close stream
 		)
 		
 		on bt_export pressed do
 		(
 			if selection.count != 1 do return messagebox "Select one object"
 			if not canconvertto selection[1] editable_mesh do return messagebox "Invalid selection"
 				
 			filename = getSaveFileName types:"Mesh(*.pt3d)|*.pt3d"
 			if filename != undefined do
 			(
 				setwaitcursor()
 				
 				gc()
 				st = timestamp(); sh = heapfree
 				SaveMesh selection[1] filename
 				format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
 				
 				messagebox "Done!"
 				setarrowcursor()
 			)
 		)
 
 		on bt_import pressed do
 		(
 			filename = getOpenFileName types:"Mesh(*.pt3d)|*.pt3d"
 			if filename != undefined do
 			(
 				setwaitcursor()
 				
 				gc()
 				st = timestamp(); sh = heapfree
 				LoadMesh filename
 				format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
 				
 				completeredraw()
 				messagebox "Done!"
 				setarrowcursor()
 			)
 		)
 		
 	)
 	
 	createdialog RO_BASIC_EXPORTER
 	
 )
 MZ1

Thank you! I will check it out.