pviktori / rpms / blender

Forked from rpms/blender 5 years ago
Clone
cvsextras 281bfc3
#!BPY
cvsextras 281bfc3

cvsextras 281bfc3
"""
cvsextras 281bfc3
Name: '3D Studio'
cvsextras 281bfc3
Blender: 233
cvsextras 281bfc3
Group: 'Export'
cvsextras 281bfc3
Tip: 'Export to 3DS file format. (.3ds)'
cvsextras 281bfc3
"""
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
######################################################
cvsextras 281bfc3
# 3ds Importer
cvsextras 281bfc3
# By:  Bob Holcomb and Richard Lärkäng
cvsextras 281bfc3
# Date: 22 APR 04
cvsextras 281bfc3
# Ver: 0.7
cvsextras 281bfc3
######################################################
cvsextras 281bfc3
# This script imports a 3ds file and the materials
cvsextras 281bfc3
#  into blender for editing.  Hopefully
cvsextras 281bfc3
# this will make it into a future version as an import
cvsextras 281bfc3
# feature of the menu.  Loader is based on 3ds loader
cvsextras 281bfc3
# from www.gametutorials.com(Thanks DigiBen).
cvsextras 281bfc3
######################################################
cvsextras 281bfc3

cvsextras 281bfc3
######################################################
cvsextras 281bfc3
# Importing modules
cvsextras 281bfc3
######################################################
cvsextras 281bfc3

cvsextras 281bfc3
import Blender
cvsextras 281bfc3
from Blender import NMesh, Scene, Object, Material
cvsextras 281bfc3
from Blender.BGL import *
cvsextras 281bfc3
from Blender.Draw import *
cvsextras 281bfc3
from Blender.Window import *
cvsextras 281bfc3
from Blender.Image import *
cvsextras 281bfc3
from Blender.Material import *
cvsextras 281bfc3

cvsextras 281bfc3
import sys, struct, string, types, math
cvsextras 281bfc3
from types import *
cvsextras 281bfc3

cvsextras 281bfc3
import os
cvsextras 281bfc3
from os import path
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
######################################################
cvsextras 281bfc3
# Data Structures
cvsextras 281bfc3
######################################################
cvsextras 281bfc3

cvsextras 281bfc3
#Some of the chunks that we will see
cvsextras 281bfc3
#----- Primary Chunk, at the beginning of each file
cvsextras 281bfc3
PRIMARY=19789 				#0x4D4D
cvsextras 281bfc3

cvsextras 281bfc3
#------ Main Chunks
cvsextras 281bfc3
OBJECTINFO=15677				#0x3D3D			// This gives the version of the mesh and is found right before the material and object information
cvsextras 281bfc3
VERSION=2					#0x0002			// This gives the version of the .3ds file
cvsextras 281bfc3
EDITKEYFRAME=45056			#0xB000			// This is the header for all of the key frame info
cvsextras 281bfc3

cvsextras 281bfc3
#------ sub defines of OBJECTINFO
cvsextras 281bfc3
MATERIAL=45055				#0xAFFF			// This stored the texture info
cvsextras 281bfc3
OBJECT=16384					#0x4000			// This stores the faces, vertices, etc...
cvsextras 281bfc3

cvsextras 281bfc3
#------ sub defines of MATERIAL
cvsextras 281bfc3
MATNAME=40960				#0xA000			// This holds the material name
cvsextras 281bfc3
MATAMBIENT=40976			#0xA010
cvsextras 281bfc3
MATDIFFUSE=40992				#0xA020			// This holds the color of the object/material
cvsextras 281bfc3
MATSPECULAR=41008			#0xA030
cvsextras 281bfc3
MATMAP=41472				#0xA200			// This is a header for a new material
cvsextras 281bfc3
MATMAPFILE=41728				#0xA300			// This holds the file name of the texture
cvsextras 281bfc3

cvsextras 281bfc3
RGB1=17					#0x0011
cvsextras 281bfc3
RGB2=18					#0x0012
cvsextras 281bfc3

