X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=blender%2Fio_mspgl%2Fmesh.py;h=4403c6a01dd92a2d1b2eff36cf95cd4e9853a120;hb=736a076cf12aca02492eae6c77eff846bde0cdda;hp=609f89a1566ae3848efa9404cb0358e537528e09;hpb=907a2aced4b7d70af6be0625632ba373c458f197;p=libs%2Fgl.git diff --git a/blender/io_mspgl/mesh.py b/blender/io_mspgl/mesh.py index 609f89a1..4403c6a0 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 @@ -188,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 @@ -234,7 +239,7 @@ class Mesh: def transform(self, matrix): for v in self.vertices: - v.co = matrix*v.co + v.co = matrix@v.co def splice(self, other): if len(self.uv_layers)!=len(other.uv_layers): @@ -270,8 +275,7 @@ class Mesh: self.faces += other.faces for f in self.faces[offset:]: f.index += offset - f.loop_start += loop_offset - f.loop_indices = range(f.loop_start, f.loop_start+f.loop_total) + f.loop_indices = range(f.loop_indices.start+offset, f.loop_indices.stop+offset) if other.materials: f.material_index = material_map[f.material_index] @@ -388,10 +392,34 @@ class Mesh: for g in v.groups: g.group = group_index_map[g.group] + def apply_material_map(self, material_map): + for m in self.materials: + if m.name not in material_map.material_names: + raise Exception("Material map is not compatible with Mesh") + + if self.use_uv=='NONE': + return + + 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'] + 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'] array_uv_layers = [u for u in self.uv_layers if u.name in array_uv_layers] if array_uv_layers: @@ -735,7 +763,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") @@ -750,11 +778,12 @@ def create_mesh_from_object(context, obj, progress): if c.type=="MESH" and c.compound: objs.append((c, m*c.matrix_local)) + dg = context.evaluated_depsgraph_get() + mesh = None - bmeshes = [] for o, m in objs: - bmesh = o.to_mesh(context.scene, True, "PREVIEW") - bmeshes.append(bmesh) + eval_obj = o.evaluated_get(dg) + bmesh = eval_obj.to_mesh() # Object.to_mesh does not copy custom properties bmesh.winding_test = o.data.winding_test @@ -769,6 +798,10 @@ def create_mesh_from_object(context, obj, progress): me = Mesh(bmesh) me.transform(m) + for i, s in enumerate(eval_obj.material_slots): + if s.link=='OBJECT': + me.materials[i] = s.material + if mesh: mesh.splice(me) else: @@ -776,6 +809,9 @@ def create_mesh_from_object(context, obj, progress): 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) @@ -790,8 +826,6 @@ def create_mesh_from_object(context, obj, progress): # Discard the temporary Blender meshes after making sure there's no # references to the data mesh.drop_references() - for m in bmeshes: - bpy.data.meshes.remove(m) progress.pop_task()