diff --git a/io_scene_3ds/__init__.py b/io_scene_3ds/__init__.py deleted file mode 100644 index 9430ca4..0000000 --- a/io_scene_3ds/__init__.py +++ /dev/null @@ -1,175 +0,0 @@ -# ##### 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 ##### - -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", - "version": (2, 3, 1), - "blender": (3, 0, 0), - "location": "File > Import", - "description": "Import 3DS, meshes, uvs, materials, textures, " - "cameras & lamps", - "warning": "Images must be in file folder", - "doc_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/Import-Export/Autodesk_3DS", - "category": "Import-Export", -} - -if "bpy" in locals(): - import importlib - if "import_3ds" in locals(): - importlib.reload(import_3ds) - if "export_3ds" in locals(): - importlib.reload(export_3ds) - - -@orientation_helper(axis_forward='Y', axis_up='Z') -class Import3DS(bpy.types.Operator, ImportHelper): - """Import from 3DS file format (.3ds)""" - bl_idname = "import_scene.autodesk_3ds" - bl_label = 'Import 3DS' - bl_options = {'UNDO'} - - filename_ext = ".3ds" - 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, - ) - use_image_search: BoolProperty( - 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, - ) - - read_keyframe: bpy.props.BoolProperty( - name="Read Keyframe", - description="Read the keyframe data", - default=True, - ) - - def execute(self, context): - from . import import_3ds - - keywords = self.as_keywords(ignore=("axis_forward", - "axis_up", - "filter_glob", - )) - - global_matrix = axis_conversion(from_forward=self.axis_forward, - from_up=self.axis_up, - ).to_4x4() - keywords["global_matrix"] = global_matrix - - return import_3ds.load(self, context, **keywords) - - -@orientation_helper(axis_forward='Y', axis_up='Z') -class Export3DS(bpy.types.Operator, ExportHelper): - """Export to 3DS file format (.3ds)""" - bl_idname = "export_scene.autodesk_3ds" - bl_label = 'Export 3DS' - - filename_ext = ".3ds" - filter_glob: StringProperty( - default="*.3ds", - options={'HIDDEN'}, - ) - - use_selection: BoolProperty( - name="Selection Only", - description="Export selected objects only", - default=False, - ) - - def execute(self, context): - from . import export_3ds - - keywords = self.as_keywords(ignore=("axis_forward", - "axis_up", - "filter_glob", - "check_existing", - )) - global_matrix = axis_conversion(to_forward=self.axis_forward, - to_up=self.axis_up, - ).to_4x4() - keywords["global_matrix"] = global_matrix - - return export_3ds.save(self, context, **keywords) - - -# Add to a menu -def menu_func_export(self, context): - self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)") - - -def menu_func_import(self, context): - self.layout.operator(Import3DS.bl_idname, text="3D Studio (.3ds)") - - -def register(): - bpy.utils.register_class(Import3DS) - bpy.utils.register_class(Export3DS) - - bpy.types.TOPBAR_MT_file_import.append(menu_func_import) - bpy.types.TOPBAR_MT_file_export.append(menu_func_export) - - -def unregister(): - bpy.utils.unregister_class(Import3DS) - bpy.utils.unregister_class(Export3DS) - - bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) - bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) - -# NOTES: -# why add 1 extra vertex? and remove it when done? - -# "Answer - eekadoodle - would need to re-order UV's without this since face -# order isnt always what we give blender, BMesh will solve :D" -# -# 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 deleted file mode 100644 index 5505322..0000000 --- a/io_scene_3ds/export_3ds.py +++ /dev/null @@ -1,1454 +0,0 @@ -# ##### 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: Campbell Barton, Bob Holcomb, Richard Lärkäng, Damien McGinnes, Mark Stijnman, Sebastian Sille - -""" -Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information -from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. -""" - -import bpy -import math -import struct -import mathutils -import bpy_extras -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 -PRIMARY = 0x4D4D - -# ------ 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 -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 -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 -MATSPECULAR = 0xA030 # Specular color of the object/material -MATSHINESS = 0xA040 # Specular intensity of the object/material (percent) -MATSHIN2 = 0xA041 # Reflection of the object/material (percent) -MATSHIN3 = 0xA042 # metallic/mirror of the object/material (percent) -MATTRANS = 0xA050 # Transparency value (100-OpacityValue) (percent) -MATSELFILPCT = 0xA084 # Self illumination strength (percent) -MATSHADING = 0xA100 # Material shading method - -MAT_DIFFUSEMAP = 0xA200 # This is a header for a new diffuse texture -MAT_SPECMAP = 0xA204 # head for specularity map -MAT_OPACMAP = 0xA210 # head for opacity map -MAT_REFLMAP = 0xA220 # head for reflect map -MAT_BUMPMAP = 0xA230 # head for normal map -MAT_BUMP_PERCENT = 0xA252 # Normalmap strength (percent) -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 -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 -MAT_MAP_USCALE = 0xA354 # U axis scaling -MAT_MAP_VSCALE = 0xA356 # V axis scaling -MAT_MAP_UOFFSET = 0xA358 # U axis offset -MAT_MAP_VOFFSET = 0xA35A # V axis offset -MAT_MAP_ANG = 0xA35C # UV rotation around the z-axis in rad -MAP_COL1 = 0xA360 # Tint Color1 -MAP_COL2 = 0xA362 # Tint Color2 -MAP_RCOL = 0xA364 # Red tint -MAP_GCOL = 0xA366 # Green tint -MAP_BCOL = 0xA368 # Blue tint - -RGB = 0x0010 # RGB float -RGB1 = 0x0011 # RGB Color1 -RGB2 = 0x0012 # RGB Color2 -PCT = 0x0030 # Percent chunk -MASTERSCALE = 0x0100 # Master scale factor - -# >------ 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 -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 -OBJECT_CAM_RANGES = 0x4720 # The camera range values - -# >------ sub defines of OBJECT_MESH -OBJECT_VERTICES = 0x4110 # The objects vertices -OBJECT_VERTFLAGS = 0x4111 # The objects vertex flags -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_SMOOTH = 0x4150 # The objects smooth groups -OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix - -# >------ sub defines of KFDATA -KFDATA_KFHDR = 0xB00A -KFDATA_KFSEG = 0xB008 -KFDATA_KFCURTIME = 0xB009 -KFDATA_OBJECT_NODE_TAG = 0xB002 - -# >------ sub defines of OBJECT_NODE_TAG -OBJECT_NODE_ID = 0xB030 -OBJECT_NODE_HDR = 0xB010 -OBJECT_PIVOT = 0xB013 -OBJECT_INSTANCE_NAME = 0xB011 -POS_TRACK_TAG = 0xB020 -ROT_TRACK_TAG = 0xB021 -SCL_TRACK_TAG = 0xB022 - - -# So 3ds max can open files, limit names to 12 in length -# this is very annoying for filenames! -name_unique = [] # stores str, ascii only -name_mapping = {} # stores {orig: byte} mapping - - -def sane_name(name): - name_fixed = name_mapping.get(name) - if name_fixed is not None: - return name_fixed - - # strip non ascii chars - new_name_clean = new_name = name.encode("ASCII", "replace").decode("ASCII")[:12] - i = 0 - - while new_name in name_unique: - new_name = new_name_clean + ".%.3d" % i - i += 1 - - # note, appending the 'str' version. - name_unique.append(new_name) - name_mapping[name] = new_name = new_name.encode("ASCII", "replace") - return new_name - - -def uv_key(uv): - return round(uv[0], 6), round(uv[1], 6) - - -# size defines: -SZ_SHORT = 2 -SZ_INT = 4 -SZ_FLOAT = 4 - - -class _3ds_ushort(object): - """Class representing a short (2-byte integer) for a 3ds file. - *** This looks like an unsigned short H is unsigned from the struct docs - Cam***""" - __slots__ = ("value", ) - - def __init__(self, val=0): - self.value = val - - def get_size(self): - return SZ_SHORT - - def write(self, file): - file.write(struct.pack("= ma_ls_len: - ma_index = f.material_index = 0 - ma = ma_ls[ma_index] - ma_name = None if ma is None else ma.name - # else there already set to none - - img = get_uv_image(ma) - img_name = None if img is None else img.name - - materialDict.setdefault((ma_name, img_name), (ma, img)) - - else: - for ma in ma_ls: - if ma: # material may be None so check its not. - materialDict.setdefault((ma.name, None), (ma, None)) - - # Why 0 Why! - for f in data.polygons: - if f.material_index >= ma_ls_len: - f.material_index = 0 - - # ob_derived_eval.to_mesh_clear() - - #if free: - # free_derived_objects(ob) - - # Make material chunks for all materials used in the meshes: - for ma_image in materialDict.values(): - object_info.add_subchunk(make_material_chunk(ma_image[0], ma_image[1])) - - # Give all objects a unique ID and build a dictionary from object name to object id: - translation = {} # collect translation for transformation matrix - #name_to_id = {} - for ob, data, matrix in mesh_objects: - translation[ob.name] = ob.location - #name_to_id[ob.name]= len(name_to_id) - """ - #for ob in empty_objects: - # name_to_id[ob.name]= len(name_to_id) - """ - - # Create object chunks for all meshes: - i = 0 - for ob, mesh, matrix in mesh_objects: - # create a new object chunk - object_chunk = _3ds_chunk(OBJECT) - - # set the object name - object_chunk.add_variable("name", _3ds_string(sane_name(ob.name))) - - # make a mesh chunk out of the mesh: - object_chunk.add_subchunk(make_mesh_chunk(ob, mesh, matrix, materialDict, translation)) - - # ensure the mesh has no over sized arrays - # skip ones that do!, otherwise we cant write since the array size wont - # fit into USHORT. - if object_chunk.validate(): - object_info.add_subchunk(object_chunk) - else: - operator.report({'WARNING'}, "Object %r can't be written into a 3DS file") - - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - # make a kf object node for the object: - kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) - ''' - - # if not blender_mesh.users: - # bpy.data.meshes.remove(blender_mesh) - #blender_mesh.vertices = None - - i += i - - # Create chunks for all empties: - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - for ob in empty_objects: - # Empties only require a kf object node: - kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) - pass - ''' - - # Create light object chunks - for ob in light_objects: - object_chunk = _3ds_chunk(OBJECT) - light_chunk = _3ds_chunk(OBJECT_LIGHT) - color_float_chunk = _3ds_chunk(RGB) - energy_factor = _3ds_chunk(LIGHT_MULTIPLIER) - 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)) - 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]) - 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_subchunk(spot_roll_chunk) - light_chunk.add_subchunk(spotlight_chunk) - - # Add light to object info - object_chunk.add_subchunk(light_chunk) - object_info.add_subchunk(object_chunk) - - # Create camera object chunks - 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]) - 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("lens", _3ds_float(ob.data.lens)) - object_chunk.add_subchunk(camera_chunk) - object_info.add_subchunk(object_chunk) - - # Add main object info chunk to primary chunk: - primary.add_subchunk(object_info) - - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - # Add main keyframe data chunk to primary chunk: - primary.add_subchunk(kfdata) - ''' - - # At this point, the chunk hierarchy is completely built. - - # Check the size: - primary.get_size() - # Open the file for writing: - file = open(filepath, 'wb') - - # Recursively write the chunks to file: - primary.write(file) - - # Close the file: - file.close() - - # Clear name mapping vars, could make locals too - del name_unique[:] - name_mapping.clear() - - # Debugging only: report the exporting time: - # Blender.Window.WaitCursor(0) - print("3ds export time: %.2f" % (time.time() - duration)) - - # Debugging only: dump the chunk hierarchy: - # primary.dump() - - return {'FINISHED'} diff --git a/io_scene_3ds/import_3ds.py b/io_scene_3ds/import_3ds.py deleted file mode 100644 index 833c43a..0000000 --- a/io_scene_3ds/import_3ds.py +++ /dev/null @@ -1,1271 +0,0 @@ -# ##### 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, Sebastian Sille -# Campbell Barton, Mario Lapin, Dominique Lorre, Andreas Atteneder - -import os -import time -import struct -import bpy -import math -import mathutils -from bpy_extras.node_shader_utils import PrincipledBSDFWrapper - -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 - -# ------ Data Chunks, used for various attributes -PERCENTAGE_SHORT = 0x30 -PERCENTAGE_FLOAT = 0x31 - -# ------ 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 # Roughness of the object/material (percent) -MAT_SHIN2 = 0xA041 # Shininess of the object/material (percent) -MAT_SHIN3 = 0xA042 # Reflection of the object/material (percent) -MAT_TRANSPARENCY = 0xA050 # Transparency value of material (percent) -MAT_SELF_ILLUM = 0xA080 # Self Illumination value of material -MAT_SELF_ILPCT = 0xA084 # Self illumination strength (percent) -MAT_WIRE = 0xA085 # Only render's wireframe -MAT_SHADING = 0xA100 # Material shading method - -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_BUMP_PERCENT = 0xA252 # Normalmap strength (percent) -MAT_TEX2_MAP = 0xA33A # This is a header for a secondary texture -MAT_SHIN_MAP = 0xA33C # This is a header for a new roughness map -MAT_SELFI_MAP = 0xA33D # This is a header for a new emission map -MAT_MAP_FILEPATH = 0xA300 # This holds the file name of the texture - -MAT_MAP_TILING = 0xa351 # 2nd bit (from LSB) is mirror UV flag -MAT_MAP_USCALE = 0xA354 # U axis scaling -MAT_MAP_VSCALE = 0xA356 # V axis scaling -MAT_MAP_UOFFSET = 0xA358 # U axis offset -MAT_MAP_VOFFSET = 0xA35A # V axis offset -MAT_MAP_ANG = 0xA35C # UV rotation around the z-axis in rad -MAT_MAP_COL1 = 0xA360 # Map Color1 -MAT_MAP_COL2 = 0xA362 # Map Color2 -MAT_MAP_RCOL = 0xA364 # Red mapping -MAT_MAP_GCOL = 0xA366 # Green mapping -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 -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. -OBJECT_LIGHT_OFF = 0x4620 # The light off. -OBJECT_LIGHT_ATTENUATE = 0x4625 -OBJECT_LIGHT_RAYSHADE = 0x4627 -OBJECT_LIGHT_SHADOWED = 0x4630 -OBJECT_LIGHT_LOCAL_SHADOW = 0x4640 -OBJECT_LIGHT_LOCAL_SHADOW2 = 0x4641 -OBJECT_LIGHT_SEE_CONE = 0x4650 -OBJECT_LIGHT_SPOT_RECTANGULAR = 0x4651 -OBJECT_LIGHT_SPOT_OVERSHOOT = 0x4652 -OBJECT_LIGHT_SPOT_PROJECTOR = 0x4653 -OBJECT_LIGHT_EXCLUDE = 0x4654 -OBJECT_LIGHT_RANGE = 0x4655 -OBJECT_LIGHT_ROLL = 0x4656 -OBJECT_LIGHT_SPOT_ASPECT = 0x4657 -OBJECT_LIGHT_RAY_BIAS = 0x4658 -OBJECT_LIGHT_INNER_RANGE = 0x4659 -OBJECT_LIGHT_OUTER_RANGE = 0x465A -OBJECT_LIGHT_MULTIPLIER = 0x465B -OBJECT_LIGHT_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_VERTFLAGS = 0x4111 # The objects vertex flags -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_SMOOTH = 0x4150 # The Object smooth groups -OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix - -# >------ sub defines of EDITKEYFRAME -KFDATA_AMBIENT = 0xB001 -KFDATA_OBJECT = 0xB002 -KFDATA_CAMERA = 0xB003 -KFDATA_TARGET = 0xB004 -KFDATA_LIGHT = 0xB005 -KFDATA_L_TARGET = 0xB006 -KFDATA_SPOTLIGHT = 0xB007 -KFDATA_KFSEG = 0xB008 -# KFDATA_CURTIME = 0xB009 -# KFDATA_KFHDR = 0xB00A -# >------ sub defines of KEYFRAME_NODE -OBJECT_NODE_HDR = 0xB010 -OBJECT_INSTANCE_NAME = 0xB011 -# OBJECT_PRESCALE = 0xB012 -OBJECT_PIVOT = 0xB013 -# OBJECT_BOUNDBOX = 0xB014 -# MORPH_SMOOTH = 0xB015 -POS_TRACK_TAG = 0xB020 -ROT_TRACK_TAG = 0xB021 -SCL_TRACK_TAG = 0xB022 -FOV_TRACK_TAG = 0xB023 -ROLL_TRACK_TAG = 0xB024 -COL_TRACK_TAG = 0xB025 -# MORPH_TRACK_TAG = 0xB026 -# HOTSPOT_TRACK_TAG = 0xB027 -# FALLOFF_TRACK_TAG = 0xB028 -# HIDE_TRACK_TAG = 0xB029 -# OBJECT_NODE_ID = 0xB030 - -ROOT_OBJECT = 0xFFFF - -global scn -scn = None - -object_dictionary = {} -object_matrix = {} - - -class Chunk: - __slots__ = ( - "ID", - "length", - "bytes_read", - ) - # we don't read in the bytes_read, we compute that - binary_format = " 0: - bmesh.polygons[f].use_smooth = True - - if contextMatrix: - ob.matrix_local = contextMatrix - object_matrix[ob] = contextMatrix.copy() - - # a spare chunk - new_chunk = Chunk() - temp_chunk = Chunk() - - CreateBlenderObject = False - CreateLightObject = False - CreateCameraObject = False - - def read_float_color(temp_chunk): - temp_data = file.read(SZ_3FLOAT) - temp_chunk.bytes_read += SZ_3FLOAT - return [float(col) for col in struct.unpack('<3f', temp_data)] - - def read_float(temp_chunk): - temp_data = file.read(SZ_FLOAT) - temp_chunk.bytes_read += SZ_FLOAT - return struct.unpack(' 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: - process_next_chunk(context, file, new_chunk, imported_objects, IMAGE_SEARCH, KEYFRAME) - - # 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( - context, - contextMesh_vertls, - contextMesh_facels, - contextMesh_flag, - contextMeshMaterials, - contextMesh_smooth, - ) - contextMesh_vertls = [] - contextMesh_facels = [] - contextMeshMaterials = [] - contextMesh_flag = None - contextMesh_smooth = None - contextMeshUV = None - # Reset matrix - contextMatrix = 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: - contextMaterial = bpy.data.materials.new('Material') - contextWrapper = PrincipledBSDFWrapper(contextMaterial, is_readonly=False, use_nodes=False) - - elif new_chunk.ID == MAT_NAME: - material_name, read_str_len = read_string(file) - - # 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 - - elif new_chunk.ID == MAT_AMBIENT: - read_chunk(file, temp_chunk) - # only available color is emission color - if temp_chunk.ID == MAT_FLOAT_COLOR: - contextMaterial.line_color[:3] = read_float_color(temp_chunk) - elif temp_chunk.ID == MAT_24BIT_COLOR: - contextMaterial.line_color[:3] = read_byte_color(temp_chunk) - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read += temp_chunk.bytes_read - - elif new_chunk.ID == MAT_DIFFUSE: - read_chunk(file, temp_chunk) - if temp_chunk.ID == MAT_FLOAT_COLOR: - contextMaterial.diffuse_color[:3] = read_float_color(temp_chunk) - elif temp_chunk.ID == MAT_24BIT_COLOR: - contextMaterial.diffuse_color[:3] = read_byte_color(temp_chunk) - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read += temp_chunk.bytes_read - - elif new_chunk.ID == MAT_SPECULAR: - read_chunk(file, temp_chunk) - # Specular color is available - if temp_chunk.ID == MAT_FLOAT_COLOR: - contextMaterial.specular_color = read_float_color(temp_chunk) - elif temp_chunk.ID == MAT_24BIT_COLOR: - contextMaterial.specular_color = read_byte_color(temp_chunk) - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read += temp_chunk.bytes_read - - elif new_chunk.ID == MAT_SHINESS: - read_chunk(file, temp_chunk) - if temp_chunk.ID == PERCENTAGE_SHORT: - temp_data = file.read(SZ_U_SHORT) - temp_chunk.bytes_read += SZ_U_SHORT - contextMaterial.roughness = 1 - (float(struct.unpack('= 2: - contextWrapper.use_nodes = True - contextWrapper.emission_color = contextMaterial.line_color[:3] - contextWrapper.emission_strength = contextMaterial.line_priority / 100 - 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] - contextWrapper.use_nodes = False - if shading >= 3: - contextWrapper.use_nodes = True - - 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: - contextMaterial.blend_method = 'BLEND' - read_texture(new_chunk, temp_chunk, "Opacity", "ALPHA") - - elif new_chunk.ID == MAT_REFLECTION_MAP: - read_texture(new_chunk, temp_chunk, "Reflect", "METALLIC") - - elif new_chunk.ID == MAT_BUMP_MAP: - read_texture(new_chunk, temp_chunk, "Bump", "NORMAL") - - elif new_chunk.ID == MAT_BUMP_PERCENT: - read_chunk(file, temp_chunk) - if temp_chunk.ID == PERCENTAGE_SHORT: - temp_data = file.read(SZ_U_SHORT) - temp_chunk.bytes_read += SZ_U_SHORT - contextWrapper.normalmap_strength = (float(struct.unpack(' value: - axis_min[axis] = value - if axis_max[axis] < value: - axis_max[axis] = value - - # Scale objects - max_axis = max(axis_max[0] - axis_min[0], - axis_max[1] - axis_min[1], - axis_max[2] - axis_min[2]) - scale = 1.0 - - while global_clamp_size < max_axis * scale: - scale = scale / 10.0 - - scale_mat = mathutils.Matrix.Scale(scale, 4) - - for obj in imported_objects: - if obj.parent is None: - obj.matrix_world = scale_mat @ obj.matrix_world - - # Select all new objects. - print(" done in %.4f sec." % (time.time() - time1)) - file.close() - - -def load(operator, - context, - filepath="", - constrain_size=0.0, - use_image_search=True, - read_keyframe=True, - use_apply_transform=True, - global_matrix=None, - ): - - load_3ds(filepath, - context, - IMPORT_CONSTRAIN_BOUNDS=constrain_size, - IMAGE_SEARCH=use_image_search, - KEYFRAME=read_keyframe, - APPLY_MATRIX=use_apply_transform, - global_matrix=global_matrix, - ) - - return {'FINISHED'}