cvsextras 281bfc3
OBJECT_MESH=16640			#0x4100			// This lets us know that we are reading a new object
cvsextras 281bfc3

cvsextras 281bfc3
#------ sub defines of OBJECT_MESH
cvsextras 281bfc3
OBJECT_VERTICES=16656			#0x4110			// The objects vertices
cvsextras 281bfc3
OBJECT_FACES=16672			#0x4120			// The objects faces
cvsextras 281bfc3
OBJECT_MATERIAL=16688		#0x4130			// This is found if the object has a material, either texture map or color
cvsextras 281bfc3
OBJECT_UV=16704				#0x4140			// The UV texture coordinates
cvsextras 281bfc3
OBJECT_TRANS_MATRIX=16736	#0x4160			// The translation matrix of the object 54 bytes
cvsextras 281bfc3

cvsextras 281bfc3
def point_by_matrix(p, m):
cvsextras 281bfc3
  return [p[0] * m[0][0] + p[1] * m[1][0] + p[2] * m[2][0] + m[3][0],
cvsextras 281bfc3
          p[0] * m[0][1] + p[1] * m[1][1] + p[2] * m[2][1] + m[3][1],
cvsextras 281bfc3
          p[0] * m[0][2] + p[1] * m[1][2] + p[2] * m[2][2] + m[3][2]]
cvsextras 281bfc3

cvsextras 281bfc3
#the chunk class
cvsextras 281bfc3
class chunk:
cvsextras 281bfc3
	ID=0
cvsextras 281bfc3
	size=0
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=0
cvsextras 281bfc3
		self.size=0
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		self.size=6
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		#calculate size
cvsextras 281bfc3
		temp_data=[0]*2
cvsextras 281bfc3
		temp_data[0]=self.ID
cvsextras 281bfc3
		temp_data[1]=self.size
cvsextras 281bfc3
		#write header
cvsextras 281bfc3
		data=struct.pack(binary_format,temp_data[0],temp_data[1])
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3
	def dump(self):
cvsextras 281bfc3
		print "ID: ", self.ID
cvsextras 281bfc3
		print "ID in hex: ", hex(self.ID)
cvsextras 281bfc3
		print "size: ", self.size
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
#may want to add light, camera, keyframe chunks.
cvsextras 281bfc3
class vert_chunk(chunk):
cvsextras 281bfc3
	verts=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.verts=[]
cvsextras 281bfc3
		self.ID=OBJECT_VERTICES
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=2 #for the number of verts short
cvsextras 281bfc3
		for vert in self.verts:
cvsextras 281bfc3
			temp_size+=12  #3 floats x 4 bytes each
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "vert_chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		temp_data=[0]
cvsextras 281bfc3
		temp_data[0]=len(self.verts)
cvsextras 281bfc3
		#write header
cvsextras 281bfc3
		data=struct.pack(binary_format,temp_data[0])
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3
		#write verts
cvsextras 281bfc3
		for vert in self.verts:
cvsextras 281bfc3
			binary_format="<3f"
cvsextras 281bfc3
			temp_data=[0.0]*3
cvsextras 281bfc3
			temp_data[0]=vert[0]
cvsextras 281bfc3
			temp_data[1]=vert[1]
cvsextras 281bfc3
			temp_data[2]=vert[2]
cvsextras 281bfc3
			data=struct.pack(binary_format,temp_data[0],temp_data[1], temp_data[2])
cvsextras 281bfc3
			file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3
class obj_material_chunk(chunk):
cvsextras 281bfc3
	name=""
cvsextras 281bfc3
	faces=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.name=""
cvsextras 281bfc3
		self.faces=[]
cvsextras 281bfc3
		self.ID=OBJECT_MATERIAL
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=(len(self.name)+1)
cvsextras 281bfc3
		temp_size+=2
cvsextras 281bfc3
		for face in self.faces:
cvsextras 281bfc3
			temp_size+=2
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "obj material chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write name
cvsextras 281bfc3
		name_length=len(self.name)+1
