From a3760ee0536ab8abdb26c4d4d5adef228006b048 Mon Sep 17 00:00:00 2001 From: Sebastian Sille Date: Sun, 26 Mar 2023 18:31:09 +0200 Subject: [PATCH 1/3] io_scene_3ds: Updated version changed version Signed-off-by: Sebastian Sille --- io_scene_3ds/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_scene_3ds/__init__.py b/io_scene_3ds/__init__.py index 3912ac1..9430ca4 100644 --- a/io_scene_3ds/__init__.py +++ b/io_scene_3ds/__init__.py @@ -32,7 +32,7 @@ import bpy bl_info = { "name": "Autodesk 3DS format", "author": "Bob Holcomb, Campbell Barton, Andreas Atteneder, Sebastian Schrand", - "version": (2, 2, 0), + "version": (2, 3, 1), "blender": (3, 0, 0), "location": "File > Import", "description": "Import 3DS, meshes, uvs, materials, textures, " -- 2.30.2 From 3a11dae2437a3dfb7866d578e17548b2ca799763 Mon Sep 17 00:00:00 2001 From: Sebastian Sille Date: Sun, 26 Mar 2023 19:05:22 +0200 Subject: [PATCH 2/3] io_scene_3ds: Added face and point flags added point array chunk exporting sharp edge flags some cleanup Signed-off-by: Sebastian Sille --- io_scene_3ds/export_3ds.py | 57 ++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/io_scene_3ds/export_3ds.py b/io_scene_3ds/export_3ds.py index 71c55fc..e7dda76 100644 --- a/io_scene_3ds/export_3ds.py +++ b/io_scene_3ds/export_3ds.py @@ -108,6 +108,7 @@ 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 @@ -327,10 +328,11 @@ class _3ds_rgb_color(object): class _3ds_face(object): """Class representing a face for a 3ds file.""" - __slots__ = ("vindex", ) + __slots__ = ("vindex", "flag") - def __init__(self, vindex): + def __init__(self, vindex, flag): self.vindex = vindex + self.flag = flag def get_size(self): return 4 * SZ_SHORT @@ -339,11 +341,11 @@ class _3ds_face(object): # catch this problem def write(self, file): - # The last zero is only used by 3d studio - file.write(struct.pack("<4H", self.vindex[0], self.vindex[1], self.vindex[2], 0)) + # The last short is used for face flags + file.write(struct.pack("<4H", self.vindex[0], self.vindex[1], self.vindex[2], self.flag)) def __str__(self): - return "[%d %d %d]" % (self.vindex[0], self.vindex[1], self.vindex[2]) + return "[%d %d %d %d]" % (self.vindex[0], self.vindex[1], self.vindex[2], self.flag) class _3ds_array(object): @@ -763,17 +765,17 @@ def make_material_chunk(material, image): class tri_wrapper(object): """Class representing a triangle. - Used when converting faces to triangles""" - __slots__ = "vertex_index", "ma", "image", "faceuvs", "offset", "group" + __slots__ = "vertex_index", "ma", "image", "faceuvs", "offset", "flag", "group" - def __init__(self, vindex=(0, 0, 0), ma=None, image=None, faceuvs=None, group=0): + def __init__(self, vindex=(0, 0, 0), ma=None, image=None, faceuvs=None, flag=0, group=0): self.vertex_index = vindex self.ma = ma self.image = image self.faceuvs = faceuvs self.offset = [0, 0, 0] # offset indices + self.flag = flag self.group = group @@ -789,7 +791,7 @@ def extract_triangles(mesh): img = None for i, face in enumerate(mesh.loop_triangles): f_v = face.vertices - + v1, v2, v3 = f_v[0], f_v[1], f_v[2] uf = mesh.uv_layers.active.data if do_uv else None if do_uv: @@ -798,13 +800,37 @@ def extract_triangles(mesh): img = get_uv_image(ma) if uf else None if img is not None: img = img.name + uv1, uv2, uv3 = f_uv[0], f_uv[1], f_uv[2] + + """Flag 0x1 sets CA edge visible, Flag 0x2 sets BC edge visible, Flag 0x4 sets AB edge visible + Flag 0x8 indicates a U axis texture wrap and Flag 0x10 indicates a V axis texture wrap + In Blender we use the edge CA, BC, and AB flags for sharp edges flags""" + a_b = mesh.edges[mesh.loops[face.loops[0]].edge_index] + b_c = mesh.edges[mesh.loops[face.loops[1]].edge_index] + c_a = mesh.edges[mesh.loops[face.loops[2]].edge_index] + + if v3 == 0: + a_b, b_c, c_a = c_a, a_b, b_c + + faceflag = 0 + if c_a.use_edge_sharp: + faceflag = faceflag + 0x1 + if b_c.use_edge_sharp: + faceflag = faceflag + 0x2 + if a_b.use_edge_sharp: + faceflag = faceflag + 0x4 smoothgroup = polygroup[face.polygon_index] - if len(f_v) == 3: - new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img) + if len(f_v)==3: + if v3 == 0: + v1, v2, v3 = v3, v1, v2 + if do_uv: + uv1, uv2, uv3 = uv3, uv1, uv2 + new_tri = tri_wrapper((v1, v2, v3), face.material_index, img) if (do_uv): - new_tri.faceuvs = uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2]) + new_tri.faceuvs = uv_key(uv1), uv_key(uv2), uv_key(uv3) + new_tri.flag = faceflag new_tri.group = smoothgroup if face.use_smooth else 0 tri_list.append(new_tri) @@ -813,7 +839,6 @@ def extract_triangles(mesh): def remove_face_uv(verts, tri_list): """Remove face UV coordinates from a list of triangles. - Since 3ds files only support one pair of uv coordinates for each vertex, face uv coordinates need to be converted to vertex uv coordinates. That means that vertices need to be duplicated when there are multiple uv coordinates per vertex.""" @@ -896,8 +921,7 @@ def make_faces_chunk(tri_list, mesh, materialDict): # Gather materials used in this mesh - mat/image pairs unique_mats = {} for i, tri in enumerate(tri_list): - - face_list.add(_3ds_face(tri.vertex_index)) + face_list.add(_3ds_face(tri.vertex_index, tri.flag)) if materials: ma = materials[tri.ma] @@ -927,7 +951,6 @@ def make_faces_chunk(tri_list, mesh, materialDict): face_chunk.add_subchunk(obj_material_chunk) else: - obj_material_faces = [] obj_material_names = [] for m in materials: @@ -937,7 +960,7 @@ def make_faces_chunk(tri_list, mesh, materialDict): n_materials = len(obj_material_names) for i, tri in enumerate(tri_list): - face_list.add(_3ds_face(tri.vertex_index)) + face_list.add(_3ds_face(tri.vertex_index, tri.flag)) if (tri.ma < n_materials): obj_material_faces[tri.ma].add(_3ds_ushort(i)) -- 2.30.2 From cce6fce4bc4e44377e5fbb8ebf1c208be546153d Mon Sep 17 00:00:00 2001 From: Sebastian Sille Date: Sun, 26 Mar 2023 19:15:20 +0200 Subject: [PATCH 3/3] io_scene_3ds: Added face and point flags fixed edge flag loop to match with point loop some cleanup Signed-off-by: Sebastian Sille --- io_scene_3ds/import_3ds.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/io_scene_3ds/import_3ds.py b/io_scene_3ds/import_3ds.py index d333618..833c43a 100644 --- a/io_scene_3ds/import_3ds.py +++ b/io_scene_3ds/import_3ds.py @@ -400,15 +400,6 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, IMAGE_SE for fidx in faces: bmesh.polygons[fidx].material_index = mat_idx -# if uv_faces and img: -# for fidx in faces: -# bmesh.polygons[fidx].material_index = mat_idx -# # TODO: How to restore this? -# # uv_faces[fidx].image = img -# else: -# for fidx in faces: -# bmesh.polygons[fidx].material_index = mat_idx - if uv_faces: uvl = bmesh.uv_layers.active.data[:] for fidx, pl in enumerate(bmesh.polygons): @@ -433,13 +424,16 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, IMAGE_SE imported_objects.append(ob) if myContextMesh_flag: - # Bit 0 (0x1) sets edge CA visible, Bit 1 (0x2) sets edge BC visible and Bit 2 (0x4) sets the edge AB visible + # Bit 0 (0x1) sets edge CA visible, Bit 1 (0x2) sets edge BC visible and Bit 2 (0x4) sets edge AB visible # In Blender we use sharp edges for those flags - for lt, tri in enumerate(bmesh.loop_triangles): - faceflag = myContextMesh_flag[lt] - edge_ca = bmesh.edges[bmesh.loops[tri.loops[2]].edge_index] - edge_bc = bmesh.edges[bmesh.loops[tri.loops[1]].edge_index] - edge_ab = bmesh.edges[bmesh.loops[tri.loops[0]].edge_index] + for f, pl in enumerate(bmesh.polygons): + face = myContextMesh_facels[f] + faceflag = myContextMesh_flag[f] + edge_ab = bmesh.edges[bmesh.loops[pl.loop_start].edge_index] + edge_bc = bmesh.edges[bmesh.loops[pl.loop_start + 1].edge_index] + edge_ca = bmesh.edges[bmesh.loops[pl.loop_start + 2].edge_index] + if face[2] == 0: + edge_ab, edge_bc, edge_ca = edge_ca, edge_ab, edge_bc if faceflag == 1: edge_ca.use_edge_sharp = True elif faceflag == 2: @@ -455,8 +449,10 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, IMAGE_SE elif faceflag == 6: edge_bc.use_edge_sharp = True edge_ab.use_edge_sharp = True - elif faceflag >= 7: - pass + elif faceflag == 7: + edge_bc.use_edge_sharp = True + edge_ab.use_edge_sharp = True + edge_ca.use_edge_sharp = True if myContextMesh_smooth: for f, pl in enumerate(bmesh.polygons): -- 2.30.2