- Added parameterized tests for image edit replacement to ensure alpha mode preservation. - Refactored existing tests to utilize new image editing methods and improve clarity. - Introduced new tests for image target functionality, ensuring proper handling of shared textures and context. - Updated various tests to validate alpha mode handling across different scenarios. - Improved undo/redo functionality in image operators to maintain state consistency. - Added support for texture node actions, enhancing integration with Blender's node system. - Ensured that image properties are preserved during operations and that invalid contexts are handled gracefully.
88 lines
2.9 KiB
Python
88 lines
2.9 KiB
Python
import bpy
|
|
|
|
from ..properties import BEN2_MODEL_KEY
|
|
from ..runtime import JobOperatorBase
|
|
from ..common.ai import (
|
|
require_background_input_path,
|
|
invoke_ai_setup_if_needed,
|
|
production_device,
|
|
require_environment,
|
|
require_model,
|
|
)
|
|
|
|
from ..common.image import cleanup_image_input
|
|
from ..common.image_target import ImageEditTarget, image_edit_owner
|
|
|
|
|
|
_HIDDEN = {"HIDDEN", "SKIP_SAVE"}
|
|
|
|
|
|
class RemoveImageBackground(bpy.types.Operator):
|
|
bl_idname = "anyimage.remove_image_background"
|
|
bl_label = "Remove Background"
|
|
bl_description = "Remove the image background with BEN2"
|
|
bl_options = {"REGISTER"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
from ..runtime import runtime
|
|
|
|
return image_edit_owner(context) is not None and not runtime.server_busy()
|
|
|
|
def invoke(self, _context, _event):
|
|
setup_result = invoke_ai_setup_if_needed()
|
|
if setup_result is not None:
|
|
return setup_result
|
|
return self.execute(_context)
|
|
|
|
def execute(self, _context):
|
|
result = bpy.ops.anyimage.run_background_removal()
|
|
if "CANCELLED" not in result:
|
|
return {"FINISHED"}
|
|
return {"CANCELLED"}
|
|
|
|
|
|
class RunBackgroundRemoval(JobOperatorBase, bpy.types.Operator):
|
|
bl_idname = "anyimage.run_background_removal"
|
|
bl_label = "Run Background Removal"
|
|
job_type = "remove-background"
|
|
starting_message = "Starting image background removal"
|
|
|
|
input_path: bpy.props.StringProperty(options=_HIDDEN)
|
|
delete_input: bpy.props.BoolProperty(default=False, options=_HIDDEN)
|
|
|
|
def execute(self, context):
|
|
try:
|
|
self._image_target = ImageEditTarget.capture(context)
|
|
source_path, self.delete_input = self._image_target.prepare(context)
|
|
except RuntimeError as error:
|
|
self.report({"ERROR"}, str(error))
|
|
return {"CANCELLED"}
|
|
self.input_path = str(source_path)
|
|
result = super().execute(context)
|
|
if "CANCELLED" in result:
|
|
self.cleanup()
|
|
return result
|
|
|
|
def request(self, context):
|
|
require_environment()
|
|
require_model(BEN2_MODEL_KEY)
|
|
settings = context.scene.anyimage_settings
|
|
return {
|
|
"input": str(require_background_input_path(self.input_path)),
|
|
"model": BEN2_MODEL_KEY,
|
|
"device": production_device().lower(),
|
|
"video_frames": settings.video_frames,
|
|
"start_frame": self._image_target.start_frame,
|
|
}
|
|
|
|
def response(self, _context, result):
|
|
self._image_target.apply(result.directory)
|
|
if "FINISHED" not in bpy.ops.ed.undo_push(message="Remove Background"):
|
|
raise RuntimeError("Unable to create the Remove Background Undo step")
|
|
return "Image background is removed"
|
|
|
|
def cleanup(self):
|
|
cleanup_image_input(self.input_path, self.delete_input)
|
|
self._image_target = None
|