Skip to content

Commit

Permalink
code fmt and fix stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
KarryCharon committed Nov 29, 2024
1 parent 219b342 commit c1ca1e6
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 39 deletions.
3 changes: 2 additions & 1 deletion SDNode/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from .tree import rtnode_reg, rtnode_unreg
from .nodegroup import nodegroup_reg, nodegroup_unreg
from .operators import ops_register, ops_unregister
from .manager import TaskManager, Task, FakeServer
from .custom_support import crystools_monitor
try:
from . import aiprompt
from . import node_process
except Exception as e:
import traceback
traceback.print_exc()
traceback.print_exc()
18 changes: 16 additions & 2 deletions SDNode/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ def draw_prop_with_link(layout, self, prop, swsock, swdisp=False, row=True, pre=
return layout


hack_nodes_num = [0]


def setwidth(self: NodeBase, w, count=1):
if get_pref().preview_image_size_type == "DEFAULT":
def delegate(self: NodeBase):
Expand All @@ -119,7 +122,7 @@ def delegate(self: NodeBase):
sw = w
w *= count

def delegate(self, w, fpis):
def delegate(self: NodeBase, w, fpis):
"""
可能会因为 width 访问导致crash, 可以先清理Timer
"""
Expand All @@ -128,6 +131,12 @@ def delegate(self, w, fpis):
self.bl_width_min = 32
if self.width == w and not fpis:
return
# 避免删除所有节点时导致blender崩溃
if len(self.get_tree().nodes) != hack_nodes_num[0]:
hack_nodes_num[0] = len(self.get_tree().nodes)
Timer.clear()
return
hack_nodes_num[0] = len(self.get_tree().nodes)
self.width = w
if self.bl_width_max < w or fpis:
self.bl_width_max = w
Expand Down Expand Up @@ -310,6 +319,7 @@ def load(s, self: NodeBase, data, with_id=True):
size = data.get("size", [200, 200])
properties = data.get("properties", {})
self.sdn_hide = properties.get("sdn_hide", False)
self.label = properties.get("label", "")
color = data.get("bgcolor", None)
if color:
self.color = hex2rgb(color)
Expand Down Expand Up @@ -463,6 +473,8 @@ def dump(s, self: NodeBase, selected_only=False):
"properties": {"sdn_hide": self.sdn_hide, },
"widgets_values": widgets_values
}
if self.label:
cfg["properties"]["label"] = self.label
if self.use_custom_color:
color = rgb2hex(*self.color)
cfg["bgcolor"] = color
Expand Down Expand Up @@ -1462,7 +1474,7 @@ def f(img_src, img):
img_src.source = "FILE"
if img_src.packed_file:
img_src.unpack(method="REMOVE")
img_src.alpha_mode = 'CHANNEL_PACKED' # For painting masks from inside Blender
img_src.alpha_mode = 'CHANNEL_PACKED' # For painting masks from inside Blender
img_src.reload()
Timer.put((f, image, img))
post_fn = partial(__post_fn__, self, mode=self.mode, image=self.image)
Expand Down Expand Up @@ -2834,6 +2846,8 @@ def dump(s, self: SDNGroup, selected_only=False):
"properties": {"sdn_hide": self.sdn_hide, },
"widgets_values": widgets_values
}
if self.label:
cfg["properties"]["label"] = self.label
if self.use_custom_color:
color = rgb2hex(*self.color)
cfg["bgcolor"] = color
Expand Down
8 changes: 4 additions & 4 deletions SDNode/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ def run(self) -> bool:
pidpath = Path(__file__).parent / "pid"
if pidpath.exists():
self.force_kill(pidpath.read_text())
pidpath.unlink()
pidpath.unlink(missing_ok=True)

pref = get_pref()
model_path = pref.model_path
Expand Down Expand Up @@ -669,7 +669,7 @@ def run(self) -> bool:
t = t.replace("FORCE_LOG = False", f"FORCE_LOG = {get_pref().force_log}")
Path(model_path).joinpath("custom_nodes", file.name, cup_py.name).write_text(t, encoding="utf-8")
if old_cup_py.exists():
Path(model_path).joinpath("custom_nodes", cup_py.name).unlink()
Path(model_path).joinpath("custom_nodes", cup_py.name).unlink(missing_ok=True)
except Exception as e:
# 可能会拷贝失败(权限问题)
...
Expand Down Expand Up @@ -703,7 +703,7 @@ def close(self):
pidpath = Path(__file__).parent / "pid"
if pidpath.exists():
self.force_kill(pidpath.read_text())
pidpath.unlink()
pidpath.unlink(missing_ok=True)