cvsextras 281bfc3
		binary_format="<"+str(name_length)+"s"
cvsextras 281bfc3
		data=struct.pack(binary_format, self.name)
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		print "Nr of faces: ", len(self.faces)
cvsextras 281bfc3
		data=struct.pack(binary_format, len(self.faces))
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3
		for face in self.faces:
cvsextras 281bfc3
			data=struct.pack(binary_format, face)
cvsextras 281bfc3
			file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3
class face_chunk(chunk):
cvsextras 281bfc3
	faces=[]
cvsextras 281bfc3
	num_faces=0
cvsextras 281bfc3
	m_chunks=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.faces=[]
cvsextras 281bfc3
		self.ID=OBJECT_FACES
cvsextras 281bfc3
		self.num_faces=0
cvsextras 281bfc3
		self.m_chunks=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=2 #num faces info
cvsextras 281bfc3
		for face in self.faces:
cvsextras 281bfc3
			temp_size+=8  #4 short ints x 2 bytes each
cvsextras 281bfc3
		for m in self.m_chunks:
cvsextras 281bfc3
			temp_size+=m.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "face_chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		temp_data=[0]
cvsextras 281bfc3
		temp_data[0]=len(self.faces)
cvsextras 281bfc3
		data=struct.pack(binary_format,temp_data[0])
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3
		#write faces
cvsextras 281bfc3
		for face in self.faces:
cvsextras 281bfc3
			binary_format="<4H"
cvsextras 281bfc3
			temp_data=[0]*4
cvsextras 281bfc3
			temp_data[0]=face[0]
cvsextras 281bfc3
			temp_data[1]=face[1]
cvsextras 281bfc3
			temp_data[2]=face[2]
cvsextras 281bfc3
			temp_data[3]=0 #only used by 3d studio
cvsextras 281bfc3
			data=struct.pack(binary_format,temp_data[0],temp_data[1], temp_data[2], temp_data[3])
cvsextras 281bfc3
			file.write(data)
cvsextras 281bfc3
		#write materials
cvsextras 281bfc3
		for m in self.m_chunks:
cvsextras 281bfc3
			m.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class uv_chunk(chunk):
cvsextras 281bfc3
	uv=[]
cvsextras 281bfc3
	num_uv=0
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.uv=[]
cvsextras 281bfc3
		self.ID=OBJECT_UV
cvsextras 281bfc3
		self.num_uv=0
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=2 #for num UV
cvsextras 281bfc3
		for this_uv in self.uv:
cvsextras 281bfc3
			temp_size+=8  #2 floats at 4 bytes each
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "uv chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		temp_data=[0]
cvsextras 281bfc3
		temp_data[0]=len(self.uv)
cvsextras 281bfc3
		#write header
cvsextras 281bfc3
		data=struct.pack(binary_format,temp_data[0])
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3
		#write verts
cvsextras 281bfc3
		for this_uv in self.uv:
cvsextras 281bfc3
			binary_format="<2f"
cvsextras 281bfc3
			temp_data=[0.0]*2
cvsextras 281bfc3
			temp_data[0]=this_uv[0]
cvsextras 281bfc3
			temp_data[1]=this_uv[1]
cvsextras 281bfc3
			data=struct.pack(binary_format,temp_data[0],temp_data[1])
cvsextras 281bfc3
			file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3
class mesh_chunk(chunk):
cvsextras 281bfc3
	v_chunk=vert_chunk()
cvsextras 281bfc3
	f_chunk=face_chunk()
cvsextras 281bfc3
	uv_chunk=uv_chunk()
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.v_chunk=vert_chunk()
cvsextras 281bfc3
		self.f_chunk=face_chunk()
cvsextras 281bfc3
		self.uv_chunk=uv_chunk()
cvsextras 281bfc3
		self.ID=OBJECT_MESH
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=self.v_chunk.get_size()
cvsextras 281bfc3
		temp_size+=self.f_chunk.get_size()
