3
11

io_scene_3ds: Added face and point flags #11

Merged
Sebastian Sille merged 3 commits from :main into main 2023-03-26 19:29:34 +02:00
Showing only changes of commit 3a11dae243 - Show all commits

View File

@ -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 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))