Code archives/3D Graphics - Mesh/SaveB3D

This code has been declared by its author to be Public Domain code.

Download source code

SaveB3D by jfk EO-111102003
EDIT jan.2007: Wow, 3 years ago... I just released a new version (for Blitz3D 1.98) that will try to save any mesh "AS IS". Some tricks had to be used to make it work so it may be not very robust, anyway, you may find it useful:
http://www.melog.ch/dl/saveb3d_2007a.zip
If you don't then you can always use the original, following code that is more robust, athough less flexible.
------------------------------------------
This will save Meshes as .B3D, including Texture Paths. ATM it requires that every Brush is using a Texture and it doesn't support animated Meshes or multiple blended Textures (such as Lightmaps), but blended Textures can be implemented easy (see comments).

You will need the B3Dfile.bb include File from here:
http://www.blitzbasic.com/sdkspecs/sdkspecs/b3dfile_utils.zip , if you don't have it yet, it's about time.

Since this Program is using the new Texturename$ Functions it requires Blitz3D Version 1.85.

you can also use AddMesh() to add multiple Meshes together and then save it...

PRETTY IMPORTANT NOTE: The Brushes and textures (c_brush(n) and c_tex(n)) must be freed after usage because they are not only references, but they have their own media in Memory.
Graphics3D 640,480,32,2
SetBuffer BackBuffer()

meshname$="testsurf.3ds" ; Mesh to save... (one that is using textures)

; BTW: you should run this from inside the folder where the Mesh resides, unless you edit the
; Part labeled by "<<<<<<<<<<<<"

Include "b3dfile.bb"
; this file can be found here: http://www.blitzbasic.com/sdkspecs/sdkspecs/b3dfile_utils.zip
cam=CreateCamera()
TranslateEntity cam,0,0,-10
mesh=LoadMesh(meshname$)
Global c_surfs=CountSurfaces(mesh)

Print "Mesh "+meshname$+" has "+ c_surfs+" Surfaces, using the following textures:"

Dim c_surf(c_surfs)
Dim c_brush(c_surfs)
Dim c_tex(c_surfs)
Dim c_tex_name$(c_surfs)

; track down used textures (thanks Mark!)
For i=1 To c_surfs
 c_surf(i)= GetSurface(mesh,i)
 c_brush(i)=GetSurfaceBrush( c_surf(i) )
 c_tex(i)=GetBrushTexture( c_brush(i) )
 c_tex_name$(i)=Lower$(TextureName$( c_tex(i))) ; Full (!) Texture Path
 curdir$=Lower$(CurrentDir$()) 
 c_tex_name$(i)= Replace$(c_tex_name$(i),curdir$,"") ;<<<<<<<<<<<<<<<<<<<
 Print c_tex_name$(i)
 If c_tex_name$(i)="" Then Print "Error: Surface No."+i+" has no Texture"
 If FileType(c_tex_name$(i))<>1 Then Print "Warning: Surface No."+i+" uses nonexistant Texture ("+c_tex_name$(i)+")."
Next

Print "Press any key to save this Mesh as TEMP.B3D"


WaitKey()

; end

WriteBB3D( "temp.b3d",mesh )

For i=1 To c_surfs
 FreeBrush c_brush(i); release memory
 FreeTexture c_tex(i)
Next


; test if it worked...
FreeEntity mesh
mesh2=LoadMesh("temp.b3d")
While Not KeyDown(1)
 TurnEntity mesh2,1,2,3
 RenderWorld()
 Text 0,0,"TEMP.B3D"
 Flip
Wend
End


Function WriteBB3D( f_name$,mesh )

	file=WriteFile( f_name$ )

	b3dSetFile( file )
	
	b3dBeginChunk( "BB3D" )
		b3dWriteInt( 1 )	;version

		b3dBeginChunk( "TEXS" ) ; list all textures used by the mesh
		For i=1 To c_surfs
			b3dWriteString( c_tex_name$(i) ) 	;texture file
			b3dWriteInt( 1 )					;flags
			b3dWriteInt( 2 )					;blend
			b3dWriteFloat( 0 )					;x in tex 0 (hu?)
			b3dWriteFloat( 0 )					;y in tex 0
			b3dWriteFloat( 1 )					;x scale 1
			b3dWriteFloat( 1 )					;y scale 1
			b3dWriteFloat( 0 )					;rotation 0
			
		Next
		b3dEndChunk()	;end of TEXS chunk

		
		For i=1 To c_surfs
			b3dBeginChunk( "BRUS" ) ; describe all brushes used by the mesh
		
			b3dWriteInt( 1 )					;number of textures per brush ; (eg 2 with lightmap)
			b3dWriteString( "brush"+(i-1) )		;brushname
			b3dWriteFloat( 1 )					;red
			b3dWriteFloat( 1 )					;green
			b3dWriteFloat( 1 )					;blue
			b3dWriteFloat( 1 )					;alpha
			b3dWriteFloat( 0 )					;shininess
			b3dWriteInt( 1 )					;blendmode
			b3dWriteInt( 0 )					;FX
			b3dWriteInt( i-1 )					;used texture index 