cvsextras 281bfc3
		temp_size+=self.uv_chunk.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "object mesh chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write stuff
cvsextras 281bfc3
		self.v_chunk.write(file)
cvsextras 281bfc3
		self.f_chunk.write(file)
cvsextras 281bfc3
		self.uv_chunk.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class object_chunk(chunk):
cvsextras 281bfc3
	name=""
cvsextras 281bfc3
	mesh_chunks=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.name=""
cvsextras 281bfc3
		self.mesh_chunks=[]
cvsextras 281bfc3
		self.ID=OBJECT
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=len(self.name)+1 #+1 for null character
cvsextras 281bfc3
		for mesh in self.mesh_chunks:
cvsextras 281bfc3
			temp_size+=mesh.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "object chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write name
cvsextras 281bfc3
		name_length=len(self.name)+1
cvsextras 281bfc3
		binary_format="<"+str(name_length)+"s"
cvsextras 281bfc3
		data=struct.pack(binary_format, self.name)
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3
		#write stuff
cvsextras 281bfc3
		for mesh in self.mesh_chunks:
cvsextras 281bfc3
			mesh.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class object_info_chunk(chunk):
cvsextras 281bfc3
	obj_chunks=[]
cvsextras 281bfc3
	mat_chunks=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.obj_chunks=[]
cvsextras 281bfc3
		self.mat_chunks=[]
cvsextras 281bfc3
		self.ID=OBJECTINFO
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=0
cvsextras 281bfc3
		for mat in self.mat_chunks:
cvsextras 281bfc3
			temp_size+=mat.get_size()
cvsextras 281bfc3
		for obj in self.obj_chunks:
cvsextras 281bfc3
			temp_size+=obj.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "object info size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write all the materials
cvsextras 281bfc3
		for mat in self.mat_chunks:
cvsextras 281bfc3
			mat.write(file)
cvsextras 281bfc3
		#write all the objects
cvsextras 281bfc3
		for obj in self.obj_chunks:
cvsextras 281bfc3
			obj.write(file)
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
class version_chunk(chunk):
cvsextras 281bfc3
	version=3
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=VERSION
cvsextras 281bfc3
		self.version=3 #that the document that I'm using
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=4 #bytes for the version info
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "version chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		temp_data=[0]
cvsextras 281bfc3
		temp_data[0]=self.version
cvsextras 281bfc3
		#write header and version
cvsextras 281bfc3
		data=struct.pack(binary_format,temp_data[0])
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3
class rgb_chunk(chunk):
cvsextras 281bfc3
	col=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.col=[]
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=3  #color size
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "rgb chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		binary_format="
cvsextras 281bfc3
		#write colors
cvsextras 281bfc3
		for i in [0, 1, 2]:
cvsextras 281bfc3
			data=struct.pack(binary_format,chr(255*self.col[i]))
cvsextras 281bfc3
			file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
class rgb1_chunk(rgb_chunk):
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=RGB1
cvsextras 281bfc3

cvsextras 281bfc3
class rgb2_chunk(rgb_chunk):
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=RGB2
cvsextras 281bfc3

cvsextras 281bfc3
class material_ambient_chunk(chunk):
cvsextras 281bfc3
	col1=None
cvsextras 281bfc3
	col2=None
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=MATAMBIENT
cvsextras 281bfc3
		self.col1=rgb1_chunk()
cvsextras 281bfc3
		self.col2=rgb2_chunk()
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=self.col1.get_size()
cvsextras 281bfc3
		temp_size+=self.col2.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "material ambient size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write colors
cvsextras 281bfc3
		self.col1.write(file)
cvsextras 281bfc3
		self.col2.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class material_diffuse_chunk(chunk):
cvsextras 281bfc3
	col1=None
cvsextras 281bfc3
	col2=None
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=MATDIFFUSE
cvsextras 281bfc3
		self.col1=rgb1_chunk()
cvsextras 281bfc3
		self.col2=rgb2_chunk()
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=self.col1.get_size()
cvsextras 281bfc3
		temp_size+=self.col2.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "material diffuse size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write colors