if self.child:
self.child.kill()
Expand All @@ -720,7 +720,7 @@ def wait_connect(self) -> bool:
update_screen()
import requests
try:
if requests.get(f"{self.get_url()}/object_info", proxies={"http": None, "https": None}, timeout=1).status_code == 200:
if requests.get(f"{self.get_url()}/object_info", proxies={"http": None, "https": None}, timeout=5).status_code == 200:
get_pref().preview_method = get_pref().preview_method
return True
except requests.exceptions.ConnectionError:
Expand Down
4 changes: 2 additions & 2 deletions SDNode/rt_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def update_deps(self, depsgraph):
elif t in {Object, Mesh, Collection}:
self.push_status(t.__name__)
break
else:
print(f"{t.__name__} {update.id.name} changed")
# else:
# print(f"{t.__name__} {update.id.name} changed")

def push_status(self, name):
while not self.status.empty():
Expand Down
68 changes: 40 additions & 28 deletions ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ def invoke(self, context, event: bpy.types.Event):
wm = bpy.context.window_manager
self.alt = event.alt
self.select_nodes = []
self.init_pos = context.space_data.cursor_location.copy()
self.init_pos = (0, 0)
if hasattr(context.space_data, "cursor_location"):
self.init_pos = context.space_data.cursor_location.copy()

if self.action == "Submit" and not TaskManager.is_launched():
return wm.invoke_props_dialog(self, width=200)
if self.action in {"Load", "Del"}:
Expand Down Expand Up @@ -244,6 +247,7 @@ def find_frames(path):
# logger.debug(f"F {frame}: {fnode.image}")
else:
logger.debug(_T("Frame Task <{}> Added!").format(frame))

def pre(pre_img_map: dict):
for fnode, fpath in pre_img_map.items():
try:
Expand Down Expand Up @@ -884,22 +888,23 @@ def menu_sync_stencil_image(self: bpy.types.Menu, context: bpy.types.Context):
bpy.types.VIEW3D_PT_tools_brush_settings.append(menu_sync_stencil_image)
# bpy.types.VIEW3D_PT_tools_brush_display.append(menu_sync_stencil_image)


def sdn_get_image(node: bpy.types.Node):
if node.bl_idname in ('PreviewImage', '预览') and len(node.prev) > 0: # '预览' "Preview" Blender-side node
if node.bl_idname in ('PreviewImage', '预览') and len(node.prev) > 0: # '预览' "Preview" Blender-side node
return node.prev[0].image

if node.bl_idname == '输入图像': # "Input Image" Blender-side node
if node.bl_idname == '输入图像': # "Input Image" Blender-side node
return node.prev

if node.bl_idname == '存储' and node.mode == 'ToImage': # "Save" Blender-side node
if node.bl_idname == '存储' and node.mode == 'ToImage': # "Save" Blender-side node
return node.image

image = None

if node.bl_idname == 'SaveImage' or (node.bl_idname == '存储' and node.mode == 'Save'):
path = Path(node.output_dir)
prefix = node.filename_prefix
file_re = re.compile(f'{prefix}_([0-9]+)') # Should the _ at the end be included?
file_re = re.compile(f'{prefix}_([0-9]+)') # Should the _ at the end be included?
biggest = (None, -1)
if (len(node.inputs) == 1 or node.inputs[1].connections == ()) and path.is_dir():
# Find newest image, by filename
Expand All @@ -910,21 +915,22 @@ def sdn_get_image(node: bpy.types.Node):
biggest = (f, int(match.groups()[0]))

# If found, see if loaded, create if not
if biggest[0] != None:
if biggest[0] is not None:
for im in bpy.data.images:
if im.filepath == f.as_posix():
image = im
break
if image == None:

if image is None:
image = bpy.data.images.new(f.stem + f.suffix, 32, 32)
image.source = 'FILE'
image.filepath = f.as_posix()

return image

return image


def get_imeditor(context: bpy.types.Context, check_for_image: bool = False):
for window in context.window_manager.windows:
for area in window.screen.areas:
Expand All @@ -934,17 +940,19 @@ def get_imeditor(context: bpy.types.Context, check_for_image: bool = False):
else:
if area.type == 'IMAGE_EDITOR' and not area.spaces[0].use_image_pin:
return area

return None


def get_sdneditor(context: bpy.types.Context):
for window in context.window_manager.windows:
for area in window.screen.areas:
if area.type == 'NODE_EDITOR' and area.spaces[0].tree_type == TREE_TYPE and area.spaces[0].edit_tree:
return area

return None


class SDNode_To_Image(bpy.types.Operator):
bl_idname = "sdn.sdn_to_image"
bl_label = "ComfyUI node to Image Editor"
Expand All @@ -964,7 +972,7 @@ def execute(self, context):
if context.area.type == 'NODE_EDITOR':
node = context.active_node
ime_area = get_imeditor(context, False)

if context.area.type == 'IMAGE_EDITOR':
ime_area = context.area
sdn_area = get_sdneditor(context)
Expand All @@ -988,9 +996,11 @@ def execute(self, context):
ime_area.spaces[0].image.alpha_mode = 'CHANNEL_PACKED'