;			b3dWriteInt( ? )					;additional texture index (eg lightmap), but here we only use 1 (see above)

			b3dEndChunk()	;end of BRUS chunk
		Next
		
		b3dBeginChunk( "NODE" )
			b3dWriteString( "entity_name_here!" )
			b3dWriteFloat( 0 )	;x_pos
			b3dWriteFloat( 0 )	;y_pos
			b3dWriteFloat( 0 )	;z_pos
			b3dWriteFloat( 1 )	;x_scale
			b3dWriteFloat( 1 )	;y_scale
			b3dWriteFloat( 1 )	;z_scale
			b3dWriteFloat( 1 )	;rot_w
			b3dWriteFloat( 0 )	;rot_x
			b3dWriteFloat( 0 )	;rot_y
			b3dWriteFloat( 0 )	;rot_z
			WriteMESH( mesh )
		b3dEndChunk()	;end of NODE chunk
		
	b3dEndChunk()	;end of BB3D chunk
	
	CloseFile file
End Function

Function WriteMESH( mesh )

	n_surfs=CountSurfaces( mesh )
	
	b3dBeginChunk( "MESH" )
		b3dWriteInt( -1 )				;no 'entity' brush -1
		
		b3dBeginChunk( "VRTS" )
			b3dWriteInt( 0 )			;flags - 0=no normal/color
			b3dWriteInt( 1 )			;number of tex_coord sets (eg: 2 with lightmap)
			b3dWriteInt( 2 )			;coords per set (u,v,w?) 2 with uv, 3 with uvw
			
			For k=1 To n_surfs
				surf=GetSurface( mesh,k )
				n_verts=CountVertices( surf )-1
				
				For j=0 To n_verts
					b3dWriteFloat( VertexX( surf,j ) )
					b3dWriteFloat( VertexY( surf,j ) )
					b3dWriteFloat( VertexZ( surf,j ) )
					b3dWriteFloat( VertexU#( surf,j,0 ) )
					b3dWriteFloat( VertexV#( surf,j,0 ) )
;					b3dWriteFloat( VertexW#( surf,j,0 ) )
;;					b3dWriteFloat( VertexU#( surf,j,1 ) ) ; lightmap uv
;;					b3dWriteFloat( VertexV#( surf,j,1 ) ) ; lightmap uv
;					b3dWriteFloat( VertexW#( surf,j,1 ) )
				Next
			Next
		b3dEndChunk()	;end of VRTS chunk
		
		first_vert=0
		For k=1 To n_surfs
			surf=GetSurface( mesh,k )
			n_tris=CountTriangles( surf )-1
			
			b3dBeginChunk( "TRIS" )
				b3dWriteInt( k-1 )		;brush for these triangles (surf -1 !!!)
				
				For j=0 To n_tris
					b3dWriteInt( first_vert+TriangleVertex( surf,j,0 ) )
					b3dWriteInt( first_vert+TriangleVertex( surf,j,1 ) )
					b3dWriteInt( first_vert+TriangleVertex( surf,j,2 ) )
				Next
				
			b3dEndChunk()	;end of TRIS chunk
			
			first_vert=first_vert+CountVertices( surf )
			
		Next
		
	b3dEndChunk()	;end of MESH chunk
	
End Function


;-------------------------------------------------------------------------------------------------

Comments

CodeOrc2004
This is very cool! I noticed that the file size of the source mesh get reduced by almost 2/3 in most cases.

Great Job JFK!


WendellM2004
Thanks, jfk - that could be quite useful!


puki2004
Nice one "jfk" - I assume you are working on including animated meshes and/or multiple blended Textures?


jfk EO-111102004
uh, animated meshes is beyond my horizon :) . Multiple Textures can be done easily, just read the remarked lines carefully.


Shambler2005
This is great!
I'm using it to shrink the meshes that CartographyShop exports before importing them into Gile[s].
It is converting a file that has dozens of meshes into a single mesh with minimum amount of surfaces.
I also tweaked it a little so that it changes the texture extension from .bmp to .png.

Cheers!


Panno2005
many thx jfk :)


dav3d2006
Really thx jfk, thats wat I searched for so long :D.
As it can export animations it would be so great!


jfk EO-111102006
Andrea used to release an Animation tool with source code, so you may find some useful functions in it:
http://www.blitzbasic.com/Community/posts.php?topic=54978
I hope the source is still part of the distribution. I think it's an installation exe, kind of unhandy, but hey.


Iamhere2006
Not at the moment but soon (I have a timeout in programming at the moment ) , if someone needed urgend then write me an EMAIL I send the source.

And it's only a ZIP-File.

Email to antome@...


Bnesiba2006
for some reason this doesnt work for me... my meshes have no texture...

also, when i download the sourcecode for the demo, and put the include files in it, it cant find the command:
getsurfacebrush() idk what this is, but it's not a function in any of the files in the .zip


Wayne2006
getsurfacebrush() is in the current version of B3D.


Bnesiba2006
NVM i figured it out.


jfk EO-111102006
yes, requires version 1.85 or later. Textures must be applied as brushes (PaintMesh or PaintSurface instead of EntityTexture)


jfk EO-111102007
BTW: For animated meshes you may also check this one out:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1794
Ricky as well as Andrea are such nice persons, gave away their precious sources for free!


jfk EO-111102007
Please note: a new version was released, scroll to the first posting in this thread.


_PJ_2007
So... this incorporates the textures and UV too?

SWEET!


jfk EO-111102007
This function is trying to save EVERYTHING. period. (vertex alpha, normals , uVs, color, multiple textures, UV/sets...) DDS textures, as well as "special stuff" like cubemaps etc, are not supported.

Pleas note there's a bug: in the part that writes the BRUS chunk, a temporary helper brush named "lo_bru" is created in a loop. This brush needs to be freed at the end of the said loop to prevent a memory leak.


Code Archives Forum