diff options
author | nutti <nutti.metro@gmail.com> | 2020-10-23 14:18:09 +0300 |
---|---|---|
committer | nutti <nutti.metro@gmail.com> | 2020-10-23 14:18:09 +0300 |
commit | 40e34a8bbb30c6a4ddc73aa11e92c6bd2095eb80 (patch) | |
tree | 5c46bb7af6381407596cab713f21dede0aa65f27 /magic_uv/op/uv_inspection.py | |
parent | ec3c96a37e2daddd5ca9f652c4b018b00a3acc53 (diff) |
Magic UV: Release v6.4
* Support multiple objects editing mode
* Add snap to point/edge features
* Fix bugs
Diffstat (limited to 'magic_uv/op/uv_inspection.py')
-rw-r--r-- | magic_uv/op/uv_inspection.py | 292 |
1 files changed, 151 insertions, 141 deletions
diff --git a/magic_uv/op/uv_inspection.py b/magic_uv/op/uv_inspection.py index 8aae181e..49525b98 100644 --- a/magic_uv/op/uv_inspection.py +++ b/magic_uv/op/uv_inspection.py @@ -20,8 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "6.3" -__date__ = "10 Aug 2020" +__version__ = "6.4" +__date__ = "23 Oct 2020" import random from math import fabs @@ -42,23 +42,18 @@ else: def _is_valid_context(context): - obj = context.object + objs = common.get_uv_editable_objects(context) + if not objs: + return False # only edit mode is allowed to execute - if obj is None: - return False - if obj.type != 'MESH': - return False if context.object.mode != 'EDIT': return False # 'IMAGE_EDITOR' and 'VIEW_3D' space is allowed to execute. # If 'View_3D' space is not allowed, you can't find option in Tool-Shelf # after the execution - for space in context.area.spaces: - if (space.type == 'IMAGE_EDITOR') or (space.type == 'VIEW_3D'): - break - else: + if not common.is_valid_space(context, ['IMAGE_EDITOR', 'VIEW_3D']): return False return True @@ -67,17 +62,13 @@ def _is_valid_context(context): def _update_uvinsp_info(context): sc = context.scene props = sc.muv_props.uv_inspection + objs = common.get_uv_editable_objects(context) bm_list = [] uv_layer_list = [] faces_list = [] - for o in bpy.data.objects: - if not compat.get_object_select(o): - continue - if o.type != 'MESH': - continue - - bm = bmesh.from_edit_mesh(o.data) + for obj in objs: + bm = bmesh.from_edit_mesh(obj.data) if common.check_version(2, 73, 0) >= 0: bm.faces.ensure_lookup_table() uv_layer = bm.loops.layers.uv.verify() @@ -359,137 +350,156 @@ class MUV_OT_UVInspection_PaintUVIsland(bpy.types.Operator): return None def execute(self, context): - obj = context.active_object + selected_objs_orig = [o for o in bpy.data.objects + if compat.get_object_select(o)] + active_obj_orig = compat.get_active_object(context) + + objs = common.get_uv_editable_objects(context) mode_orig = context.object.mode override_context = self._get_override_context(context) if override_context is None: self.report({'WARNING'}, "More than one 'VIEW_3D' area must exist") return {'CANCELLED'} - # Setup material of drawing target. - target_image = self._get_or_new_image( - "MagicUV_PaintUVIsland", 4096, 4096) - target_mtrl = self._get_or_new_material("MagicUV_PaintUVMaterial") - if compat.check_version(2, 80, 0) >= 0: - target_mtrl.use_nodes = True - output_node = target_mtrl.node_tree.nodes["Material Output"] - nodes_to_remove = [n for n in target_mtrl.node_tree.nodes - if n != output_node] - for n in nodes_to_remove: - target_mtrl.node_tree.nodes.remove(n) - texture_node = \ - target_mtrl.node_tree.nodes.new("ShaderNodeTexImage") - texture_node.image = target_image - target_mtrl.node_tree.links.new(output_node.inputs["Surface"], - texture_node.outputs["Color"]) - obj.data.use_paint_mask = True - - # Apply material to object (all faces). - found = False - for mtrl_idx, mtrl_slot in enumerate(obj.material_slots): - if mtrl_slot.material == target_mtrl: - found = True - break - if not found: - bpy.ops.object.material_slot_add() - mtrl_idx = len(obj.material_slots) - 1 - obj.material_slots[mtrl_idx].material = target_mtrl - bpy.ops.object.mode_set(mode='EDIT') - bm = bmesh.from_edit_mesh(obj.data) - bm.faces.ensure_lookup_table() - for f in bm.faces: - f.select = True - bmesh.update_edit_mesh(obj.data) - obj.active_material_index = mtrl_idx - obj.active_material = target_mtrl - bpy.ops.object.material_slot_assign() - else: - target_tex_slot = target_mtrl.texture_slots.add() - target_tex = self._get_or_new_texture("MagicUV_PaintUVTexture") - target_tex_slot.texture = target_tex - obj.data.use_paint_mask = True - - # Apply material to object (all faces). - found = False - for mtrl_idx, mtrl_slot in enumerate(obj.material_slots): - if mtrl_slot.material == target_mtrl: - found = True - break - if not found: - bpy.ops.object.material_slot_add() - mtrl_idx = len(obj.material_slots) - 1 - obj.material_slots[mtrl_idx].material = target_mtrl - bpy.ops.object.mode_set(mode='EDIT') - bm = bmesh.from_edit_mesh(obj.data) - bm.faces.ensure_lookup_table() - for f in bm.faces: - f.select = True - bmesh.update_edit_mesh(obj.data) - obj.active_material_index = mtrl_idx - obj.active_material = target_mtrl - bpy.ops.object.material_slot_assign() - - # Update active image in Image Editor. - _, _, space = common.get_space( - 'IMAGE_EDITOR', 'WINDOW', 'IMAGE_EDITOR') - if space is None: - return {'CANCELLED'} - space.image = target_image - - # Analyze island to make map between face and paint color. - islands = common.get_island_info_from_bmesh(bm) - color_to_faces = [] - for isl in islands: - color = self._create_unique_color([c[0] for c in color_to_faces]) - if color is None: - self.report({'WARNING'}, - "Failed to create color. Please try again") - return {'CANCELLED'} - indices = [f["face"].index for f in isl["faces"]] - color_to_faces.append((color, indices)) - - for cf in color_to_faces: - # Update selection information. - bpy.ops.object.mode_set(mode='EDIT') - bm = bmesh.from_edit_mesh(obj.data) - bm.faces.ensure_lookup_table() - for f in bm.faces: - f.select = False - for fidx in cf[1]: - bm.faces[fidx].select = True - bmesh.update_edit_mesh(obj.data) - bpy.ops.object.mode_set(mode='OBJECT') - - # Update brush color. - bpy.data.brushes["Fill"].color = cf[0] - - # Paint. - bpy.ops.object.mode_set(mode='TEXTURE_PAINT') + for i, obj in enumerate(objs): + # Select/Active only one object to paint. + for o in objs: + compat.set_object_select(o, False) + compat.set_object_select(obj, True) + compat.set_active_object(obj) + + # Setup material of drawing target. + target_image = self._get_or_new_image( + "MagicUV_PaintUVIsland_{}".format(i), 4096, 4096) + target_mtrl = self._get_or_new_material( + "MagicUV_PaintUVMaterial_{}".format(i)) if compat.check_version(2, 80, 0) >= 0: - bpy.ops.paint.brush_select(override_context, image_tool='FILL') + target_mtrl.use_nodes = True + output_node = target_mtrl.node_tree.nodes["Material Output"] + nodes_to_remove = [n for n in target_mtrl.node_tree.nodes + if n != output_node] + for n in nodes_to_remove: + target_mtrl.node_tree.nodes.remove(n) + texture_node = \ + target_mtrl.node_tree.nodes.new("ShaderNodeTexImage") + texture_node.image = target_image + target_mtrl.node_tree.links.new(output_node.inputs["Surface"], + texture_node.outputs["Color"]) + obj.data.use_paint_mask = True + + # Apply material to object (all faces). + found = False + for mtrl_idx, mtrl_slot in enumerate(obj.material_slots): + if mtrl_slot.material == target_mtrl: + found = True + break + if not found: + bpy.ops.object.material_slot_add() + mtrl_idx = len(obj.material_slots) - 1 + obj.material_slots[mtrl_idx].material = target_mtrl + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + bm.faces.ensure_lookup_table() + for f in bm.faces: + f.select = True + bmesh.update_edit_mesh(obj.data) + obj.active_material_index = mtrl_idx + obj.active_material = target_mtrl + bpy.ops.object.material_slot_assign() else: - paint_settings = \ - bpy.data.scenes['Scene'].tool_settings.image_paint - paint_mode_orig = paint_settings.mode - paint_canvas_orig = paint_settings.canvas - paint_settings.mode = 'IMAGE' - paint_settings.canvas = target_image - bpy.ops.paint.brush_select(override_context, - texture_paint_tool='FILL') - bpy.ops.paint.image_paint(override_context, stroke=[{ - "name": "", - "location": (0, 0, 0), - "mouse": (0, 0), - "size": 0, - "pressure": 0, - "pen_flip": False, - "time": 0, - "is_start": False - }]) - - if compat.check_version(2, 80, 0) < 0: - paint_settings.mode = paint_mode_orig - paint_settings.canvas = paint_canvas_orig + target_tex_slot = target_mtrl.texture_slots.add() + target_tex = self._get_or_new_texture( + "MagicUV_PaintUVTexture_{}".format(i)) + target_tex_slot.texture = target_tex + obj.data.use_paint_mask = True + + # Apply material to object (all faces). + found = False + for mtrl_idx, mtrl_slot in enumerate(obj.material_slots): + if mtrl_slot.material == target_mtrl: + found = True + break + if not found: + bpy.ops.object.material_slot_add() + mtrl_idx = len(obj.material_slots) - 1 + obj.material_slots[mtrl_idx].material = target_mtrl + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + bm.faces.ensure_lookup_table() + for f in bm.faces: + f.select = True + bmesh.update_edit_mesh(obj.data) + obj.active_material_index = mtrl_idx + obj.active_material = target_mtrl + bpy.ops.object.material_slot_assign() + + # Update active image in Image Editor. + _, _, space = common.get_space( + 'IMAGE_EDITOR', 'WINDOW', 'IMAGE_EDITOR') + if space is None: + return {'CANCELLED'} + space.image = target_image + + # Analyze island to make map between face and paint color. + islands = common.get_island_info_from_bmesh(bm) + color_to_faces = [] + for isl in islands: + color = self._create_unique_color( + [c[0] for c in color_to_faces]) + if color is None: + self.report({'WARNING'}, + "Failed to create color. Please try again") + return {'CANCELLED'} + indices = [f["face"].index for f in isl["faces"]] + color_to_faces.append((color, indices)) + + for cf in color_to_faces: + # Update selection information. + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + bm.faces.ensure_lookup_table() + for f in bm.faces: + f.select = False + for fidx in cf[1]: + bm.faces[fidx].select = True + bmesh.update_edit_mesh(obj.data) + bpy.ops.object.mode_set(mode='OBJECT') + + # Update brush color. + bpy.data.brushes["Fill"].color = cf[0] + + # Paint. + bpy.ops.object.mode_set(mode='TEXTURE_PAINT') + if compat.check_version(2, 80, 0) >= 0: + bpy.ops.paint.brush_select(override_context, + image_tool='FILL') + else: + paint_settings = \ + bpy.data.scenes['Scene'].tool_settings.image_paint + paint_mode_orig = paint_settings.mode + paint_canvas_orig = paint_settings.canvas + paint_settings.mode = 'IMAGE' + paint_settings.canvas = target_image + bpy.ops.paint.brush_select(override_context, + texture_paint_tool='FILL') + bpy.ops.paint.image_paint(override_context, stroke=[{ + "name": "", + "location": (0, 0, 0), + "mouse": (0, 0), + "size": 0, + "pressure": 0, + "pen_flip": False, + "time": 0, + "is_start": False + }]) + + if compat.check_version(2, 80, 0) < 0: + paint_settings.mode = paint_mode_orig + paint_settings.canvas = paint_canvas_orig + + for obj in selected_objs_orig: + compat.set_object_select(obj, True) + compat.set_active_object(active_obj_orig) bpy.ops.object.mode_set(mode=mode_orig) |