diff --git a/io_scene_3ds/__init__.py b/io_scene_3ds/__init__.py index af4aaa5644949ddedb6eab43022e56acb0857b92..0137dd222f5ad263adf7eaac0cf110c02008724d 100644 --- a/io_scene_3ds/__init__.py +++ b/io_scene_3ds/__init__.py @@ -18,6 +18,19 @@ # <pep8-80 compliant> +from bpy_extras.io_utils import ( + ImportHelper, + ExportHelper, + orientation_helper, + axis_conversion, +) +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + StringProperty, +) +import bpy bl_info = { "name": "Autodesk 3DS format", "author": "Bob Holcomb, Campbell Barton, Andreas Atteneder, Sebastian Schrand", @@ -40,21 +53,6 @@ if "bpy" in locals(): importlib.reload(export_3ds) -import bpy -from bpy.props import ( - BoolProperty, - EnumProperty, - FloatProperty, - StringProperty, - ) -from bpy_extras.io_utils import ( - ImportHelper, - ExportHelper, - orientation_helper, - axis_conversion, - ) - - @orientation_helper(axis_forward='Y', axis_up='Z') class Import3DS(bpy.types.Operator, ImportHelper): """Import from 3DS file format (.3ds)""" @@ -66,31 +64,31 @@ class Import3DS(bpy.types.Operator, ImportHelper): filter_glob: StringProperty(default="*.3ds", options={'HIDDEN'}) constrain_size: FloatProperty( - name="Size Constraint", - description="Scale the model by 10 until it reaches the " - "size constraint (0 to disable)", - min=0.0, max=1000.0, - soft_min=0.0, soft_max=1000.0, - default=10.0, - ) + name="Size Constraint", + description="Scale the model by 10 until it reaches the " + "size constraint (0 to disable)", + min=0.0, max=1000.0, + soft_min=0.0, soft_max=1000.0, + default=10.0, + ) use_image_search: BoolProperty( - name="Image Search", - description="Search subdirectories for any associated images " - "(Warning, may be slow)", - default=True, - ) + name="Image Search", + description="Search subdirectories for any associated images " + "(Warning, may be slow)", + default=True, + ) use_apply_transform: BoolProperty( - name="Apply Transform", - description="Workaround for object transformations " - "importing incorrectly", - default=True, - ) + name="Apply Transform", + description="Workaround for object transformations " + "importing incorrectly", + default=True, + ) read_keyframe: bpy.props.BoolProperty( - name="Read Keyframe", - description="Read the keyframe data", - default=True, - ) + name="Read Keyframe", + description="Read the keyframe data", + default=True, + ) def execute(self, context): from . import import_3ds @@ -116,15 +114,15 @@ class Export3DS(bpy.types.Operator, ExportHelper): filename_ext = ".3ds" filter_glob: StringProperty( - default="*.3ds", - options={'HIDDEN'}, - ) + default="*.3ds", + options={'HIDDEN'}, + ) use_selection: BoolProperty( - name="Selection Only", - description="Export selected objects only", - default=False, - ) + name="Selection Only", + description="Export selected objects only", + default=False, + ) def execute(self, context): from . import export_3ds @@ -174,5 +172,6 @@ def unregister(): # disabled scaling to size, this requires exposing bb (easy) and understanding # how it works (needs some time) + if __name__ == "__main__": register() diff --git a/io_scene_3ds/export_3ds.py b/io_scene_3ds/export_3ds.py index d96d665148cccfd9a066ffc57d21b9f9e08608c0..de5333f9ba6522ebb21be1530243bfba4c638552 100644 --- a/io_scene_3ds/export_3ds.py +++ b/io_scene_3ds/export_3ds.py @@ -37,22 +37,22 @@ from bpy_extras import node_shader_utils # Data Structures ###################################################### -#Some of the chunks that we will export -#----- Primary Chunk, at the beginning of each file +# Some of the chunks that we will export +# ----- Primary Chunk, at the beginning of each file PRIMARY = 0x4D4D -#------ Main Chunks +# ------ Main Chunks VERSION = 0x0002 # This gives the version of the .3ds file KFDATA = 0xB000 # This is the header for all of the key frame info -#------ sub defines of OBJECTINFO +# ------ sub defines of OBJECTINFO OBJECTINFO = 0x3D3D # Main mesh object chunk before the material and object information MESHVERSION = 0x3D3E # This gives the version of the mesh AMBIENTLIGHT = 0x2100 # The color of the ambient light MATERIAL = 45055 # 0xAFFF // This stored the texture info OBJECT = 16384 # 0x4000 // This stores the faces, vertices, etc... -#>------ sub defines of MATERIAL +# >------ sub defines of MATERIAL MATNAME = 0xA000 # This holds the material name MATAMBIENT = 0xA010 # Ambient color of the object/material MATDIFFUSE = 0xA020 # This holds the color of the object/material @@ -74,7 +74,7 @@ MAT_TEX2MAP = 0xA33A # head for secondary texture MAT_SHINMAP = 0xA33C # head for roughness map MAT_SELFIMAP = 0xA33D # head for emission map -#>------ sub defines of MAT_MAP +# >------ sub defines of MAT_MAP MATMAPFILE = 0xA300 # This holds the file name of a texture MAT_MAP_TILING = 0xa351 # 2nd bit (from LSB) is mirror UV flag MAT_MAP_TEXBLUR = 0xA353 # Texture blurring factor @@ -95,20 +95,20 @@ RGB2 = 0x0012 # RGB Color2 PCT = 0x0030 # Percent chunk MASTERSCALE = 0x0100 # Master scale factor -#>------ sub defines of OBJECT +# >------ sub defines of OBJECT OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object OBJECT_LIGHT = 0x4600 # This lets us know we are reading a light object OBJECT_CAMERA = 0x4700 # This lets us know we are reading a camera object -#>------ Sub defines of LIGHT +# >------ Sub defines of LIGHT LIGHT_MULTIPLIER = 0x465B # The light energy factor LIGHT_SPOTLIGHT = 0x4610 # The target of a spotlight LIGHT_SPOTROLL = 0x4656 # The roll angle of the spot -#>------ sub defines of CAMERA +# >------ sub defines of CAMERA OBJECT_CAM_RANGES = 0x4720 # The camera range values -#>------ sub defines of OBJECT_MESH +# >------ 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 @@ -116,13 +116,13 @@ OBJECT_UV = 0x4140 # The UV texture coordinates OBJECT_SMOOTH = 0x4150 # The objects smooth groups OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix -#>------ sub defines of KFDATA +# >------ sub defines of KFDATA KFDATA_KFHDR = 0xB00A KFDATA_KFSEG = 0xB008 KFDATA_KFCURTIME = 0xB009 KFDATA_OBJECT_NODE_TAG = 0xB002 -#>------ sub defines of OBJECT_NODE_TAG +# >------ sub defines of OBJECT_NODE_TAG OBJECT_NODE_ID = 0xB030 OBJECT_NODE_HDR = 0xB010 OBJECT_PIVOT = 0xB013 @@ -160,6 +160,7 @@ def sane_name(name): def uv_key(uv): return round(uv[0], 6), round(uv[1], 6) + # size defines: SZ_SHORT = 2 SZ_INT = 4 @@ -236,7 +237,7 @@ class _3ds_string(object): def __str__(self): return str(self.value) - + class _3ds_point_3d(object): """Class representing a three-dimensional point for a 3ds file.""" __slots__ = "x", "y", "z" @@ -253,6 +254,7 @@ class _3ds_point_3d(object): def __str__(self): return '(%f, %f, %f)' % (self.x, self.y, self.z) + # Used for writing a track ''' class _3ds_point_4d(object): @@ -290,7 +292,7 @@ class _3ds_point_uv(object): def __str__(self): return '(%g, %g)' % self.uv - + class _3ds_float_color(object): """Class representing a rgb float color for a 3ds file.""" __slots__ = "r", "g", "b" @@ -406,7 +408,7 @@ class _3ds_named_variable(object): self.value) -#the chunk class +# the chunk class class _3ds_chunk(object): """Class representing a chunk in a 3ds file. @@ -459,7 +461,7 @@ class _3ds_chunk(object): """Write the chunk to a file. Uses the write function of the variables and the subchunks to do the actual work.""" - #write header + # write header self.ID.write(file) self.size.write(file) for variable in self.variables: @@ -495,6 +497,7 @@ def get_material_image(material): if slot.type == 'IMAGE': return slot + def get_uv_image(ma): """ Get image from material wrapper.""" if ma and ma.use_nodes: @@ -505,6 +508,7 @@ def get_uv_image(ma): else: return get_material_image(ma) + def make_material_subchunk(chunk_id, color): """Make a material subchunk. @@ -516,17 +520,19 @@ def make_material_subchunk(chunk_id, color): # optional: #col2 = _3ds_chunk(RGB1) #col2.add_variable("color2", _3ds_rgb_color(color)) - #mat_sub.add_subchunk(col2) + # mat_sub.add_subchunk(col2) return mat_sub + def make_percent_subchunk(chunk_id, percent): """Make a percentage based subchunk.""" pct_sub = _3ds_chunk(chunk_id) pcti = _3ds_chunk(PCT) - pcti.add_variable("percent", _3ds_ushort(int(round(percent * 100,0)))) + pcti.add_variable("percent", _3ds_ushort(int(round(percent * 100, 0)))) pct_sub.add_subchunk(pcti) return pct_sub + def make_texture_chunk(chunk_id, images): """Make Material Map texture chunk.""" # Add texture percentage value (100 = 1.0) @@ -538,13 +544,14 @@ def make_texture_chunk(chunk_id, images): ma_sub_file = _3ds_chunk(MATMAPFILE) ma_sub_file.add_variable("image", _3ds_string(sane_name(filename))) ma_sub.add_subchunk(ma_sub_file) - + for image in images: add_image(image) has_entry = True - + return ma_sub if has_entry else None + def make_material_texture_chunk(chunk_id, texslots, pct): """Make Material Map texture chunk given a seq. of `MaterialTextureSlot`'s Paint slots are optionally used as image source if no nodes are @@ -577,18 +584,18 @@ def make_material_texture_chunk(chunk_id, texslots, pct): mat_sub_tile.add_variable("tiling", _3ds_ushort(maptile)) mat_sub.add_subchunk(mat_sub_tile) - if socket=='Alpha': + if socket == 'Alpha': mat_sub_alpha = _3ds_chunk(MAP_TILING) alphaflag = 0x40 # summed area sampling 0x20 mat_sub_alpha.add_variable("alpha", _3ds_ushort(alphaflag)) mat_sub.add_subchunk(mat_sub_alpha) if texslot.socket_dst.identifier in {'Base Color', 'Specular'}: mat_sub_tint = _3ds_chunk(MAP_TILING) # RGB tint 0x200 - tint = 0x80 if texslot.image.colorspace_settings.name=='Non-Color' else 0x200 + tint = 0x80 if texslot.image.colorspace_settings.name == 'Non-Color' else 0x200 mat_sub_tint.add_variable("tint", _3ds_ushort(tint)) mat_sub.add_subchunk(mat_sub_tint) - mat_sub_texblur = _3ds_chunk(MAT_MAP_TEXBLUR) # Based on observation this is usually 1.0 + mat_sub_texblur = _3ds_chunk(MAT_MAP_TEXBLUR) # Based on observation this is usually 1.0 mat_sub_texblur.add_variable("maptexblur", _3ds_float(1.0)) mat_sub.add_subchunk(mat_sub_texblur) @@ -599,7 +606,7 @@ def make_material_texture_chunk(chunk_id, texslots, pct): mat_sub_vscale = _3ds_chunk(MAT_MAP_VSCALE) mat_sub_vscale.add_variable("mapvscale", _3ds_float(round(texslot.scale[1], 6))) mat_sub.add_subchunk(mat_sub_vscale) - + mat_sub_uoffset = _3ds_chunk(MAT_MAP_UOFFSET) mat_sub_uoffset.add_variable("mapuoffset", _3ds_float(round(texslot.translation[0], 6))) mat_sub.add_subchunk(mat_sub_uoffset) @@ -609,11 +616,11 @@ def make_material_texture_chunk(chunk_id, texslots, pct): mat_sub.add_subchunk(mat_sub_voffset) mat_sub_angle = _3ds_chunk(MAT_MAP_ANG) - mat_sub_angle.add_variable("mapangle", _3ds_float(round(texslot.rotation[2],6))) + mat_sub_angle.add_variable("mapangle", _3ds_float(round(texslot.rotation[2], 6))) mat_sub.add_subchunk(mat_sub_angle) if texslot.socket_dst.identifier in {'Base Color', 'Specular'}: - rgb = _3ds_chunk(MAP_COL1) # Add tint color + rgb = _3ds_chunk(MAP_COL1) # Add tint color base = texslot.owner_shader.material.diffuse_color[:3] spec = texslot.owner_shader.material.specular_color[:] rgb.add_variable("mapcolor", _3ds_rgb_color(spec if texslot.socket_dst.identifier == 'Specular' else base)) @@ -629,6 +636,7 @@ def make_material_texture_chunk(chunk_id, texslots, pct): return mat_sub if has_entry else None + def make_material_chunk(material, image): """Make a material chunk out of a blender material. Shading method is required for 3ds max, 0 for wireframe. @@ -653,7 +661,7 @@ def make_material_chunk(material, image): material_chunk.add_subchunk(make_percent_subchunk(MATSHINESS, .2)) material_chunk.add_subchunk(make_percent_subchunk(MATSHIN2, 1)) material_chunk.add_subchunk(shading) - + elif material and material.use_nodes: wrap = node_shader_utils.PrincipledBSDFWrapper(material) shading.add_variable("shading", _3ds_ushort(3)) # Phong shading @@ -663,11 +671,11 @@ def make_material_chunk(material, image): material_chunk.add_subchunk(make_percent_subchunk(MATSHINESS, wrap.roughness)) material_chunk.add_subchunk(make_percent_subchunk(MATSHIN2, wrap.specular)) material_chunk.add_subchunk(make_percent_subchunk(MATSHIN3, wrap.metallic)) - material_chunk.add_subchunk(make_percent_subchunk(MATTRANS, 1-wrap.alpha)) + material_chunk.add_subchunk(make_percent_subchunk(MATTRANS, 1 - wrap.alpha)) material_chunk.add_subchunk(shading) - + if wrap.base_color_texture: - d_pct = 0.7+sum(wrap.base_color[:])*.1 + d_pct = 0.7 + sum(wrap.base_color[:]) * .1 color = [wrap.base_color_texture] matmap = make_material_texture_chunk(MAT_DIFFUSEMAP, color, d_pct) if matmap: @@ -686,7 +694,7 @@ def make_material_chunk(material, image): matmap = make_material_texture_chunk(MAT_OPACMAP, alpha, a_pct) if matmap: material_chunk.add_subchunk(matmap) - + if wrap.metallic_texture: metallic = [wrap.metallic_texture] m_pct = material.metallic @@ -698,7 +706,7 @@ def make_material_chunk(material, image): normal = [wrap.normalmap_texture] bump = wrap.normalmap_strength b_pct = min(bump, 1) - bumpval = min(999, (bump * 100)) # 3ds max bump = 999 + bumpval = min(999, (bump * 100)) # 3ds max bump = 999 strength = _3ds_chunk(MAT_BUMP_PERCENT) strength.add_variable("bump_pct", _3ds_ushort(int(bumpval))) matmap = make_material_texture_chunk(MAT_BUMPMAP, normal, b_pct) @@ -714,7 +722,7 @@ def make_material_chunk(material, image): material_chunk.add_subchunk(matmap) if wrap.emission_color_texture: - e_pct = sum(wrap.emission_color[:])*.25 + e_pct = sum(wrap.emission_color[:]) * .25 emission = [wrap.emission_color_texture] matmap = make_material_texture_chunk(MAT_SELFIMAP, emission, e_pct) if matmap: @@ -727,7 +735,7 @@ def make_material_chunk(material, image): for link in wrap.material.node_tree.links: if link.from_node.type == 'TEX_IMAGE' and link.to_node.type != 'BSDF_PRINCIPLED': diffuse = [link.from_node.image] if not wrap.normalmap_texture else None - + if diffuse: matmap = make_texture_chunk(MAT_TEX2MAP, diffuse) if matmap: @@ -741,14 +749,14 @@ def make_material_chunk(material, image): material_chunk.add_subchunk(make_percent_subchunk(MATSHINESS, material.roughness)) material_chunk.add_subchunk(make_percent_subchunk(MATSHIN2, material.specular_intensity)) material_chunk.add_subchunk(make_percent_subchunk(MATSHIN3, material.metallic)) - material_chunk.add_subchunk(make_percent_subchunk(MATTRANS, 1-material.diffuse_color[3])) + material_chunk.add_subchunk(make_percent_subchunk(MATTRANS, 1 - material.diffuse_color[3])) material_chunk.add_subchunk(shading) slots = [get_material_image(material)] # can be None if image: material_chunk.add_subchunk(make_texture_chunk(MAT_DIFFUSEMAP, slots)) - + return material_chunk @@ -770,10 +778,10 @@ class tri_wrapper(object): def extract_triangles(mesh): """Extract triangles from a mesh.""" - + mesh.calc_loop_triangles() (polygroup, count) = mesh.calc_smooth_groups(use_bitflags=True) - + tri_list = [] do_uv = bool(mesh.uv_layers) @@ -942,7 +950,7 @@ def make_faces_chunk(tri_list, mesh, materialDict): if do_smooth: obj_smooth_chunk = _3ds_chunk(OBJECT_SMOOTH) for i, tri in enumerate(tri_list): - obj_smooth_chunk.add_variable("face_" + str(i),_3ds_uint(tri.group)) + obj_smooth_chunk.add_variable("face_" + str(i), _3ds_uint(tri.group)) face_chunk.add_subchunk(obj_smooth_chunk) return face_chunk @@ -961,6 +969,7 @@ def make_uv_chunk(uv_array): uv_chunk.add_variable("uv coords", uv_array) return uv_chunk + ''' def make_matrix_4x3_chunk(matrix): matrix_chunk = _3ds_chunk(OBJECT_TRANS_MATRIX) @@ -970,6 +979,7 @@ def make_matrix_4x3_chunk(matrix): return matrix_chunk ''' + def make_mesh_chunk(ob, mesh, matrix, materialDict, translation): """Make a chunk out of a Blender mesh.""" @@ -992,7 +1002,7 @@ def make_mesh_chunk(ob, mesh, matrix, materialDict, translation): # add vertex chunk: mesh_chunk.add_subchunk(make_vert_chunk(vert_array)) - + # add faces chunk: mesh_chunk.add_subchunk(make_faces_chunk(tri_list, mesh, materialDict)) @@ -1000,7 +1010,7 @@ def make_mesh_chunk(ob, mesh, matrix, materialDict, translation): if uv_array: mesh_chunk.add_subchunk(make_uv_chunk(uv_array)) - #mesh_chunk.add_subchunk(make_matrix_4x3_chunk(matrix)) + # mesh_chunk.add_subchunk(make_matrix_4x3_chunk(matrix)) # create transformation matrix chunk matrix_chunk = _3ds_chunk(OBJECT_TRANS_MATRIX) @@ -1010,7 +1020,7 @@ def make_mesh_chunk(ob, mesh, matrix, materialDict, translation): obj_translate = translation[ob.name] else: # Calculate child matrix translation relative to parent - obj_translate = translation[ob.name].cross(-1*translation[ob.parent.name]) + obj_translate = translation[ob.name].cross(-1 * translation[ob.parent.name]) matrix_chunk.add_variable("xx", _3ds_float(obj_matrix[0].to_tuple(6)[0])) matrix_chunk.add_variable("xy", _3ds_float(obj_matrix[0].to_tuple(6)[1])) @@ -1024,7 +1034,7 @@ def make_mesh_chunk(ob, mesh, matrix, materialDict, translation): matrix_chunk.add_variable("tx", _3ds_float(obj_translate.to_tuple(6)[0])) matrix_chunk.add_variable("ty", _3ds_float(obj_translate.to_tuple(6)[1])) matrix_chunk.add_variable("tz", _3ds_float(obj_translate.to_tuple(6)[2])) - + mesh_chunk.add_subchunk(matrix_chunk) return mesh_chunk @@ -1167,7 +1177,7 @@ def save(operator, # Time the export duration = time.time() - #Blender.Window.WaitCursor(1) + # Blender.Window.WaitCursor(1) if global_matrix is None: global_matrix = mathutils.Matrix() @@ -1196,7 +1206,7 @@ def save(operator, mscale = _3ds_chunk(MASTERSCALE) mscale.add_variable("scale", _3ds_float(1)) object_info.add_subchunk(mscale) - + # Add AMBIENT color if scene.world is not None: ambient_chunk = _3ds_chunk(AMBIENTLIGHT) @@ -1219,7 +1229,7 @@ def save(operator, objects = [ob for ob in scene.objects if not ob.hide_viewport and ob.select_get(view_layer=layer)] else: objects = [ob for ob in scene.objects if not ob.hide_viewport] - + light_objects = [ob for ob in objects if ob.type == 'LIGHT'] camera_objects = [ob for ob in objects if ob.type == 'CAMERA'] @@ -1276,7 +1286,7 @@ def save(operator, if f.material_index >= ma_ls_len: f.material_index = 0 - #ob_derived_eval.to_mesh_clear() + # ob_derived_eval.to_mesh_clear() if free: free_derived_objects(ob) @@ -1321,8 +1331,8 @@ def save(operator, kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) ''' - #if not blender_mesh.users: - #bpy.data.meshes.remove(blender_mesh) + # if not blender_mesh.users: + # bpy.data.meshes.remove(blender_mesh) #blender_mesh.vertices = None i += i @@ -1344,23 +1354,23 @@ def save(operator, object_chunk.add_variable("light", _3ds_string(sane_name(ob.name))) light_chunk.add_variable("location", _3ds_point_3d(ob.location)) color_float_chunk.add_variable("color", _3ds_float_color(ob.data.color)) - energy_factor.add_variable("energy", _3ds_float(ob.data.energy*.001)) + energy_factor.add_variable("energy", _3ds_float(ob.data.energy * .001)) light_chunk.add_subchunk(color_float_chunk) light_chunk.add_subchunk(energy_factor) if ob.data.type == 'SPOT': cone_angle = math.degrees(ob.data.spot_size) - hotspot = cone_angle-(ob.data.spot_blend*math.floor(cone_angle)) - hypo = math.copysign(math.sqrt(pow(ob.location[0],2)+pow(ob.location[1],2)), ob.location[1]) - pos_x = ob.location[0]+(ob.location[1]*math.tan(ob.rotation_euler[2])) - pos_y = ob.location[1]+(ob.location[0]*math.tan(math.radians(90)-ob.rotation_euler[2])) - pos_z = hypo*math.tan(math.radians(90)-ob.rotation_euler[0]) + hotspot = cone_angle - (ob.data.spot_blend * math.floor(cone_angle)) + hypo = math.copysign(math.sqrt(pow(ob.location[0], 2) + pow(ob.location[1], 2)), ob.location[1]) + pos_x = ob.location[0] + (ob.location[1] * math.tan(ob.rotation_euler[2])) + pos_y = ob.location[1] + (ob.location[0] * math.tan(math.radians(90) - ob.rotation_euler[2])) + pos_z = hypo * math.tan(math.radians(90) - ob.rotation_euler[0]) spotlight_chunk = _3ds_chunk(LIGHT_SPOTLIGHT) spot_roll_chunk = _3ds_chunk(LIGHT_SPOTROLL) spotlight_chunk.add_variable("target", _3ds_point_3d((pos_x, pos_y, pos_z))) - spotlight_chunk.add_variable("hotspot", _3ds_float(round(hotspot,4))) - spotlight_chunk.add_variable("angle", _3ds_float(round(cone_angle,4))) - spot_roll_chunk.add_variable("roll", _3ds_float(round(ob.rotation_euler[1],6))) + spotlight_chunk.add_variable("hotspot", _3ds_float(round(hotspot, 4))) + spotlight_chunk.add_variable("angle", _3ds_float(round(cone_angle, 4))) + spot_roll_chunk.add_variable("roll", _3ds_float(round(ob.rotation_euler[1], 6))) spotlight_chunk.add_subchunk(spot_roll_chunk) light_chunk.add_subchunk(spotlight_chunk) @@ -1372,14 +1382,14 @@ def save(operator, for ob in camera_objects: object_chunk = _3ds_chunk(OBJECT) camera_chunk = _3ds_chunk(OBJECT_CAMERA) - diagonal = math.copysign(math.sqrt(pow(ob.location[0],2)+pow(ob.location[1],2)), ob.location[1]) - focus_x = ob.location[0]+(ob.location[1]*math.tan(ob.rotation_euler[2])) - focus_y = ob.location[1]+(ob.location[0]*math.tan(math.radians(90)-ob.rotation_euler[2])) - focus_z = diagonal*math.tan(math.radians(90)-ob.rotation_euler[0]) + diagonal = math.copysign(math.sqrt(pow(ob.location[0], 2) + pow(ob.location[1], 2)), ob.location[1]) + focus_x = ob.location[0] + (ob.location[1] * math.tan(ob.rotation_euler[2])) + focus_y = ob.location[1] + (ob.location[0] * math.tan(math.radians(90) - ob.rotation_euler[2])) + focus_z = diagonal * math.tan(math.radians(90) - ob.rotation_euler[0]) object_chunk.add_variable("camera", _3ds_string(sane_name(ob.name))) camera_chunk.add_variable("location", _3ds_point_3d(ob.location)) camera_chunk.add_variable("target", _3ds_point_3d((focus_x, focus_y, focus_z))) - camera_chunk.add_variable("roll", _3ds_float(round(ob.rotation_euler[1],6))) + camera_chunk.add_variable("roll", _3ds_float(round(ob.rotation_euler[1], 6))) camera_chunk.add_variable("lens", _3ds_float(ob.data.lens)) object_chunk.add_subchunk(camera_chunk) object_info.add_subchunk(object_chunk) @@ -1410,10 +1420,10 @@ def save(operator, name_mapping.clear() # Debugging only: report the exporting time: - #Blender.Window.WaitCursor(0) + # Blender.Window.WaitCursor(0) print("3ds export time: %.2f" % (time.time() - duration)) # Debugging only: dump the chunk hierarchy: - #primary.dump() + # primary.dump() return {'FINISHED'} diff --git a/io_scene_3ds/import_3ds.py b/io_scene_3ds/import_3ds.py index 636fb105a803f3bb178aa4181004fab9c7e4e4c1..cb3d9b4ca08e58fcd73a99744049219ab9ae28f6 100644 --- a/io_scene_3ds/import_3ds.py +++ b/io_scene_3ds/import_3ds.py @@ -37,25 +37,25 @@ BOUNDS_3DS = [] # Data Structures ###################################################### -#Some of the chunks that we will see -#----- Primary Chunk, at the beginning of each file +# Some of the chunks that we will see +# ----- Primary Chunk, at the beginning of each file PRIMARY = 0x4D4D -#------ Main Chunks +# ------ 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 -#------ Data Chunks, used for various attributes +# ------ Data Chunks, used for various attributes PERCENTAGE_SHORT = 0x30 PERCENTAGE_FLOAT = 0x31 -#------ sub defines of OBJECTINFO +# ------ 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 +# >------ 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 @@ -92,7 +92,7 @@ MAT_MAP_BCOL = 0xA368 # Blue mapping MAT_FLOAT_COLOR = 0x0010 # color defined as 3 floats MAT_24BIT_COLOR = 0x0011 # color defined as 3 bytes -#>------ sub defines of OBJECT +# >------ sub defines of OBJECT OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object OBJECT_LIGHT = 0x4600 # This lets un know we are reading a light object OBJECT_LIGHT_SPOT = 0x4610 # The light is a spotloght. @@ -118,10 +118,10 @@ OBJECT_LIGHT_AMBIENT_LIGHT = 0x4680 OBJECT_CAMERA = 0x4700 # This lets un know we are reading a camera object -#>------ sub defines of CAMERA +# >------ sub defines of CAMERA OBJECT_CAM_RANGES = 0x4720 # The camera range values -#>------ sub defines of OBJECT_MESH +# >------ 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 @@ -129,7 +129,7 @@ OBJECT_UV = 0x4140 # The UV texture coordinates OBJECT_SMOOTH = 0x4150 # The Object smooth groups OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix -#>------ sub defines of EDITKEYFRAME +# >------ sub defines of EDITKEYFRAME KFDATA_AMBIENT = 0xB001 KFDATA_OBJECT = 0xB002 KFDATA_CAMERA = 0xB003 @@ -140,7 +140,7 @@ KFDATA_SPOTLIGHT = 0xB007 KFDATA_KFSEG = 0xB008 # KFDATA_CURTIME = 0xB009 # KFDATA_KFHDR = 0xB00A -#>------ sub defines of KEYFRAME_NODE +# >------ sub defines of KEYFRAME_NODE OBJECT_NODE_HDR = 0xB010 OBJECT_INSTANCE_NAME = 0xB011 # OBJECT_PRESCALE = 0xB012 @@ -194,15 +194,15 @@ def read_chunk(file, chunk): data = struct.unpack(chunk.binary_format, temp_data) chunk.ID = data[0] chunk.length = data[1] - #update the bytes read function + # update the bytes read function chunk.bytes_read = 6 - #if debugging - #chunk.dump() + # if debugging + # chunk.dump() def read_string(file): - #read in the characters till we get a null character + # read in the characters till we get a null character s = [] while True: c = file.read(1) @@ -224,7 +224,7 @@ def process_next_object_chunk(file, previous_chunk): new_chunk = Chunk() while (previous_chunk.bytes_read < previous_chunk.length): - #read the next chunk + # read the next chunk read_chunk(file, new_chunk) @@ -238,40 +238,40 @@ def skip_to_end(file, skip_chunk): def add_texture_to_material(image, contextWrapper, pct, extend, alpha, scale, offset, angle, tintcolor, mapto): shader = contextWrapper.node_principled_bsdf nodetree = contextWrapper.material.node_tree - shader.location = (-300,0) + shader.location = (-300, 0) nodes = nodetree.nodes links = nodetree.links if mapto == 'COLOR': mixer = nodes.new(type='ShaderNodeMixRGB') mixer.label = "Mixer" - mixer.inputs[0].default_value = pct/100 - mixer.inputs[1].default_value = tintcolor[:3]+[1] if tintcolor else (0,0,0,0) - contextWrapper._grid_to_location(1,2, dst_node=mixer, ref_node=shader) + mixer.inputs[0].default_value = pct / 100 + mixer.inputs[1].default_value = tintcolor[:3] + [1] if tintcolor else (0, 0, 0, 0) + contextWrapper._grid_to_location(1, 2, dst_node=mixer, ref_node=shader) img_wrap = contextWrapper.base_color_texture links.new(img_wrap.node_image.outputs['Color'], mixer.inputs[2]) links.new(mixer.outputs['Color'], shader.inputs['Base Color']) elif mapto == 'SPECULARITY': img_wrap = contextWrapper.specular_texture elif mapto == 'ALPHA': - shader.location = (0,-300) + shader.location = (0, -300) img_wrap = contextWrapper.alpha_texture elif mapto == 'METALLIC': - shader.location = (300,300) + shader.location = (300, 300) img_wrap = contextWrapper.metallic_texture elif mapto == 'ROUGHNESS': - shader.location = (300,0) + shader.location = (300, 0) img_wrap = contextWrapper.roughness_texture elif mapto == 'EMISSION': - shader.location = (-300,-600) + shader.location = (-300, -600) img_wrap = contextWrapper.emission_color_texture elif mapto == 'NORMAL': - shader.location = (300,300) + shader.location = (300, 300) img_wrap = contextWrapper.normalmap_texture elif mapto == 'TEXTURE': img_wrap = nodes.new(type='ShaderNodeTexImage') img_wrap.label = image.name - contextWrapper._grid_to_location(0,2, dst_node=img_wrap, ref_node=shader) + contextWrapper._grid_to_location(0, 2, dst_node=img_wrap, ref_node=shader) for node in nodes: if node.label == 'Mixer': spare = node.inputs[1] if node.inputs[1].is_linked is False else node.inputs[2] @@ -284,7 +284,7 @@ def add_texture_to_material(image, contextWrapper, pct, extend, alpha, scale, of img_wrap.image = image img_wrap.extension = 'REPEAT' - + if mapto != 'TEXTURE': img_wrap.scale = scale img_wrap.translation = offset @@ -304,8 +304,8 @@ def add_texture_to_material(image, contextWrapper, pct, extend, alpha, scale, of if alpha == 'alpha': links.new(img_wrap.node_image.outputs['Alpha'], img_wrap.socket_dst) - shader.location = (300,300) - contextWrapper._grid_to_location(1,0, dst_node=contextWrapper.node_out, ref_node=shader) + shader.location = (300, 300) + contextWrapper._grid_to_location(1, 0, dst_node=contextWrapper.node_out, ref_node=shader) def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEARCH, KEYFRAME): @@ -339,7 +339,8 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA object_parent = [] # index of parent in hierarchy, 0xFFFF = no parent pivot_list = [] # pivots with hierarchy handling - def putContextMesh(context, myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials, myContextMeshSmooth): + def putContextMesh(context, myContextMesh_vertls, myContextMesh_facels, + myContextMeshMaterials, myContextMeshSmooth): bmesh = bpy.data.meshes.new(contextObName) if myContextMesh_facels is None: @@ -381,7 +382,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA bmesh.materials.append(bmat) # can be None - if uv_faces and img: + if uv_faces and img: for fidx in faces: bmesh.polygons[fidx].material_index = mat_idx # TODO: How to restore this? @@ -423,7 +424,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA ob.matrix_local = contextMatrix object_matrix[ob] = contextMatrix.copy() - #a spare chunk + # a spare chunk new_chunk = Chunk() temp_chunk = Chunk() @@ -458,14 +459,14 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA extend = 'wrap' alpha = False pct = 50 - + contextWrapper.emission_color = contextMaterial.line_color[:3] contextWrapper.base_color = contextMaterial.diffuse_color[:3] contextWrapper.specular = contextMaterial.specular_intensity contextWrapper.roughness = contextMaterial.roughness contextWrapper.metallic = contextMaterial.metallic contextWrapper.alpha = contextMaterial.diffuse_color[3] - + while (new_chunk.bytes_read < new_chunk.length): read_chunk(file, temp_chunk) if temp_chunk.ID == PERCENTAGE_SHORT: @@ -523,32 +524,37 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA dirname = os.path.dirname(file.name) - #loop through all the data for this chunk (previous chunk) and see what it is + # loop through all the data for this chunk (previous chunk) and see what it is while (previous_chunk.bytes_read < previous_chunk.length): read_chunk(file, new_chunk) - #is it a Version chunk? + # is it a Version chunk? if new_chunk.ID == VERSION: - #read in the version of the file + # read in the version of the file temp_data = file.read(struct.calcsize('I')) version = struct.unpack('<I', temp_data)[0] new_chunk.bytes_read += 4 # read the 4 bytes for the version number - #this loader works with version 3 and below, but may not with 4 and above + # this loader works with version 3 and below, but may not with 4 and above if version > 3: print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) - #is it an object info chunk? + # is it an object info chunk? elif new_chunk.ID == OBJECTINFO: process_next_chunk(context, file, new_chunk, importedObjects, IMAGE_SEARCH, KEYFRAME) - #keep track of how much we read in the main chunk + # keep track of how much we read in the main chunk new_chunk.bytes_read += temp_chunk.bytes_read - #is it an object chunk? + # is it an object chunk? elif new_chunk.ID == OBJECT: if CreateBlenderObject: - putContextMesh(context, contextMesh_vertls, contextMesh_facels, contextMeshMaterials, contextMesh_smooth) + putContextMesh( + context, + contextMesh_vertls, + contextMesh_facels, + contextMeshMaterials, + contextMesh_smooth) contextMesh_vertls = [] contextMesh_facels = [] contextMeshMaterials = [] @@ -561,7 +567,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA contextObName, read_str_len = read_string(file) new_chunk.bytes_read += read_str_len - #is it a material chunk? + # is it a material chunk? elif new_chunk.ID == MATERIAL: contextMaterial = bpy.data.materials.new('Material') contextWrapper = PrincipledBSDFWrapper(contextMaterial, is_readonly=False, use_nodes=False) @@ -569,7 +575,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA elif new_chunk.ID == MAT_NAME: material_name, read_str_len = read_string(file) - #plus one for the null character that ended the string + # 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 @@ -653,7 +659,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA temp_chunk.bytes_read += SZ_FLOAT contextMaterial.diffuse_color[3] = 1 - float(struct.unpack('f', temp_data)[0]) else: - print( "Cannot read material transparency") + print("Cannot read material transparency") new_chunk.bytes_read += temp_chunk.bytes_read elif new_chunk.ID == MAT_TEXTURE_MAP: @@ -709,17 +715,17 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA temp_data = file.read(SZ_FLOAT) contextLamp.data.energy = float(struct.unpack('f', temp_data)[0]) new_chunk.bytes_read += SZ_FLOAT - + elif CreateLightObject and new_chunk.ID == OBJECT_LIGHT_SPOT: # spotlight temp_data = file.read(SZ_3FLOAT) contextLamp.data.type = 'SPOT' spot = mathutils.Vector(struct.unpack('<3f', temp_data)) aim = contextLamp.location + spot - hypo = math.copysign(math.sqrt(pow(aim[1],2)+pow(aim[0],2)),aim[1]) - track = math.copysign(math.sqrt(pow(hypo,2)+pow(spot[2],2)),aim[1]) - angle = math.radians(90)-math.copysign(math.acos(hypo/track),aim[2]) - contextLamp.rotation_euler[0] = -1*math.copysign(angle, aim[1]) - contextLamp.rotation_euler[2] = -1*(math.radians(90)-math.acos(aim[0]/hypo)) + hypo = math.copysign(math.sqrt(pow(aim[1], 2) + pow(aim[0], 2)), aim[1]) + track = math.copysign(math.sqrt(pow(hypo, 2) + pow(spot[2], 2)), aim[1]) + angle = math.radians(90) - math.copysign(math.acos(hypo / track), aim[2]) + contextLamp.rotation_euler[0] = -1 * math.copysign(angle, aim[1]) + contextLamp.rotation_euler[2] = -1 * (math.radians(90) - math.acos(aim[0] / hypo)) new_chunk.bytes_read += SZ_3FLOAT temp_data = file.read(SZ_FLOAT) # hotspot hotspot = float(struct.unpack('f', temp_data)[0]) @@ -727,13 +733,13 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA temp_data = file.read(SZ_FLOAT) # angle beam_angle = float(struct.unpack('f', temp_data)[0]) contextLamp.data.spot_size = math.radians(beam_angle) - contextLamp.data.spot_blend = (1.0 - (hotspot/beam_angle))*2 + contextLamp.data.spot_blend = (1.0 - (hotspot / beam_angle)) * 2 new_chunk.bytes_read += SZ_FLOAT elif CreateLightObject and new_chunk.ID == OBJECT_LIGHT_ROLL: # roll temp_data = file.read(SZ_FLOAT) contextLamp.rotation_euler[1] = float(struct.unpack('f', temp_data)[0]) new_chunk.bytes_read += SZ_FLOAT - + elif contextObName and new_chunk.ID == OBJECT_CAMERA and CreateCameraObject is False: # Basic camera support camera = bpy.data.cameras.new("Camera") contextCamera = bpy.data.objects.new(contextObName, camera) @@ -745,14 +751,14 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA temp_data = file.read(SZ_3FLOAT) target = mathutils.Vector(struct.unpack('<3f', temp_data)) cam = contextCamera.location + target - focus = math.copysign(math.sqrt(pow(cam[1],2)+pow(cam[0],2)),cam[1]) + focus = math.copysign(math.sqrt(pow(cam[1], 2) + pow(cam[0], 2)), cam[1]) new_chunk.bytes_read += SZ_3FLOAT temp_data = file.read(SZ_FLOAT) # triangulating camera angles - direction = math.copysign(math.sqrt(pow(focus,2)+pow(target[2],2)),cam[1]) - pitch = math.radians(90)-math.copysign(math.acos(focus/direction),cam[2]) - contextCamera.rotation_euler[0] = -1*math.copysign(pitch, cam[1]) + direction = math.copysign(math.sqrt(pow(focus, 2) + pow(target[2], 2)), cam[1]) + pitch = math.radians(90) - math.copysign(math.acos(focus / direction), cam[2]) + contextCamera.rotation_euler[0] = -1 * math.copysign(pitch, cam[1]) contextCamera.rotation_euler[1] = float(struct.unpack('f', temp_data)[0]) - contextCamera.rotation_euler[2] = -1*(math.radians(90)-math.acos(cam[0]/focus)) + contextCamera.rotation_euler[2] = -1 * (math.radians(90) - math.acos(cam[0] / focus)) new_chunk.bytes_read += SZ_FLOAT temp_data = file.read(SZ_FLOAT) contextCamera.data.lens = (float(struct.unpack('f', temp_data)[0]) * 10) @@ -763,10 +769,10 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA elif new_chunk.ID == OBJECT_MESH: pass - + elif new_chunk.ID == OBJECT_VERTICES: """Worldspace vertex locations""" - + temp_data = file.read(SZ_U_SHORT) num_verts = struct.unpack('<H', temp_data)[0] new_chunk.bytes_read += 2 @@ -793,7 +799,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA new_chunk.bytes_read += SZ_U_SHORT * num_faces_using_mat temp_data = struct.unpack("<%dH" % (num_faces_using_mat), temp_data) contextMeshMaterials.append((material_name, temp_data)) - #look up the material in all the materials + # look up the material in all the materials elif new_chunk.ID == OBJECT_SMOOTH: temp_data = file.read(struct.calcsize('I') * num_faces) @@ -814,17 +820,19 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA temp_data = file.read(SZ_4x3MAT) data = list(struct.unpack('<ffffffffffff', temp_data)) new_chunk.bytes_read += SZ_4x3MAT - contextMatrix = mathutils.Matrix((data[:3]+[0], data[3:6]+[0], data[6:9]+[0], data[9:]+[1])).transposed() + contextMatrix = mathutils.Matrix( + (data[:3] + [0], data[3:6] + [0], data[6:9] + [0], data[9:] + [1])).transposed() - elif (new_chunk.ID == MAT_MAP_FILEPATH): + elif (new_chunk.ID == MAT_MAP_FILEPATH): texture_name, read_str_len = read_string(file) if contextMaterial.name not in TEXTURE_DICT: - TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname, place_holder=False, recursive=IMAGE_SEARCH) + TEXTURE_DICT[contextMaterial.name] = load_image( + texture_name, dirname, place_holder=False, recursive=IMAGE_SEARCH) new_chunk.bytes_read += read_str_len # plus one for the null character that gets removed elif new_chunk.ID == EDITKEYFRAME: pass - + elif new_chunk.ID == KFDATA_KFSEG: temp_data = file.read(struct.calcsize('I')) start = struct.unpack('<I', temp_data)[0] @@ -836,7 +844,8 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA context.scene.frame_end = stop # including these here means their EK_OB_NODE_HEADER are scanned - elif new_chunk.ID in {KFDATA_AMBIENT, KFDATA_CAMERA, KFDATA_OBJECT, KFDATA_TARGET, KFDATA_LIGHT, KFDATA_L_TARGET,}: # another object is being processed + # another object is being processed + elif new_chunk.ID in {KFDATA_AMBIENT, KFDATA_CAMERA, KFDATA_OBJECT, KFDATA_TARGET, KFDATA_LIGHT, KFDATA_L_TARGET, }: child = None elif new_chunk.ID == OBJECT_NODE_HDR: @@ -862,7 +871,8 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA object_name, read_str_len = read_string(file) if child.name == '$$$DUMMY': child.name = object_name - else: child.name += "." + object_name + else: + child.name += "." + object_name object_dictionary[object_name] = child new_chunk.bytes_read += read_str_len @@ -908,7 +918,8 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA rad, axis_x, axis_y, axis_z = struct.unpack("<4f", temp_data) new_chunk.bytes_read += SZ_4FLOAT if nframe == 0: - child.rotation_euler = mathutils.Quaternion((axis_x, axis_y, axis_z), -rad).to_euler() # why negative? + child.rotation_euler = mathutils.Quaternion( + (axis_x, axis_y, axis_z), -rad).to_euler() # why negative? elif KEYFRAME and new_chunk.ID == SCL_TRACK_TAG and child.type == 'MESH': # scale new_chunk.bytes_read += SZ_U_SHORT * 5 @@ -966,7 +977,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA new_chunk.bytes_read += SZ_FLOAT if nframe == 0: child.data.angle = math.radians(fov) - + elif new_chunk.ID == ROLL_TRACK_TAG and child.type == 'CAMERA': # Roll angle new_chunk.bytes_read += SZ_U_SHORT * 5 temp_data = file.read(SZ_U_SHORT * 5) @@ -992,7 +1003,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA temp_data = file.read(struct.calcsize(binary_format)) new_chunk.bytes_read += buffer_size - #update the previous chunk bytes read + # update the previous chunk bytes read previous_chunk.bytes_read += new_chunk.bytes_read # FINISHED LOOP @@ -1020,7 +1031,7 @@ def process_next_chunk(context, file, previous_chunk, importedObjects, IMAGE_SEA if ob.type == 'MESH': pivot = pivot_list[ind] pivot_matrix = object_matrix.get(ob, mathutils.Matrix()) # unlikely to fail - pivot_matrix = mathutils.Matrix.Translation(-1*pivot) + pivot_matrix = mathutils.Matrix.Translation(-1 * pivot) #pivot_matrix = mathutils.Matrix.Translation(pivot_matrix.to_3x3() @ -pivot) ob.data.transform(pivot_matrix) @@ -1032,11 +1043,11 @@ def load_3ds(filepath, KEYFRAME=True, APPLY_MATRIX=True, global_matrix=None): -# global SCN + # global SCN # XXX -# if BPyMessages.Error_NoFile(filepath): -# return + # if BPyMessages.Error_NoFile(filepath): + # return print("importing 3DS: %r..." % (filepath), end="") @@ -1050,7 +1061,7 @@ def load_3ds(filepath, file = open(filepath, 'rb') - #here we go! + # here we go! # print 'reading the first chunk' read_chunk(file, current_chunk) if current_chunk.ID != PRIMARY: @@ -1063,7 +1074,7 @@ def load_3ds(filepath, else: del BOUNDS_3DS[:] - ##IMAGE_SEARCH + # IMAGE_SEARCH # fixme, make unglobal, clear in case object_dictionary.clear()