return {'FINISHED'}



MODIFIED_IMAGE_SUFFIX = '_m'


class Image_To_SDNode(bpy.types.Operator):
bl_idname = "sdn.image_to_sdn"
bl_label = "Image Editor to ComfyUI node"
Expand All @@ -1005,7 +1015,7 @@ def poll(cls, context: Context):

return (context.space_data.type == 'IMAGE_EDITOR' and context.space_data.image and get_sdneditor(context)) or \
(context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == TREE_TYPE and get_imeditor(context, True))

def execute(self, context):
sdn_area = None
ime_area = None
Expand All @@ -1016,13 +1026,13 @@ def execute(self, context):
ime_area = context.area
image = context.space_data.image
sdn_area = get_sdneditor(context)

if not sdn_area:
self.report({'ERROR'}, "No ComfyUI Node Editor found!")
return {'CANCELLED'}

new_node_loc = sdn_area.regions[3].view2d.region_to_view(sdn_area.x + sdn_area.width / 2.0, sdn_area.y + sdn_area.height / 2.0)

if context.area.type == 'NODE_EDITOR':
sdn_area = context.area
ime_area = get_imeditor(context, True)
Expand All @@ -1031,7 +1041,7 @@ def execute(self, context):
if not ime_area:
self.report({'ERROR'}, "No Image Editor with an open image found!")
return {'CANCELLED'}

if not self.force_centered:
new_node_loc = sdn_area.spaces[0].cursor_location
else:
Expand All @@ -1041,8 +1051,8 @@ def execute(self, context):
image.file_format = 'PNG'
if image.alpha_mode != 'CHANNEL_PACKED':
self.report({'WARNING'}, "The image is not using channel packed alpha. If you have painted a mask, the color underneath is black!")
if image.source in ['VIEWER', 'GENERATED']: # viewer = render result

if image.source in ['VIEWER', 'GENERATED']: # viewer = render result
filename = f"render_{uuid.uuid4()}"
newpath = f"/tmp/{filename}.png"
image.alpha_mode = 'CHANNEL_PACKED'
Expand All @@ -1055,15 +1065,14 @@ def execute(self, context):
extensionless = image.filepath_raw[:image.filepath_raw.rfind(".")]
if not extensionless.endswith(MODIFIED_IMAGE_SUFFIX):
newpath = extensionless + MODIFIED_IMAGE_SUFFIX + ".png"
image.save_render(filepath=newpath, scene=context.scene) # save_render is needed to properly save channel packed images
image.save_render(filepath=newpath, scene=context.scene) # save_render is needed to properly save channel packed images
image.filepath = newpath
image.name = image.name
image.name = image.name
else:
image.save()


active = sdn_area.spaces[0].node_tree.nodes.active
if active and active.bl_idname == '输入图像' and active.select: # "Input Image" Blender-side node
if active and active.bl_idname == '输入图像' and active.select: # "Input Image" Blender-side node
active.image = image.filepath_raw
else:
new_node = sdn_area.spaces[0].node_tree.nodes.new('输入图像')
Expand All @@ -1075,23 +1084,26 @@ def execute(self, context):
sdn_area.spaces[0].node_tree.nodes.active = new_node

return {'FINISHED'}

# There are a few cases in which images can't have their alpha changed through the UI, and channel packed alpha is needed to paint them properly.
# This operator lets the user change the alpha forcefully.


class Image_Set_Channel_Packed(bpy.types.Operator):
bl_idname = "sdn.image_set_channel_packed"
bl_label = "Set Image Alpha to Channel Packed"
bl_description = "Set the current image's alpha to channel packed, even if the option is not displayed in the UI.\nThis allows masks with color to be properly painted onto the image"
bl_translation_context = ctxt

@classmethod
def poll(cls, context: Context):
return context.space_data.type == 'IMAGE_EDITOR' and context.space_data.image and context.space_data.image.alpha_mode != 'CHANNEL_PACKED'

def execute(self, context):
context.space_data.image.alpha_mode = 'CHANNEL_PACKED'
return {'FINISHED'}


@bpy.app.handlers.persistent
def clear(_):
Ops.is_advanced_enable = False
Expand Down
4 changes: 2 additions & 2 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,11 @@ def reg_none(none: Path):
Icon.reg_icon(Icon.NONE_IMAGE)

@staticmethod
def reg_icon(path, reload=False):
def reg_icon(path, reload=False, hq=False):
path = FSWatcher.to_str(path)
if not Icon.can_mark_image(path):
return Icon[path]
if Icon.ENABLE_HQ_PREVIEW:
if Icon.ENABLE_HQ_PREVIEW and hq:
try:
Icon.reg_icon_hq(path)
except BaseException:
Expand Down

0 comments on commit c1ca1e6

Please sign in to comment.