cvsextras 281bfc3
		self.col1.write(file)
cvsextras 281bfc3
		self.col2.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class material_specular_chunk(chunk):
cvsextras 281bfc3
	col1=None
cvsextras 281bfc3
	col2=None
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=MATSPECULAR
cvsextras 281bfc3
		self.col1=rgb1_chunk()
cvsextras 281bfc3
		self.col2=rgb2_chunk()
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=self.col1.get_size()
cvsextras 281bfc3
		temp_size+=self.col2.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "material specular size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write colors
cvsextras 281bfc3
		self.col1.write(file)
cvsextras 281bfc3
		self.col2.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class material_name_chunk(chunk):
cvsextras 281bfc3
	name=""
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=MATNAME
cvsextras 281bfc3
		self.name=""
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=(len(self.name)+1)
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "material name size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write name
cvsextras 281bfc3
		name_length=len(self.name)+1
cvsextras 281bfc3
		binary_format="<"+str(name_length)+"s"
cvsextras 281bfc3
		data=struct.pack(binary_format, self.name)
cvsextras 281bfc3
		file.write(data)
cvsextras 281bfc3

cvsextras 281bfc3
class material_chunk(chunk):
cvsextras 281bfc3
	matname_chunk=None
cvsextras 281bfc3
	matambient_chunk=None
cvsextras 281bfc3
	matdiffuse_chunk=None
cvsextras 281bfc3
	matspecular_chunk=None
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.ID=MATERIAL
cvsextras 281bfc3
		self.matname_chunk=material_name_chunk()
cvsextras 281bfc3
		self.matambient_chunk=material_ambient_chunk()
cvsextras 281bfc3
		self.matdiffuse_chunk=material_diffuse_chunk()
cvsextras 281bfc3
		self.matspecular_chunk=material_specular_chunk()
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=self.matname_chunk.get_size()
cvsextras 281bfc3
		temp_size+=self.matambient_chunk.get_size()
cvsextras 281bfc3
		temp_size+=self.matdiffuse_chunk.get_size()
cvsextras 281bfc3
		temp_size+=self.matspecular_chunk.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "material chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write name chunk
cvsextras 281bfc3
		self.matname_chunk.write(file)
cvsextras 281bfc3
		#write material colors
cvsextras 281bfc3
		self.matambient_chunk.write(file)
cvsextras 281bfc3
		self.matdiffuse_chunk.write(file)
cvsextras 281bfc3
		self.matspecular_chunk.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
class primary_chunk(chunk):
cvsextras 281bfc3
	version=None
cvsextras 281bfc3
	obj_info=None
cvsextras 281bfc3

cvsextras 281bfc3
	def __init__(self):
cvsextras 281bfc3
		self.version=version_chunk()
cvsextras 281bfc3
		self.obj_info=object_info_chunk()
cvsextras 281bfc3
		self.ID=PRIMARY
cvsextras 281bfc3

cvsextras 281bfc3
	def get_size(self):
cvsextras 281bfc3
		chunk.get_size(self)
cvsextras 281bfc3
		temp_size=self.version.get_size()
cvsextras 281bfc3
		temp_size+=self.obj_info.get_size()
cvsextras 281bfc3
		self.size+=temp_size
cvsextras 281bfc3
		print "primary chunk size: ", self.size
cvsextras 281bfc3
		return self.size
cvsextras 281bfc3

cvsextras 281bfc3
	def write(self, file):
cvsextras 281bfc3
		chunk.write(self, file)
cvsextras 281bfc3
		#write version chunk
cvsextras 281bfc3
		self.version.write(file)
cvsextras 281bfc3
		#write object_info chunk
cvsextras 281bfc3
		self.obj_info.write(file)
cvsextras 281bfc3

cvsextras 281bfc3
def read_chunk(file, chunk):
cvsextras 281bfc3
		temp_data=file.read(struct.calcsize(chunk.binary_format))
