diff --git a/DUV_MatAssign.py b/DUV_MatAssign.py index 3fc2cac..25a16ef 100644 --- a/DUV_MatAssign.py +++ b/DUV_MatAssign.py @@ -2,58 +2,58 @@ import bmesh class DREAMUV_OT_mat_assign(bpy.types.Operator): - """Assigns the material from the active face to the selected faces.""" + """Clones the material from the active face to the target faces.""" bl_idname = "view3d.dreamuv_matassign" - bl_label = "3D View Assign Material" + bl_label = "3D View Clone Material" bl_options = {"UNDO"} def execute(self, context): - # To-do: Make it work across objects. - ob = bpy.context.object - mesh = ob.data - bm = bmesh.from_edit_mesh(mesh) - bm.faces.ensure_lookup_table() - - uv_layer = bm.loops.layers.uv.active + objs = bpy.context.selected_objects + active_obj = bpy.context.active_object facecounter = 0 + selection = {} + + # I haven't found a way to differentiate between multiple active faces in multi-object editing. + # For now the "source" object has to be selected last. + for obj in objs: + bm = bmesh.from_edit_mesh(obj.data) + bm.faces.ensure_lookup_table() + + selected_faces = [] + for f in bm.faces: + if f.select: + facecounter += 1 + if f is bm.faces.active and obj is active_obj: + # Get source material. + slot_len = len(obj.material_slots) + if f.material_index < 0 or f.material_index >= slot_len: + self.report({'INFO'}, "object has no materials, aborting") + return {'FINISHED'} + + material = obj.material_slots[f.material_index].material + if material is None: + self.report({'INFO'}, "Active face has no material, aborting") + return {'FINISHED'} + + else: selected_faces.append(f) + + if len(selected_faces) > 0: + selection[obj] = selected_faces - selected_faces=[] - active_face = bm.faces.active - - # Ensure that at least 1 face is selected. - for f in bm.faces: - if f.select: - facecounter += 1 if facecounter < 2: self.report({'INFO'}, "only one face selected, aborting") return {'FINISHED'} - # Save the remaining selected faces. - for f in bm.faces: - if f.select: - if f is not bm.faces.active: - selected_faces.append(f) - # Not sure what the point of this is. - else: - f.select=False - - # Try to get the material being applied to the face. - slot_len = len(ob.material_slots) - if active_face.material_index < 0 or active_face.material_index >= slot_len: - self.report({'INFO'}, "object has no materials, aborting") - return {'FINISHED'} - - material = ob.material_slots[active_face.material_index].material - if material is None: - self.report({'INFO'}, "face has no material, aborting") - return {'FINISHED'} + # This creates a lot of duplicate materials. They can be cleaned up in post, + # but it would be nice if we merged here if possible. + # Should also check if the material already exists. + for obj in selection: + print(obj) + obj.data.materials.append(material) + for f in selection[obj]: + f.material_index = len(obj.data.materials) - 1 - # Sets the selected faces' materials to that of the active face. - # This is stupid and creates a lot of clone materials. - for f in selected_faces: - ob.data.materials.append(material) - f.material_index = len(ob.data.materials) - 1 + bmesh.update_edit_mesh(obj.data) - bmesh.update_edit_mesh(ob.data) return {'FINISHED'} \ No newline at end of file diff --git a/__init__.py b/__init__.py index 159394a..451b291 100644 --- a/__init__.py +++ b/__init__.py @@ -27,8 +27,8 @@ from . import DUV_UVUnwrap from . import DUV_UVInset from . import DUV_UVTrim -from . import DUV_MatAssign from . import DUV_UVTexelDensity +from . import DUV_MatAssign import importlib if 'bpy' in locals(): @@ -47,8 +47,8 @@ importlib.reload(DUV_UVUnwrap) importlib.reload(DUV_UVInset) importlib.reload(DUV_UVTrim) - importlib.reload(DUV_MatAssign) importlib.reload(DUV_UVTexelDensity) + importlib.reload(DUV_MatAssign) class DUVUVToolsPreferences(bpy.types.AddonPreferences): bl_idname = __name__ @@ -208,7 +208,7 @@ def draw(self, context): box.enabled = False col = box.column(align=True) col.label(text="Material Tools:") - col.operator("view3d.dreamuv_matassign", text="Transfer Material", icon="OUTLINER_OB_LATTICE") + col.operator("view3d.dreamuv_matassign", text="Transfer Material", icon="MATERIAL") col.separator() box = layout.box()