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