# ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # # Script copyright (C) Bob Holcomb # Contributors: Bob Holcomb, Richard L?rk?ng, Damien McGinnes, Campbell Barton, Mario Lapin, Dominique Lorre import os import time import struct from io_utils import load_image import bpy import mathutils BOUNDS_3DS = [] ###################################################### # Data Structures ###################################################### #Some of the chunks that we will see #----- Primary Chunk, at the beginning of each file PRIMARY = 0x4D4D #------ Main Chunks OBJECTINFO = 0x3D3D # This gives the version of the mesh and is found right before the material and object information VERSION = 0x0002 # This gives the version of the .3ds file EDITKEYFRAME = 0xB000 # This is the header for all of the key frame info #------ sub defines of OBJECTINFO MATERIAL = 0xAFFF # This stored the texture info OBJECT = 0x4000 # This stores the faces, vertices, etc... #>------ sub defines of MATERIAL #------ sub defines of MATERIAL_BLOCK MAT_NAME = 0xA000 # This holds the material name MAT_AMBIENT = 0xA010 # Ambient color of the object/material MAT_DIFFUSE = 0xA020 # This holds the color of the object/material MAT_SPECULAR = 0xA030 # SPecular color of the object/material MAT_SHINESS = 0xA040 # ?? MAT_TRANSPARENCY = 0xA050 # Transparency value of material MAT_SELF_ILLUM = 0xA080 # Self Illumination value of material MAT_WIRE = 0xA085 # Only render's wireframe MAT_TEXTURE_MAP = 0xA200 # This is a header for a new texture map MAT_SPECULAR_MAP = 0xA204 # This is a header for a new specular map MAT_OPACITY_MAP = 0xA210 # This is a header for a new opacity map MAT_REFLECTION_MAP = 0xA220 # This is a header for a new reflection map MAT_BUMP_MAP = 0xA230 # This is a header for a new bump map MAT_MAP_FILEPATH = 0xA300 # This holds the file name of the texture MAT_FLOAT_COLOR = 0x0010 # color defined as 3 floats MAT_24BIT_COLOR = 0x0011 # color defined as 3 bytes #>------ sub defines of OBJECT OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object OBJECT_LAMP = 0x4600 # This lets un know we are reading a light object OBJECT_LAMP_SPOT = 0x4610 # The light is a spotloght. OBJECT_LAMP_OFF = 0x4620 # The light off. OBJECT_LAMP_ATTENUATE = 0x4625 OBJECT_LAMP_RAYSHADE = 0x4627 OBJECT_LAMP_SHADOWED = 0x4630 OBJECT_LAMP_LOCAL_SHADOW = 0x4640 OBJECT_LAMP_LOCAL_SHADOW2 = 0x4641 OBJECT_LAMP_SEE_CONE = 0x4650 OBJECT_LAMP_SPOT_RECTANGULAR = 0x4651 OBJECT_LAMP_SPOT_OVERSHOOT = 0x4652 OBJECT_LAMP_SPOT_PROJECTOR = 0x4653 OBJECT_LAMP_EXCLUDE = 0x4654 OBJECT_LAMP_RANGE = 0x4655 OBJECT_LAMP_ROLL = 0x4656 OBJECT_LAMP_SPOT_ASPECT = 0x4657 OBJECT_LAMP_RAY_BIAS = 0x4658 OBJECT_LAMP_INNER_RANGE = 0x4659 OBJECT_LAMP_OUTER_RANGE = 0x465A OBJECT_LAMP_MULTIPLIER = 0x465B OBJECT_LAMP_AMBIENT_LIGHT = 0x4680 OBJECT_CAMERA = 0x4700 # This lets un know we are reading a camera object #>------ sub defines of CAMERA OBJECT_CAM_RANGES = 0x4720 # The camera range values #>------ sub defines of OBJECT_MESH OBJECT_VERTICES = 0x4110 # The objects vertices OBJECT_FACES = 0x4120 # The objects faces OBJECT_MATERIAL = 0x4130 # This is found if the object has a material, either texture map or color OBJECT_UV = 0x4140 # The UV texture coordinates OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix #>------ sub defines of EDITKEYFRAME ED_KEY_AMBIENT_NODE = 0xB001 ED_KEY_OBJECT_NODE = 0xB002 ED_KEY_CAMERA_NODE = 0xB003 ED_KEY_TARGET_NODE = 0xB004 ED_KEY_LIGHT_NODE = 0xB005 ED_KEY_L_TARGET_NODE = 0xB006 ED_KEY_SPOTLIGHT_NODE = 0xB007 #>------ sub defines of ED_KEY_OBJECT_NODE # EK_OB_KEYFRAME_SEG = 0xB008 # EK_OB_KEYFRAME_CURTIME = 0xB009 # EK_OB_KEYFRAME_HEADER = 0xB00A EK_OB_NODE_HEADER = 0xB010 EK_OB_INSTANCE_NAME = 0xB011 # EK_OB_PRESCALE = 0xB012 EK_OB_PIVOT = 0xB013 # EK_OB_BOUNDBOX = 0xB014 # EK_OB_MORPH_SMOOTH = 0xB015 EK_OB_POSITION_TRACK = 0xB020 EK_OB_ROTATION_TRACK = 0xB021 EK_OB_SCALE_TRACK = 0xB022 # EK_OB_CAMERA_FOV_TRACK = 0xB023 # EK_OB_CAMERA_ROLL_TRACK = 0xB024 # EK_OB_COLOR_TRACK = 0xB025 # EK_OB_MORPH_TRACK = 0xB026 # EK_OB_HOTSPOT_TRACK = 0xB027 # EK_OB_FALLOF_TRACK = 0xB028 # EK_OB_HIDE_TRACK = 0xB029 # EK_OB_NODE_ID = 0xB030 ROOT_OBJECT = 0xFFFF global scn scn = None object_dictionary = {} object_matrix = {} #the chunk class class chunk: ID = 0 length = 0 bytes_read = 0 #we don't read in the bytes_read, we compute that binary_format = " 3): print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) #is it an object info chunk? elif (new_chunk.ID == OBJECTINFO): #print 'elif (new_chunk.ID == OBJECTINFO):' # print 'found an OBJECTINFO chunk' process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) #keep track of how much we read in the main chunk new_chunk.bytes_read += temp_chunk.bytes_read #is it an object chunk? elif (new_chunk.ID == OBJECT): if CreateBlenderObject: putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) contextMesh_vertls = [] contextMesh_facels = [] ## preparando para receber o proximo objeto contextMeshMaterials = {} # matname:[face_idxs] contextMeshUV = None #contextMesh.vertexUV = 1 # Make sticky coords. # Reset matrix contextMatrix_rot = None #contextMatrix_tx = None CreateBlenderObject = True contextObName, read_str_len = read_string(file) new_chunk.bytes_read += read_str_len #is it a material chunk? elif (new_chunk.ID == MATERIAL): # print("read material") #print 'elif (new_chunk.ID == MATERIAL):' contextMaterial = bpy.data.materials.new('Material') elif (new_chunk.ID == MAT_NAME): #print 'elif (new_chunk.ID == MAT_NAME):' material_name, read_str_len = read_string(file) # print("material name", material_name) #plus one for the null character that ended the string new_chunk.bytes_read += read_str_len contextMaterial.name = material_name.rstrip() # remove trailing whitespace MATDICT[material_name] = (contextMaterial.name, contextMaterial) elif (new_chunk.ID == MAT_AMBIENT): #print 'elif (new_chunk.ID == MAT_AMBIENT):' read_chunk(file, temp_chunk) if (temp_chunk.ID == MAT_FLOAT_COLOR): contextMaterial.mirror_color = read_float_color(temp_chunk) # temp_data = file.read(struct.calcsize('3f')) # temp_chunk.bytes_read += 12 # contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] elif (temp_chunk.ID == MAT_24BIT_COLOR): contextMaterial.mirror_color = read_byte_color(temp_chunk) # temp_data = file.read(struct.calcsize('3B')) # temp_chunk.bytes_read += 3 # contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb else: skip_to_end(file, temp_chunk) new_chunk.bytes_read += temp_chunk.bytes_read elif (new_chunk.ID == MAT_DIFFUSE): #print 'elif (new_chunk.ID == MAT_DIFFUSE):' read_chunk(file, temp_chunk) if (temp_chunk.ID == MAT_FLOAT_COLOR): contextMaterial.diffuse_color = read_float_color(temp_chunk) # temp_data = file.read(struct.calcsize('3f')) # temp_chunk.bytes_read += 12 # contextMaterial.rgbCol = [float(col) for col in struct.unpack('<3f', temp_data)] elif (temp_chunk.ID == MAT_24BIT_COLOR): contextMaterial.diffuse_color = read_byte_color(temp_chunk) # temp_data = file.read(struct.calcsize('3B')) # temp_chunk.bytes_read += 3 # contextMaterial.rgbCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb else: skip_to_end(file, temp_chunk) # print("read material diffuse color", contextMaterial.diffuse_color) new_chunk.bytes_read += temp_chunk.bytes_read elif (new_chunk.ID == MAT_SPECULAR): #print 'elif (new_chunk.ID == MAT_SPECULAR):' read_chunk(file, temp_chunk) if (temp_chunk.ID == MAT_FLOAT_COLOR): contextMaterial.specular_color = read_float_color(temp_chunk) # temp_data = file.read(struct.calcsize('3f')) # temp_chunk.bytes_read += 12 # contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] elif (temp_chunk.ID == MAT_24BIT_COLOR): contextMaterial.specular_color = read_byte_color(temp_chunk) # temp_data = file.read(struct.calcsize('3B')) # temp_chunk.bytes_read += 3 # contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb else: skip_to_end(file, temp_chunk) new_chunk.bytes_read += temp_chunk.bytes_read elif (new_chunk.ID == MAT_TEXTURE_MAP): read_texture(new_chunk, temp_chunk, "Diffuse", "COLOR") elif (new_chunk.ID == MAT_SPECULAR_MAP): read_texture(new_chunk, temp_chunk, "Specular", "SPECULARITY") elif (new_chunk.ID == MAT_OPACITY_MAP): read_texture(new_chunk, temp_chunk, "Opacity", "ALPHA") elif (new_chunk.ID == MAT_BUMP_MAP): read_texture(new_chunk, temp_chunk, "Bump", "NORMAL") elif (new_chunk.ID == MAT_TRANSPARENCY): #print 'elif (new_chunk.ID == MAT_TRANSPARENCY):' read_chunk(file, temp_chunk) temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT) temp_chunk.bytes_read += 2 contextMaterial.alpha = 1 - (float(struct.unpack(' BOUNDS_3DS[i + 3]: BOUNDS_3DS[i + 3] = v[i] # min # Get the max axis x/y/z max_axis = max(BOUNDS_3DS[3] - BOUNDS_3DS[0], BOUNDS_3DS[4] - BOUNDS_3DS[1], BOUNDS_3DS[5] - BOUNDS_3DS[2]) # print max_axis if max_axis < 1 << 30: # Should never be false but just make sure. # Get a new scale factor if set as an option SCALE = 1.0 while (max_axis * SCALE) > IMPORT_CONSTRAIN_BOUNDS: SCALE /= 10.0 # SCALE Matrix SCALE_MAT = mathutils.Matrix.Scale(SCALE, 4) for ob in importedObjects: if ob.parent is None: ob.matrix_world = ob.matrix_world * SCALE_MAT # Done constraining to bounds. # Select all new objects. print(" done in %.4f sec." % (time.clock() - time1)) file.close() def load(operator, context, filepath="", constrain_size=0.0, use_image_search=True, use_apply_transform=True): load_3ds(filepath, context, IMPORT_CONSTRAIN_BOUNDS=constrain_size, IMAGE_SEARCH=use_image_search, APPLY_MATRIX=use_apply_transform) return {'FINISHED'}