|
cvsextras |
281bfc3 |
#!BPY
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
"""
|
|
cvsextras |
281bfc3 |
Name: '3D Studio'
|
|
cvsextras |
281bfc3 |
Blender: 233
|
|
cvsextras |
281bfc3 |
Group: 'Import'
|
|
cvsextras |
281bfc3 |
Tip: 'Import from 3DS file format. (.3ds)'
|
|
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
|
|
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 |
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 |
#the chunk class
|
|
cvsextras |
281bfc3 |
class chunk:
|
|
cvsextras |
281bfc3 |
ID=0
|
|
cvsextras |
281bfc3 |
length=0
|
|
cvsextras |
281bfc3 |
bytes_read=0
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#we don't read in the bytes_read, we compute that
|
|
cvsextras |
281bfc3 |
binary_format="
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
def __init__(self):
|
|
cvsextras |
281bfc3 |
self.ID=0
|
|
cvsextras |
281bfc3 |
self.length=0
|
|
cvsextras |
281bfc3 |
self.bytes_read=0
|
|
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 "length: ", self.length
|
|
cvsextras |
281bfc3 |
print "bytes_read: ", self.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
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.length=data[1]
|
|
cvsextras |
281bfc3 |
#update the bytes read function
|
|
cvsextras |
281bfc3 |
chunk.bytes_read=6
|
|
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 |
|
|
cvsextras |
281bfc3 |
#remove the null character from the string
|
|
cvsextras |
281bfc3 |
the_string=s[:-1]
|
|
cvsextras |
281bfc3 |
return str(the_string)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
######################################################
|
|
cvsextras |
281bfc3 |
# IMPORT
|
|
cvsextras |
281bfc3 |
######################################################
|
|
cvsextras |
281bfc3 |
def process_next_object_chunk(file, previous_chunk, mesh):
|
|
cvsextras |
281bfc3 |
new_chunk=chunk()
|
|
cvsextras |
281bfc3 |
temp_chunk=chunk()
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
while (previous_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
#read the next chunk
|
|
cvsextras |
281bfc3 |
read_chunk(file, new_chunk)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
if (new_chunk.ID==OBJECT_MESH):
|
|
cvsextras |
281bfc3 |
print "Found an OBJECT_MESH chunk"
|
|
cvsextras |
281bfc3 |
print "object_mesh: lenght: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
process_next_object_chunk(file, new_chunk, mesh)
|
|
cvsextras |
281bfc3 |
print "object mesh: bytes read: ", new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==OBJECT_VERTICES):
|
|
cvsextras |
281bfc3 |
print "Found an OBJECT_VERTICES chunk"
|
|
cvsextras |
281bfc3 |
print "object_verts: lenght: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("H"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("H", temp_data)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=2
|
|
cvsextras |
281bfc3 |
num_verts=data[0]
|
|
cvsextras |
281bfc3 |
print "number of verts: ", num_verts
|
|
cvsextras |
281bfc3 |
for counter in range (0,num_verts):
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("3f"))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=12 #3 floats x 4 bytes each
|
|
cvsextras |
281bfc3 |
data=struct.unpack("3f", temp_data)
|
|
cvsextras |
281bfc3 |
v=NMesh.Vert(data[0],data[1],data[2])
|
|
cvsextras |
281bfc3 |
mesh.verts.append(v)
|
|
cvsextras |
281bfc3 |
print "object verts: bytes read: ", new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==OBJECT_FACES):
|
|
cvsextras |
281bfc3 |
print "Found an OBJECT_FACES chunk"
|
|
cvsextras |
281bfc3 |
print "object faces: lenght: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("H"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("H", temp_data)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=2
|
|
cvsextras |
281bfc3 |
num_faces=data[0]
|
|
cvsextras |
281bfc3 |
print "number of faces: ", num_faces
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
for counter in range(0,num_faces):
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("4H"))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=8 #4 short ints x 2 bytes each
|
|
cvsextras |
281bfc3 |
data=struct.unpack("4H", temp_data)
|
|
cvsextras |
281bfc3 |
#insert the mesh info into the faces, don't worry about data[3] it is a 3D studio thing
|
|
cvsextras |
281bfc3 |
f=NMesh.Face()
|
|
cvsextras |
281bfc3 |
f.v.append(mesh.verts[data[0]])
|
|
cvsextras |
281bfc3 |
f.v.append(mesh.verts[data[1]])
|
|
cvsextras |
281bfc3 |
f.v.append(mesh.verts[data[2]])
|
|
cvsextras |
281bfc3 |
mesh.faces.append(f)
|
|
cvsextras |
281bfc3 |
print "object faces: bytes read: ", new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==OBJECT_MATERIAL):
|
|
cvsextras |
281bfc3 |
print "Found an OBJECT_MATERIAL chunk"
|
|
cvsextras |
281bfc3 |
print "object material: length: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
material_name=""
|
|
cvsextras |
281bfc3 |
material_name=str(read_string(file))
|
|
cvsextras |
281bfc3 |
#plus one for the null character that gets removed
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=(len(material_name)+1)
|
|
cvsextras |
281bfc3 |
print "material_name: ", material_name
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#look up the material in all the materials
|
|
cvsextras |
281bfc3 |
material_found=0
|
|
cvsextras |
281bfc3 |
for mat in Material.Get():
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#found it, add it to the mesh
|
|
cvsextras |
281bfc3 |
if(mat.name==material_name):
|
|
cvsextras |
281bfc3 |
if(len(mesh.materials)>=15):
|
|
cvsextras |
281bfc3 |
result=Blender.Draw.PupMenu("Cannot assign more than 16 materials to a mesh: Continue?%t|OK")
|
|
cvsextras |
281bfc3 |
break;
|
|
cvsextras |
281bfc3 |
else:
|
|
cvsextras |
281bfc3 |
mesh.addMaterial(mat)
|
|
cvsextras |
281bfc3 |
material_found=1
|
|
cvsextras |
281bfc3 |
print "found material: ",mat.name
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#figure out what material index this is for the mesh
|
|
cvsextras |
281bfc3 |
for mat_counter in range(0,len(mesh.materials)):
|
|
cvsextras |
281bfc3 |
if mesh.materials[mat_counter].name==material_name:
|
|
cvsextras |
281bfc3 |
mat_index=mat_counter
|
|
cvsextras |
281bfc3 |
print "material index: ",mat_index
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#break out of this for loop so we don't accidentally set material_found back to 0
|
|
cvsextras |
281bfc3 |
break
|
|
cvsextras |
281bfc3 |
else:
|
|
cvsextras |
281bfc3 |
material_found=0
|
|
cvsextras |
281bfc3 |
#print "Not matching: ", mat.name, " and ", material_name
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
if(material_found==1):
|
|
cvsextras |
281bfc3 |
#read the number of faces using this material
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("H"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("H", temp_data)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=2
|
|
cvsextras |
281bfc3 |
num_faces_using_mat=data[0]
|
|
cvsextras |
281bfc3 |
print "number of faces using this material: ", num_faces_using_mat
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#list of faces using mat
|
|
cvsextras |
281bfc3 |
for face_counter in range(0,num_faces_using_mat):
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("H"))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=2
|
|
cvsextras |
281bfc3 |
data=struct.unpack("H", temp_data)
|
|
cvsextras |
281bfc3 |
#print "face #: ", data[0]
|
|
cvsextras |
281bfc3 |
mesh.faces[data[0]].materialIndex=mat_index
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
else:
|
|
cvsextras |
281bfc3 |
#read past the information about the material you couldn't find
|
|
cvsextras |
281bfc3 |
print "Couldn't find material. Reading past face material info"
|
|
cvsextras |
281bfc3 |
buffer_size=new_chunk.length-new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
binary_format=str(buffer_size)+"c"
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize(binary_format))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=buffer_size
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
print "object mat: bytes read: ", new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==OBJECT_UV):
|
|
cvsextras |
281bfc3 |
print "Found an OBJECT_UV chunk"
|
|
cvsextras |
281bfc3 |
print "object uv: lenght: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("H"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("H", temp_data)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=2
|
|
cvsextras |
281bfc3 |
num_uv=data[0]
|
|
cvsextras |
281bfc3 |
print "number of UV: ", num_uv
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
for counter in range(0,num_uv):
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("2f"))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=8 #2 float x 4 bytes each
|
|
cvsextras |
281bfc3 |
data=struct.unpack("2f", temp_data)
|
|
cvsextras |
281bfc3 |
#insert the insert the UV coords in the vertex data
|
|
cvsextras |
281bfc3 |
mesh.verts[counter].uvco[0]=data[0]
|
|
cvsextras |
281bfc3 |
mesh.verts[counter].uvco[1]=data[1]
|
|
cvsextras |
281bfc3 |
#turn on the sticky UV coords for this mesh
|
|
cvsextras |
281bfc3 |
mesh.hasVertexUV(1)
|
|
cvsextras |
281bfc3 |
print "object uv: bytes read: ", new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
else:
|
|
cvsextras |
281bfc3 |
print "Found some other Object chunk: ",hex(new_chunk.ID)
|
|
cvsextras |
281bfc3 |
print "object faces: length: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
buffer_size=new_chunk.length-new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
binary_format=str(buffer_size)+"c"
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize(binary_format))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=buffer_size
|
|
cvsextras |
281bfc3 |
print "object other: bytes read: ", new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
previous_chunk.bytes_read+=new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
print "Bytes left in this Object chunk: ", previous_chunk.length-previous_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
def process_next_material_chunk(file, previous_chunk, mat):
|
|
cvsextras |
281bfc3 |
new_chunk=chunk()
|
|
cvsextras |
281bfc3 |
temp_chunk=chunk()
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
while (previous_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
#read the next chunk
|
|
cvsextras |
281bfc3 |
read_chunk(file, new_chunk)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
if (new_chunk.ID==MATNAME):
|
|
cvsextras |
281bfc3 |
print "Found a MATNAME chunk"
|
|
cvsextras |
281bfc3 |
material_name=""
|
|
cvsextras |
281bfc3 |
material_name=str(read_string(file))
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#plus one for the null character that ended the string
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=(len(material_name)+1)
|
|
cvsextras |
281bfc3 |
print "material_name: ", material_name
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
mat.setName(material_name)
|
|
cvsextras |
281bfc3 |
print "mat.name: ", mat.name
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==MATAMBIENT):
|
|
cvsextras |
281bfc3 |
print "Found a MATAMBIENT chunk"
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
read_chunk(file, temp_chunk)
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("3B"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("3B", temp_data)
|
|
cvsextras |
281bfc3 |
temp_chunk.bytes_read+=3
|
|
cvsextras |
281bfc3 |
r=data[0]
|
|
cvsextras |
281bfc3 |
g=data[1]
|
|
cvsextras |
281bfc3 |
b=data[2]
|
|
cvsextras |
281bfc3 |
mat.setMirCol(float(r)/255, float(g)/255, float(b)/255)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=temp_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==MATDIFFUSE):
|
|
cvsextras |
281bfc3 |
print "Found a MATDIFFUSE chunk"
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
read_chunk(file, temp_chunk)
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("3B"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("3B", temp_data)
|
|
cvsextras |
281bfc3 |
temp_chunk.bytes_read+=3
|
|
cvsextras |
281bfc3 |
r=data[0]
|
|
cvsextras |
281bfc3 |
g=data[1]
|
|
cvsextras |
281bfc3 |
b=data[2]
|
|
cvsextras |
281bfc3 |
mat.setRGBCol(float(r)/255, float(g)/255, float(b)/255)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=temp_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==MATSPECULAR):
|
|
cvsextras |
281bfc3 |
print "Found a MATSPECULAR chunk"
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
read_chunk(file, temp_chunk)
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("3B"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("3B", temp_data)
|
|
cvsextras |
281bfc3 |
temp_chunk.bytes_read+=3
|
|
cvsextras |
281bfc3 |
r=data[0]
|
|
cvsextras |
281bfc3 |
g=data[1]
|
|
cvsextras |
281bfc3 |
b=data[2]
|
|
cvsextras |
281bfc3 |
mat.setSpecCol(float(r)/255, float(g)/255, float(b)/255)
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=temp_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==MATMAP):
|
|
cvsextras |
281bfc3 |
print "Found a MATMAP chunk"
|
|
cvsextras |
281bfc3 |
#recurse into this one
|
|
cvsextras |
281bfc3 |
process_next_material_chunk(file, new_chunk, mat)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==MATMAPFILE):
|
|
cvsextras |
281bfc3 |
print "Found a MATMAPFILE chunk"
|
|
cvsextras |
281bfc3 |
texture_name=""
|
|
cvsextras |
281bfc3 |
texture_name=str(read_string(file))
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#plus one for the null character that gets removed
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=(len(texture_name)+1)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
else:
|
|
cvsextras |
281bfc3 |
print "Found some other Material chunk: ",hex(new_chunk.ID)
|
|
cvsextras |
281bfc3 |
buffer_size=new_chunk.length-new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
binary_format=str(buffer_size)+"c"
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize(binary_format))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=buffer_size
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
previous_chunk.bytes_read+=new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
print "Bytes left in this Material chunk: ", previous_chunk.length-previous_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
def process_next_chunk(file, previous_chunk):
|
|
cvsextras |
281bfc3 |
#a spare chunk
|
|
cvsextras |
281bfc3 |
new_chunk=chunk()
|
|
cvsextras |
281bfc3 |
temp_chunk=chunk()
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#loop through all the data for this chunk (previous chunk) and see what it is
|
|
cvsextras |
281bfc3 |
while (previous_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
#read the next chunk
|
|
cvsextras |
281bfc3 |
print "reading a chunk"
|
|
cvsextras |
281bfc3 |
read_chunk(file, new_chunk)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#is it a Version chunk?
|
|
cvsextras |
281bfc3 |
if (new_chunk.ID==VERSION):
|
|
cvsextras |
281bfc3 |
print "found a VERSION chunk"
|
|
cvsextras |
281bfc3 |
print "version: lenght: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
#read in the version of the file
|
|
cvsextras |
281bfc3 |
#it's an unsigned short (H)
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize("I"))
|
|
cvsextras |
281bfc3 |
data=struct.unpack("I", temp_data)
|
|
cvsextras |
281bfc3 |
version=data[0]
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=4 #read the 4 bytes for the version number
|
|
cvsextras |
281bfc3 |
#this loader works with version 3 and below, but may not with 4 and above
|
|
cvsextras |
281bfc3 |
if (version>3):
|
|
cvsextras |
281bfc3 |
print "Non-Fatal Error: Version greater than 3, may not load correctly: ", version
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#is it an object info chunk?
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==OBJECTINFO):
|
|
cvsextras |
281bfc3 |
print "found an OBJECTINFO chunk"
|
|
cvsextras |
281bfc3 |
print "object info: lenght: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
#recursively go through the rest of the file
|
|
cvsextras |
281bfc3 |
process_next_chunk(file, new_chunk)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#keep track of how much we read in the main chunk
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=temp_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#is it an object chunk?
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==OBJECT):
|
|
cvsextras |
281bfc3 |
print "found an OBJECT chunk"
|
|
cvsextras |
281bfc3 |
print "object length: ", new_chunk.length
|
|
cvsextras |
281bfc3 |
#make a mesh
|
|
cvsextras |
281bfc3 |
mesh=NMesh.New()
|
|
cvsextras |
281bfc3 |
mesh.name=str(read_string(file))
|
|
cvsextras |
281bfc3 |
print "mesh name: ", mesh.name
|
|
cvsextras |
281bfc3 |
#plus one for the null character that gets removed
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=(len(mesh.name)+1)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
process_next_object_chunk(file, new_chunk, mesh)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#put the object into blender at the cursor location
|
|
cvsextras |
281bfc3 |
mesh_obj=NMesh.PutRaw(mesh)
|
|
cvsextras |
281bfc3 |
cursor_pos=Blender.Window.GetCursorPos()
|
|
cvsextras |
281bfc3 |
mesh_obj.setLocation(float(cursor_pos[0]),float(cursor_pos[1]),float(cursor_pos[2]))
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#is it a material chunk?
|
|
cvsextras |
281bfc3 |
elif (new_chunk.ID==MATERIAL):
|
|
cvsextras |
281bfc3 |
print "found a MATERIAL chunk"
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
material=Material.New()
|
|
cvsextras |
281bfc3 |
process_next_material_chunk(file, new_chunk, material)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
else: #(new_chunk.ID!=VERSION or new_chunk.ID!=OBJECTINFO or new_chunk.ID!=OBJECT or new_chunk.ID!=MATERIAL):
|
|
cvsextras |
281bfc3 |
print "skipping to end of this chunk"
|
|
cvsextras |
281bfc3 |
buffer_size=new_chunk.length-new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
binary_format=str(buffer_size)+"c"
|
|
cvsextras |
281bfc3 |
temp_data=file.read(struct.calcsize(binary_format))
|
|
cvsextras |
281bfc3 |
new_chunk.bytes_read+=buffer_size
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#update the previous chunk bytes read
|
|
cvsextras |
281bfc3 |
previous_chunk.bytes_read+=new_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
print "Bytes left in this chunk: ", previous_chunk.length-previous_chunk.bytes_read
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
def load_3ds (filename):
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
current_chunk=chunk()
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
file=open(filename,"rb")
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#here we go!
|
|
cvsextras |
281bfc3 |
print "reading the first chunk"
|
|
cvsextras |
281bfc3 |
read_chunk(file, current_chunk)
|
|
cvsextras |
281bfc3 |
if (current_chunk.ID!=PRIMARY):
|
|
cvsextras |
281bfc3 |
print "Fatal Error: Not a valid 3ds file: ", filename
|
|
cvsextras |
281bfc3 |
Exit()
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
process_next_chunk(file, current_chunk)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
file.close()
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
#***********************************************
|
|
cvsextras |
281bfc3 |
# MAIN
|
|
cvsextras |
281bfc3 |
#***********************************************
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
def my_callback(filename):
|
|
cvsextras |
281bfc3 |
load_3ds(filename)
|
|
cvsextras |
281bfc3 |
|
|
cvsextras |
281bfc3 |
Blender.Window.FileSelector(my_callback, "Import 3DS")
|