X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=blender%2Fio_mspgl%2Fmesh.py;h=91648d28e5b28b1ab6db369586b46d974b0c332e;hp=f357936275ae6d352a5c6ad983dccf4d809c4421;hb=aa1ef522b3b2bdde8f005878fed6668f52b8d949;hpb=ab60e3a21afcfc970004512044ae32fac5c2112e diff --git a/blender/io_mspgl/mesh.py b/blender/io_mspgl/mesh.py index f3579362..91648d28 100644 --- a/blender/io_mspgl/mesh.py +++ b/blender/io_mspgl/mesh.py @@ -1,6 +1,7 @@ import bpy import math import mathutils +import itertools def make_edge_key(i1, i2): return (min(i1, i2), max(i1, i2)) @@ -60,8 +61,8 @@ class Vertex: self.tan = None self.bino = None self.index = vertex.index - self.co = vertex.co - self.normal = vertex.normal + self.co = mathutils.Vector(vertex.co) + self.normal = mathutils.Vector(vertex.normal) self.flag = False self.edges = [] self.faces = [] @@ -147,7 +148,7 @@ class UvLayer: else: self._layer = arg self.name = arg.name - self.uvs = [d.uv for d in self.data] + self.uvs = [mathutils.Vector(d.uv) for d in self.data] self.unit = None self.hidden = False @@ -167,6 +168,7 @@ class UvLayer: class Mesh: def __init__(self, mesh): self._mesh = mesh + self.name = mesh.name self.winding_test = mesh.winding_test self.tbn_vecs = mesh.tbn_vecs @@ -187,17 +189,21 @@ class Mesh: self.uv_layers = [] else: self.uv_layers = [UvLayer(u) for u in mesh.uv_layers] - self.uv_layers = sorted([u for u in self.uv_layers if not u.hidden], key=(lambda u: (u.unit or 1000, u.name))) + + # Assign texture unit numbers to UV layers that lack one + missing_unit = [u for u in self.uv_layers if u.unit is None] + if missing_unit: + missing_unit = sorted(missing_unit, key=(lambda u: u.name)) + used_units = [u.unit for u in self.uv_layers if u.unit is not None] + for u, n in zip(missing_unit, (i for i in itertools.count() if i not in used_units)): + u.unit = n + + self.uv_layers = sorted(self.uv_layers, key=(lambda u: u.unit)) if self.use_uv=='UNIT0': self.uv_layers = [self.uv_layers[0]] - - # Assign texture unit numbers to UV layers that lack one - next_unit = max((u.unit+1 for u in self.uv_layers if u.unit is not None), default=0) - for u in self.uv_layers: - if not u.unit: - u.unit = next_unit - next_unit += 1 + if self.uv_layers[0].unit!=0: + self.uv_layers = [] # Rewrite links between elements to point to cloned data, or create links # where they don't exist @@ -387,23 +393,31 @@ class Mesh: for g in v.groups: g.group = group_index_map[g.group] - def prepare_uv(self, obj, progress): - if obj.material_tex and self.use_uv!='NONE': - layer = UvLayer("material_tex") + def apply_material_map(self, material_map): + for m in self.materials: + if m not in material_map.materials: + raise Exception("Material map is not compatible with Mesh") - if self.use_uv=='UNIT0': - self.uv_layers = [layer] - layer.unit = 0 - else: - self.uv_layers.append(layer) - layer.unit = max((u.unit+1 for u in self.uv_layers if u.unit is not None), default=0) + if self.use_uv=='NONE': + return - layer.uvs = [None]*len(self.loops) - for f in self.faces: - uv = mathutils.Vector(((f.material_index+0.5)/len(self.materials), 0.5)) - for i in f.loop_indices: - layer.uvs[i] = uv + layer = UvLayer("material_map") + if self.use_uv=='UNIT0': + self.uv_layers = [layer] + layer.unit = 0 + else: + self.uv_layers.append(layer) + used_units = [u.unit for u in self.uv_layers] + layer.unit = next(i for i in itertools.count() if i not in used_units) + self.uv_layers.sort(key=lambda u: u.unit) + layer.uvs = [(0.0, 0.0)]*len(self.loops) + for f in self.faces: + uv = material_map.get_material_uv(self.materials[f.material_index]) + for i in f.loop_indices: + layer.uvs[i] = uv + + def prepare_uv(self, progress): # Form a list of UV layers referenced by materials with the array atlas # property set array_uv_layers = [t.uv_layer for m in self.materials if m.array_atlas for t in m.texture_slots if t and t.texture_coords=='UV'] @@ -750,7 +764,7 @@ class Mesh: self._mesh = None -def create_mesh_from_object(context, obj, progress): +def create_mesh_from_object(context, obj, progress, *, material_map=None): if obj.type!="MESH": raise Exception("Object is not a mesh") @@ -789,6 +803,11 @@ def create_mesh_from_object(context, obj, progress): else: mesh = me + mesh.name = obj.data.name + + if material_map: + mesh.apply_material_map(material_map) + progress.set_task("Triangulating", 0.2, 0.3) mesh.prepare_triangles(progress) progress.set_task("Smoothing", 0.3, 0.5) @@ -796,7 +815,7 @@ def create_mesh_from_object(context, obj, progress): progress.set_task("Vertex groups", 0.5, 0.6) mesh.prepare_vertex_groups(obj) progress.set_task("Preparing UVs", 0.6, 0.8) - mesh.prepare_uv(obj, progress) + mesh.prepare_uv(progress) progress.set_task("Render sequence", 0.8, 1.0) mesh.prepare_sequence(progress)