cvsextras 281bfc3
		data=struct.unpack(chunk.binary_format, temp_data)
cvsextras 281bfc3
		chunk.ID=data[0]
cvsextras 281bfc3
		chunk.size=data[1]
cvsextras 281bfc3

cvsextras 281bfc3
		#if debugging
cvsextras 281bfc3
		#chunk.dump()
cvsextras 281bfc3

cvsextras 281bfc3
def read_string(file):
cvsextras 281bfc3
	s=""
cvsextras 281bfc3
	index=0
cvsextras 281bfc3
	#print "reading a string"
cvsextras 281bfc3
	#read in the characters till we get a null character
cvsextras 281bfc3
	temp_data=file.read(struct.calcsize("c"))
cvsextras 281bfc3
	data=struct.unpack("c", temp_data)
cvsextras 281bfc3
	s=s+(data[0])
cvsextras 281bfc3
	#print "string: ",s
cvsextras 281bfc3
	while(ord(s[index])!=0):
cvsextras 281bfc3
		index+=1
cvsextras 281bfc3
		temp_data=file.read(struct.calcsize("c"))
cvsextras 281bfc3
		data=struct.unpack("c", temp_data)
cvsextras 281bfc3
		s=s+(data[0])
cvsextras 281bfc3
		#print "string: ",s
cvsextras 281bfc3
	return str(s)
cvsextras 281bfc3

cvsextras 281bfc3
######################################################
cvsextras 281bfc3
# EXPORT
cvsextras 281bfc3
######################################################
cvsextras 281bfc3
def save_3ds(filename):
cvsextras 281bfc3

cvsextras 281bfc3
	vert_list={}
cvsextras 281bfc3
	vert_count=0
cvsextras 281bfc3
	#open the current scene
cvsextras 281bfc3
	scene = Blender.Scene.GetCurrent()
cvsextras 281bfc3
	#if the user was lazy and didn't add a filename,
cvsextras 281bfc3
	#just name the files after the scene name
cvsextras 281bfc3
	#hope they weren't lazy there too.
cvsextras 281bfc3
	if filename=="model":
cvsextras 281bfc3
		filename=scene.getName()
cvsextras 281bfc3
		#basefilename and /path/filename are the same
cvsextras 281bfc3
		bfilename=filename
cvsextras 281bfc3
	else:
cvsextras 281bfc3
		#extract the actual filename from the
cvsextras 281bfc3
		#entire path of the /path/filename
cvsextras 281bfc3
		bfilename = os.path.basename(filename)
cvsextras 281bfc3

cvsextras 281bfc3
	exported_materials = []
cvsextras 281bfc3

cvsextras 281bfc3
	#fill the chunks full of data
cvsextras 281bfc3
	primary=primary_chunk()
cvsextras 281bfc3
	#get all the objects in this scene
cvsextras 281bfc3
	object_list=Blender.Object.Get()
cvsextras 281bfc3
	#fill up the data structures with objects
cvsextras 281bfc3
	for obj in object_list:
cvsextras 281bfc3
		#create a new object chunk
cvsextras 281bfc3
		if obj.getType()=="Mesh":
cvsextras 281bfc3
			primary.obj_info.obj_chunks.append(object_chunk())
cvsextras 281bfc3
			#get the mesh data
cvsextras 281bfc3
			blender_mesh=obj.getData()
cvsextras 281bfc3
			#set the object name
cvsextras 281bfc3
			primary.obj_info.obj_chunks[len(primary.obj_info.obj_chunks)-1].name=obj.getName()
cvsextras 281bfc3

cvsextras 281bfc3
			matrix = obj.getMatrix()
cvsextras 281bfc3

cvsextras 281bfc3
			#make a new mesh chunk object
cvsextras 281bfc3
			mesh=mesh_chunk()
cvsextras 281bfc3

cvsextras 281bfc3
			#fill verts in
cvsextras 281bfc3
			vert_count=0
cvsextras 281bfc3
			vert_list={}
cvsextras 281bfc3
			for vert in blender_mesh.verts:
