diff --git a/src/operators/bake_to_id_map.py b/src/operators/bake_to_id_map.py index 5da24f8..a4462e7 100644 --- a/src/operators/bake_to_id_map.py +++ b/src/operators/bake_to_id_map.py @@ -27,7 +27,7 @@ class BakeToIDMapOperator(bpy.types.Operator): def paint_id_mask(self, context, props): source = get_source(props.source) - targets = source.get_targets(context) + targets = self.get_targets(context, source, props) if len(targets) < 1: return @@ -49,6 +49,35 @@ class BakeToIDMapOperator(bpy.types.Operator): colors.append(colorsys.hls_to_rgb(h, l, s)) target = get_target(props.target) - target.paint_targets(props, targets, colors) + self.paint_targets(props, target, targets, colors) if 'after_painting' in dir(source): - source.after_painting(context, props) \ No newline at end of file + source.after_painting(context, props) + + def get_targets(self, context, source, props): + if props.selection_mode == 'SINGLE': + return source.get_targets([context.active_object]) + + if props.selection_mode == 'MULTIPLE_COMBINED': + return source.get_targets(context.selected_objects) + + if props.selection_mode == 'MULTIPLE_SEPARATE': + result = [] + for obj in context.selected_objects: + if obj.type != 'MESH': + continue + + obj_targets = source.get_targets([obj]) + result.append(obj_targets) + + return result + + raise ValueError('Invalid selection_mode') + + def paint_targets(self, props, target, targets, colors): + if props.selection_mode == 'MULTIPLE_SEPARATE': + for targetList in targets: + target.paint_targets(props,targetList, colors) + + return + + target.paint_targets(props, targets, colors) \ No newline at end of file diff --git a/src/panels/panel.py b/src/panels/panel.py index 23a37d5..50f99e8 100644 --- a/src/panels/panel.py +++ b/src/panels/panel.py @@ -13,4 +13,19 @@ class BakeToIDMapPanel(bpy.types.Panel): layout.use_property_split = True layout.use_property_decorate = False # No animation. - self.layout.operator("object.bake_to_id_map", text="Bake") + props = context.scene.bake_to_id_props + + operator_row = layout.row() + operator_row.operator("object.bake_to_id_map", text="Bake") + operator_row.enabled = self.check_if_props_valid(context, props) + + layout.prop(props, "selection_mode") + + def check_if_props_valid(self, context, props): + if (props.selection_mode == "SINGLE" and context.active_object is None): + return False + + if (props.selection_mode != "SINGLE" and len(context.selected_objects) < 1): + return False + + return True \ No newline at end of file diff --git a/src/panels/panel_info.py b/src/panels/panel_info.py index 7ac9a0f..ebcfa70 100644 --- a/src/panels/panel_info.py +++ b/src/panels/panel_info.py @@ -19,5 +19,28 @@ class BakeToIDInfoPanel(bpy.types.Panel): source = get_source(props.source) - layout.label(text="Selected Object-Count: " + str(len(context.selected_objects))) - layout.label(text="Estimated ID-Count: " + str(source.estimate_ids(context, props))) \ No newline at end of file + if props.selection_mode != 'SINGLE': + layout.label(text="Selected Object-Count: " + str(len(context.selected_objects))) + layout.separator() + + if props.selection_mode == 'SINGLE': + layout.label(text="ID-Total: " + str(source.estimate_ids([context.active_object]))) + + if props.selection_mode == 'MULTIPLE_SEPARATE': + total = 0 + count = 0 + for obj in context.selected_objects: + if (obj.type != 'MESH'): + continue + + total += source.estimate_ids([obj]) + count += 1 + + layout.label(text="Estimated ID-Total: " + str(total)) + try: + layout.label(text="Estimated ID-Average: " + str(total / count)) + except ZeroDivisionError: + layout.label(text="Estimated ID-Average: 0") + + if props.selection_mode == 'MULTIPLE_COMBINED': + layout.label(text="ID-Total: " + str(source.estimate_ids(context.selected_objects))) \ No newline at end of file diff --git a/src/panels/panel_options.py b/src/panels/panel_options.py index 2d1445e..0042ba6 100644 --- a/src/panels/panel_options.py +++ b/src/panels/panel_options.py @@ -15,6 +15,8 @@ class BakeToIDOptionsPanel(bpy.types.Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. props = context.scene.bake_to_id_props diff --git a/src/properties/bake_to_id.py b/src/properties/bake_to_id.py index 30bfa5b..bab3b6d 100644 --- a/src/properties/bake_to_id.py +++ b/src/properties/bake_to_id.py @@ -5,11 +5,22 @@ from src.types import get_source_enum, get_targets_enum class BakeToIDProperties(PropertyGroup): + selection_mode: EnumProperty( + items=[ + ("SINGLE", "Only active element", "Only use the currently selected element", 0), + ("MULTIPLE_SEPARATE", "Use Selection, separate", "It performs the transfer for every selected element, but each get there own ids", 1), + ("MULTIPLE_COMBINED", "Use Selection, combined", "It performs the transfer for every selected element, combining the ids", 2) + ], + name="Selection Mode", + description="Specifies how the 3D View-Selection is gonna be used.", + default="MULTIPLE_SEPARATE" + ) + source: EnumProperty( items=get_source_enum(), name="Source", description="From where should the IDs be taken", - default = "MATERIAL_INDEX" + default="MATERIAL_INDEX" ) target: EnumProperty( diff --git a/src/types/sources/material_index.py b/src/types/sources/material_index.py index d7b1b5b..39be292 100644 --- a/src/types/sources/material_index.py +++ b/src/types/sources/material_index.py @@ -6,9 +6,9 @@ connected_properties = [ 'source_materials_remove_all' ] -def get_targets(context): +def get_targets(objects): targets = [] - for obj in context.selected_objects: + for obj in objects: if not obj.material_slots: continue mesh = obj.data @@ -33,9 +33,9 @@ def after_painting(context, props): for obj in context.selected_objects: obj.data.materials.clear() -def estimate_ids(context, props): +def estimate_ids(objects): count = 0 - for obj in context.selected_objects: + for obj in objects: count += len(obj.material_slots) return count diff --git a/src/types/sources/object.py b/src/types/sources/object.py index d7e07e0..7a94968 100644 --- a/src/types/sources/object.py +++ b/src/types/sources/object.py @@ -4,13 +4,13 @@ description = 'Uses the object id as basis for the ID mask.' connected_properties = [] -def get_targets(context): +def get_targets(objects): targets = [] - for obj in context.selected_objects: + for obj in objects: mesh = obj.data targets.append((mesh, mesh.polygons)) return targets -def estimate_ids(context, props): - return len(context.selected_objects) \ No newline at end of file +def estimate_ids(objects): + return len(objects) \ No newline at end of file