io_scene_3ds: Added face and point flags #11
@ -32,7 +32,7 @@ import bpy
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Autodesk 3DS format",
|
"name": "Autodesk 3DS format",
|
||||||
"author": "Bob Holcomb, Campbell Barton, Andreas Atteneder, Sebastian Schrand",
|
"author": "Bob Holcomb, Campbell Barton, Andreas Atteneder, Sebastian Schrand",
|
||||||
"version": (2, 2, 0),
|
"version": (2, 3, 1),
|
||||||
"blender": (3, 0, 0),
|
"blender": (3, 0, 0),
|
||||||
"location": "File > Import",
|
"location": "File > Import",
|
||||||
"description": "Import 3DS, meshes, uvs, materials, textures, "
|
"description": "Import 3DS, meshes, uvs, materials, textures, "
|
||||||
|
@ -108,6 +108,7 @@ 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_VERTICES = 0x4110 # The objects vertices
|
||||||
|
OBJECT_VERTFLAGS = 0x4111 # The objects vertex flags
|
||||||
OBJECT_FACES = 0x4120 # The objects faces
|
OBJECT_FACES = 0x4120 # The objects faces
|
||||||
OBJECT_MATERIAL = 0x4130 # This is found if the object has a material, either texture map or color
|
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_UV = 0x4140 # The UV texture coordinates
|
||||||
@ -327,10 +328,11 @@ class _3ds_rgb_color(object):
|
|||||||
|
|
||||||
class _3ds_face(object):
|
class _3ds_face(object):
|
||||||
"""Class representing a face for a 3ds file."""
|
"""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.vindex = vindex
|
||||||
|
self.flag = flag
|
||||||
|
|
||||||
def get_size(self):
|
def get_size(self):
|
||||||
return 4 * SZ_SHORT
|
return 4 * SZ_SHORT
|
||||||
@ -339,11 +341,11 @@ class _3ds_face(object):
|
|||||||
# catch this problem
|
# catch this problem
|
||||||
|
|
||||||
def write(self, file):
|
def write(self, file):
|
||||||
# The last zero is only used by 3d studio
|
# The last short is used for face flags
|
||||||
file.write(struct.pack("<4H", self.vindex[0], self.vindex[1], self.vindex[2], 0))
|
file.write(struct.pack("<4H", self.vindex[0], self.vindex[1], self.vindex[2], self.flag))
|
||||||
|
|
||||||
def __str__(self):
|
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):
|
class _3ds_array(object):
|
||||||
@ -763,17 +765,17 @@ def make_material_chunk(material, image):
|
|||||||
|
|
||||||
class tri_wrapper(object):
|
class tri_wrapper(object):
|
||||||
"""Class representing a triangle.
|
"""Class representing a triangle.
|
||||||
|
|
||||||
Used when converting faces to triangles"""
|
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.vertex_index = vindex
|
||||||
self.ma = ma
|
self.ma = ma
|
||||||
self.image = image
|
self.image = image
|
||||||
self.faceuvs = faceuvs
|
self.faceuvs = faceuvs
|
||||||
self.offset = [0, 0, 0] # offset indices
|
self.offset = [0, 0, 0] # offset indices
|
||||||
|
self.flag = flag
|
||||||
self.group = group
|
self.group = group
|
||||||
|
|
||||||
|
|
||||||
@ -789,7 +791,7 @@ def extract_triangles(mesh):
|
|||||||
img = None
|
img = None
|
||||||
for i, face in enumerate(mesh.loop_triangles):
|
for i, face in enumerate(mesh.loop_triangles):
|
||||||
f_v = face.vertices
|
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
|
uf = mesh.uv_layers.active.data if do_uv else None
|
||||||
|
|
||||||
if do_uv:
|
if do_uv:
|
||||||
@ -798,13 +800,37 @@ def extract_triangles(mesh):
|
|||||||
img = get_uv_image(ma) if uf else None
|
img = get_uv_image(ma) if uf else None
|
||||||
if img is not None:
|
if img is not None:
|
||||||
img = img.name
|
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]
|
smoothgroup = polygroup[face.polygon_index]
|
||||||
|
|
||||||
if len(f_v)==3:
|
if len(f_v)==3:
|
||||||
new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img)
|
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):
|
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
|
new_tri.group = smoothgroup if face.use_smooth else 0
|
||||||
tri_list.append(new_tri)
|
tri_list.append(new_tri)
|
||||||
|
|
||||||
@ -813,7 +839,6 @@ def extract_triangles(mesh):
|
|||||||
|
|
||||||
def remove_face_uv(verts, tri_list):
|
def remove_face_uv(verts, tri_list):
|
||||||
"""Remove face UV coordinates from a list of triangles.
|
"""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
|
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
|
need to be converted to vertex uv coordinates. That means that vertices need to be duplicated when
|
||||||
there are multiple uv coordinates per vertex."""
|
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
|
# Gather materials used in this mesh - mat/image pairs
|
||||||
unique_mats = {}
|
unique_mats = {}
|
||||||
for i, tri in enumerate(tri_list):
|
for i, tri in enumerate(tri_list):
|
||||||
|
face_list.add(_3ds_face(tri.vertex_index, tri.flag))
|
||||||
face_list.add(_3ds_face(tri.vertex_index))
|
|
||||||
|
|
||||||
if materials:
|
if materials:
|
||||||
ma = materials[tri.ma]
|
ma = materials[tri.ma]
|
||||||
@ -927,7 +951,6 @@ def make_faces_chunk(tri_list, mesh, materialDict):
|
|||||||
face_chunk.add_subchunk(obj_material_chunk)
|
face_chunk.add_subchunk(obj_material_chunk)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
obj_material_faces = []
|
obj_material_faces = []
|
||||||
obj_material_names = []
|
obj_material_names = []
|
||||||
for m in materials:
|
for m in materials:
|
||||||
@ -937,7 +960,7 @@ def make_faces_chunk(tri_list, mesh, materialDict):
|
|||||||
n_materials = len(obj_material_names)
|
n_materials = len(obj_material_names)
|
||||||
|
|
||||||
for i, tri in enumerate(tri_list):
|
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):
|
if (tri.ma < n_materials):
|
||||||
obj_material_faces[tri.ma].add(_3ds_ushort(i))
|
obj_material_faces[tri.ma].add(_3ds_ushort(i))
|
||||||
|
|
||||||
|
@ -400,15 +400,6 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, IMAGE_SE
|
|||||||
for fidx in faces:
|
for fidx in faces:
|
||||||
bmesh.polygons[fidx].material_index = mat_idx
|
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:
|
if uv_faces:
|
||||||
uvl = bmesh.uv_layers.active.data[:]
|
uvl = bmesh.uv_layers.active.data[:]
|
||||||
for fidx, pl in enumerate(bmesh.polygons):
|
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)
|
imported_objects.append(ob)
|
||||||
|
|
||||||
if myContextMesh_flag:
|
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
|
# In Blender we use sharp edges for those flags
|
||||||
for lt, tri in enumerate(bmesh.loop_triangles):
|
for f, pl in enumerate(bmesh.polygons):
|
||||||
faceflag = myContextMesh_flag[lt]
|
face = myContextMesh_facels[f]
|
||||||
edge_ca = bmesh.edges[bmesh.loops[tri.loops[2]].edge_index]
|
faceflag = myContextMesh_flag[f]
|
||||||
edge_bc = bmesh.edges[bmesh.loops[tri.loops[1]].edge_index]
|
edge_ab = bmesh.edges[bmesh.loops[pl.loop_start].edge_index]
|
||||||
edge_ab = bmesh.edges[bmesh.loops[tri.loops[0]].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:
|
if faceflag == 1:
|
||||||
edge_ca.use_edge_sharp = True
|
edge_ca.use_edge_sharp = True
|
||||||
elif faceflag == 2:
|
elif faceflag == 2:
|
||||||
@ -455,8 +449,10 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, IMAGE_SE
|
|||||||
elif faceflag == 6:
|
elif faceflag == 6:
|
||||||
edge_bc.use_edge_sharp = True
|
edge_bc.use_edge_sharp = True
|
||||||
edge_ab.use_edge_sharp = True
|
edge_ab.use_edge_sharp = True
|
||||||
elif faceflag >= 7:
|
elif faceflag == 7:
|
||||||
pass
|
edge_bc.use_edge_sharp = True
|
||||||
|
edge_ab.use_edge_sharp = True
|
||||||
|
edge_ca.use_edge_sharp = True
|
||||||
|
|
||||||
if myContextMesh_smooth:
|
if myContextMesh_smooth:
|
||||||
for f, pl in enumerate(bmesh.polygons):
|
for f, pl in enumerate(bmesh.polygons):
|
||||||
|
Reference in New Issue
Block a user