cvsextras 281bfc3
				# get the vertex and apply all transforms to it
cvsextras 281bfc3
				v = point_by_matrix(vert.co, matrix)
cvsextras 281bfc3
				vert_key=(v[0], v[1], v[2])
cvsextras 281bfc3
				mesh.v_chunk.verts.append(vert_key)
cvsextras 281bfc3
				if not vert_list.has_key(vert_key):
cvsextras 281bfc3
					#print "didn't have the key"
cvsextras 281bfc3
					vert_list[vert_key] = vert_count  #save this info for the face lookup table
cvsextras 281bfc3
					vert_count = vert_count + 1
cvsextras 281bfc3

cvsextras 281bfc3
			print "vert_count: ", vert_count
cvsextras 281bfc3
			print "mesh.verts: ", len(blender_mesh.verts)
cvsextras 281bfc3

cvsextras 281bfc3
			for m in blender_mesh.materials:
cvsextras 281bfc3
				mesh.f_chunk.m_chunks.append(obj_material_chunk())
cvsextras 281bfc3
				mesh.f_chunk.m_chunks[len(mesh.f_chunk.m_chunks)-1].name = m.name
cvsextras 281bfc3

cvsextras 281bfc3
				# materials should only be exported once
cvsextras 281bfc3
				if m.name in exported_materials:
cvsextras 281bfc3
					continue
cvsextras 281bfc3

cvsextras 281bfc3
				material = material_chunk()
cvsextras 281bfc3
				material.matname_chunk.name=m.name
cvsextras 281bfc3
				material.matambient_chunk.col1.col = m.mirCol
cvsextras 281bfc3
				material.matambient_chunk.col2.col = m.mirCol
cvsextras 281bfc3
				material.matdiffuse_chunk.col1.col = m.rgbCol
cvsextras 281bfc3
				material.matdiffuse_chunk.col2.col = m.rgbCol
cvsextras 281bfc3
				material.matspecular_chunk.col1.col = m.specCol
cvsextras 281bfc3
				material.matspecular_chunk.col2.col = m.specCol
cvsextras 281bfc3

cvsextras 281bfc3
				primary.obj_info.mat_chunks.append(material)
cvsextras 281bfc3

cvsextras 281bfc3
				exported_materials.append(m.name)
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
			facenr=0
cvsextras 281bfc3
			#fill in faces
cvsextras 281bfc3
			for face in blender_mesh.faces:
cvsextras 281bfc3
				#is this a tri or a quad
cvsextras 281bfc3
				num_fv=len(face.v)
cvsextras 281bfc3
				
cvsextras 281bfc3
				#it's a tri
cvsextras 281bfc3
				if num_fv==3:
cvsextras 281bfc3
					indexes=[0]*3
cvsextras 281bfc3
					for i in range (0,3):
cvsextras 281bfc3
						#build the keys
cvsextras 281bfc3
						# get the vertex and apply all transforms to it
cvsextras 281bfc3
						vert=point_by_matrix(face.v[i].co, matrix)
cvsextras 281bfc3
						vert_key=(vert[0], vert[1], vert[2])
cvsextras 281bfc3
						#look up the key to get the index
cvsextras 281bfc3
						vert_index=vert_list[vert_key]
cvsextras 281bfc3
						indexes[i]=vert_index
cvsextras 281bfc3
					mesh.f_chunk.faces.append(indexes)
cvsextras 281bfc3
					if (face.materialIndex < len(mesh.f_chunk.m_chunks)):
cvsextras 281bfc3
						mesh.f_chunk.m_chunks[face.materialIndex].faces.append(facenr)
cvsextras 281bfc3
					facenr+=1
cvsextras 281bfc3
					
cvsextras 281bfc3
				#it's a quad
cvsextras 281bfc3
				elif num_fv==4:
cvsextras 281bfc3
					indexes=[0]*4
cvsextras 281bfc3
					for i in range (0,4):
cvsextras 281bfc3
						#build the keys
cvsextras 281bfc3
						vert=point_by_matrix(face.v[i].co, matrix)
cvsextras 281bfc3
						vert_key=(vert[0], vert[1], vert[2])
cvsextras 281bfc3
						#look up the key to get the index
cvsextras 281bfc3
						vert_index=vert_list[vert_key]
cvsextras 281bfc3
						indexes[i]=vert_index
cvsextras 281bfc3
						first_tri=(indexes[0], indexes[1], indexes[2])
cvsextras 281bfc3
						sec_tri=(indexes[2], indexes[3], indexes[0])
cvsextras 281bfc3
						
cvsextras 281bfc3
					mesh.f_chunk.faces.append(first_tri)  # 0,1,2
cvsextras 281bfc3
					mesh.f_chunk.faces.append(sec_tri)  # 2,3,0
cvsextras 281bfc3
					#first tri
cvsextras 281bfc3
					if (face.materialIndex < len(mesh.f_chunk.m_chunks)):
cvsextras 281bfc3
						mesh.f_chunk.m_chunks[face.materialIndex].faces.append(facenr)
cvsextras 281bfc3
					facenr+=1
cvsextras 281bfc3
					#other tri
cvsextras 281bfc3
					if (face.materialIndex < len(mesh.f_chunk.m_chunks)):
cvsextras 281bfc3
						mesh.f_chunk.m_chunks[face.materialIndex].faces.append(facenr)
cvsextras 281bfc3
					facenr+=1
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
			#fill in the UV info
cvsextras 281bfc3
			if blender_mesh.hasVertexUV():
cvsextras 281bfc3
				for vert in blender_mesh.verts:
cvsextras 281bfc3
					uv_coord=(vert.uvco)
cvsextras 281bfc3
					mesh.uv_chunk.uv.append((uv_coord[0], uv_coord[1]))
cvsextras 281bfc3

cvsextras 281bfc3
			elif blender_mesh.hasFaceUV():
cvsextras 281bfc3
				for face in blender_mesh.faces:
cvsextras 281bfc3
					num_fv=len(face.v)
cvsextras 281bfc3
					if num_fv==3:
cvsextras 281bfc3
						for i in range (0,3):
cvsextras 281bfc3
							uv_coord=(face.uv[i])
cvsextras 281bfc3
							mesh.uv_chunk.uv.append((uv_coord[0], uv_coord[1]))
cvsextras 281bfc3
					elif num_fv==4:
cvsextras 281bfc3
						for i in range (0,4):
cvsextras 281bfc3
							uv_coord=(face.uv[i])
cvsextras 281bfc3
							mesh.uv_chunk.uv.append((uv_coord[0], uv_coord[1]))
cvsextras 281bfc3

cvsextras 281bfc3

cvsextras 281bfc3
			#filled in our mesh, lets add it to the file
cvsextras 281bfc3
			primary.obj_info.obj_chunks[len(primary.obj_info.obj_chunks)-1].mesh_chunks.append(mesh)
cvsextras 281bfc3

cvsextras 281bfc3
	#check the size
cvsextras 281bfc3
	primary.get_size()
cvsextras 281bfc3
	#open the files up for writing
cvsextras 281bfc3
	file = open( filename, "wb" )
cvsextras 281bfc3
	#recursively write the stuff to file
cvsextras 281bfc3
	primary.write(file)
cvsextras 281bfc3
	file.close()
cvsextras 281bfc3

cvsextras 281bfc3
#***********************************************
cvsextras 281bfc3
# MAIN
cvsextras 281bfc3
#***********************************************
cvsextras 281bfc3

cvsextras 281bfc3
	
cvsextras 281bfc3
def my_callback(filename):
cvsextras 281bfc3
	if(filename.find('.3ds', -4) <= 0):
cvsextras 281bfc3
		filename += '.3ds'
cvsextras 281bfc3
	save_3ds(filename)
cvsextras 281bfc3

cvsextras 281bfc3
Blender.Window.FileSelector(my_callback, "Export 3DS")