Skip to content

Commit

Permalink
Merge pull request #118 from AIGODLIKE/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
KarryCharon authored Jul 31, 2024
2 parents 1f43378 + 158888b commit 7cb13c1
Show file tree
Hide file tree
Showing 20 changed files with 601 additions and 133 deletions.
9 changes: 8 additions & 1 deletion CHANGE_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@
- change: Update translation [#291b552](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/291b5524f95b8f6b32445d187ac222fa7dac1d5a)
- change: w2c loadimage to 图形输入[bl end] [#a3f0886](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/a3f08865fe74dc1e9b271e5dac58f6835c8851c6)
- add: w2c controlnet parse [web end] [#5e945e2](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/5e945e2cc803ec87bd56f1a5b4ef434ce03d1cc9)
- add: w2c preprocessor model map to comfyui [#8771f81](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/8771f81c6cf00763f6495d5e9e0e6eb79cf1fa31) [#aafb06b](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/aafb06ba01afcfe3718d51f11936fada6c101736)
- add: w2c preprocessor model map to comfyui [#8771f81](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/8771f81c6cf00763f6495d5e9e0e6eb79cf1fa31) [#aafb06b](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/aafb06ba01afcfe3718d51f11936fada6c101736)
- fix: pref popup button not work [#94bb0c0](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/94bb0c039c104d3ee69b15bea378cc4b663ff108)
- change: update readme [#653f4a9](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/653f4a977eeff51329d867942f4be7340a1609b7)
- change: update translation [#02b27b9](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/02b27b95c5d7330f4de56ef257f0651407486cca) [#27596d1](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/27596d1a024543357a3cb7e180ad49b821f5fb00)
- improve: image alpha proc [#b28f372](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/b28f372a096dfda1b487a9aca548886de4fd58b6)
- add: dict fmt widgets_values proc [#4a78472](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/4a784721e02325ef376bc9aa81bd656bed22f4ef)
- fix: ALEK #87 [#c559416](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/c55941688457f0245b0feb3ece8203f04201b83d)
- change: update translation [#a19e0d2](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/commit/a19e0d2699b3739e0c6b49e5edcfb3607486a162)
4 changes: 2 additions & 2 deletions Linker/linker.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ class Comfyui_Swapper(bpy.types.Operator):
@classmethod
def poll(cls, context):
from ..SDNode.tree import TREE_TYPE
return context.space_data.tree_type == TREE_TYPE
return context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == TREE_TYPE

def NextAssessment(self, context):
P.foundSocket = None
Expand Down Expand Up @@ -620,7 +620,7 @@ class Comfyui_Linker(bpy.types.Operator):
@classmethod
def poll(cls, context):
from ..SDNode.tree import TREE_TYPE
return context.space_data.tree_type == TREE_TYPE
return context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == TREE_TYPE

def NextAssessment(self, context):
callPos = context.space_data.cursor_location
Expand Down
7 changes: 6 additions & 1 deletion MultiLineText/words_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,18 @@ def load_map(self):
for word in self.word_list:
self.word_map[word[0]] = word


words = Words()
words.read_tags()
words.load_map()


@bpy.app.handlers.persistent
def f(_):
mtw = bpy.context.window_manager.mlt_words
try:
mtw = bpy.context.window_manager.mlt_words
except AttributeError:
return
if len(mtw) != 0:
return
ts = time.time()
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ This is an addon for using [ComfyUI](https://github.com/comfyanonymous/ComfyUI)
## Features

- Converts ComfyUI nodes to Blender nodes
- Edit launch arguments in addon preferences, or just connect to a running ComfyUI process
- Add some special Blender nodes like camera input or compositing data
- Editable launch arguments in the addon's preferences, or just connect to a running ComfyUI process
- Adds some special Blender nodes like camera input or compositing data
- Draw masks with Grease pencil
- Blender-like node groups
- Queue batch processing with mission excel
- Node tree, workflow presets and node groups
- Model previews in Loader node
- Directly import or replace 3D models
- Node tree/workflow presets and node group presets
- Image previews for models in the Load Checkpoint node
- Can directly input or replace the 3D models in Blender
- Composition output perfect controlnet image
- Live preview when sampling
- Easily move images to and from Blender's image editor

Here are some workflow showcases:
You can find all these workflow presets in `ComfyUI-BlenderAI-node/presets/`
Expand Down Expand Up @@ -45,7 +46,7 @@ https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/assets/116185401/2c21173b-84

1. **Install Blender**

First, you need to install [Blender](https://www.blender.org/download/)(Recommend Blender 3.5, 3.6.X, or previous 4.0).
First, you need to install [Blender](https://www.blender.org/download/)(We recommend Blender 3.5, 3.6.X, or 4.0).

![image](https://github.com/AIGODLIKE/ComfyUI-BlenderAI-node/assets/116185401/aacf1cfe-ae44-4930-9a93-c226a8408066)

Expand Down Expand Up @@ -219,7 +220,7 @@ Here are some interesting nodes we've tested in Blender

? = not all functions work

× = only few or no functions work
× = only a few or no functions work

|Custom Node Name|Status|
|:----|:----|
Expand Down
12 changes: 7 additions & 5 deletions SDNode/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,13 @@ def log_non_standard(stype, nname, inp):
logger.warning("%s: %s.%s -> %s", _T('Non-Standard Enum'), nname, inp, winfo)
for k in ["required", "optional"]:
for inp, inp_desc in desc["input"].get(k, {}).items():
if inp_desc[0] == [[True, False]]:
inp_desc[0] = inp_desc[0][0]
stype = deepcopy(inp_desc[0])
if not stype:
continue
if not is_all_str_list(stype):
log_non_standard(stype, nname, inp)
# if isinstance(stype, list) and is_bool_list(stype):
# # 处理 bool 列表
# log_non_standard(stype, nname, inp)
if not (isinstance(stype, list) and isinstance(stype[0], dict)):
continue
rep = [sti["content"] for sti in stype if "content" in sti]
Expand Down Expand Up @@ -353,6 +352,8 @@ def load(s, self: NodeBase, data, with_id=True):
reg_name = get_reg_name(inp_name)
try:
v = data["widgets_values"].pop(0)
except KeyError:
v = data["widgets_values"].pop(inp_name)
except IndexError:
logger.info("%s -> %s<%s>%s " + reg_name, _T('|IGNORED|'), _T('Load'), self.class_type, _T('Params not matching with current node'))
continue
Expand Down Expand Up @@ -1455,6 +1456,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.reload()
Timer.put((f, image, img))
post_fn = partial(__post_fn__, self, mode=self.mode, image=self.image)
Expand Down Expand Up @@ -1762,7 +1764,7 @@ def _capture(s, self: NodeBase):
from ..External.mss.tools import to_png
x1, y1, x2, y2 = self.x1, self.y1, self.x2, self.y2
if x1 == x2 or y1 == y2:
logger.error("%s: %s", _T('Error Capture Screen Region'), (x1, y1, x2, y2))
logger.error("%s: %s", _T('Error Capturing Screen Region'), (x1, y1, x2, y2))
return
# print("GET REGION:", x1, y1, x2, y2)
with mss() as sct:
Expand Down Expand Up @@ -1791,7 +1793,7 @@ def update_capture(self, context):
else:
x1, y1, x2, y2 = (0, 0, 0, 0)
if x1 == x2 or y1 == y2:
logger.error("%s: %s", _T('Error Capture Screen Region'), (x1, y1, x2, y2))
logger.error("%s: %s", _T('Error Capturing Screen Region'), (x1, y1, x2, y2))
return
self.x1, self.y1, self.x2, self.y2 = x1, y1, x2, y2
s._capture(self)
Expand Down
2 changes: 2 additions & 0 deletions SDNode/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,8 @@ def on_message(ws, message):

elif mtype == "execution_start":
...
elif mtype == "execution_success":
logger.warning("%s: %s", _T("Execute Node Success"), data["node"])
elif mtype == "execution_interrupted":
{"type": "execution_interrupted",
"data": {"prompt_id": "e1f3cbf9-4b83-47cf-95c3-9f9a76ab5508",
Expand Down
2 changes: 1 addition & 1 deletion SDNode/nodegroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ def execute(self, context):
return {"CANCELLED"}
# 如果选中的节点中有组节点,则报深度错误
if any([n.bl_idname == SDNGroup.bl_idname for n in selected]):
self.report({"ERROR"}, _T("Node group can't be nested"))
self.report({"ERROR"}, _T("Node groups can't be nested"))
return {"CANCELLED"}
bpy.ops.node.clipboard_copy()
# 记录选中节点的link 以便后续恢复到 节点组外部
Expand Down
22 changes: 11 additions & 11 deletions SDNode/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,13 @@ def FLOAT(nname, inp_name, reg_name, inp):
@staticmethod
def BOOLEAN(nname, inp_name, reg_name, inp):
if len(inp) <= 1:
prop = bpy.props.BoolProperty()
else:
params = {}
for k in ["name", "description", "translation_context", "default", "options", "override", "tags", "subtype", "update", "get", "set"]:
if k in inp[1]:
params[k] = inp[1][k]
prop = bpy.props.BoolProperty(**params)
return prop
return bpy.props.BoolProperty()
params = {}
for k in ["name", "description", "translation_context", "default", "options", "override", "tags", "subtype", "update", "get", "set"]:
if k not in inp[1]:
continue
params[k] = inp[1][k]
return bpy.props.BoolProperty(**params)

@staticmethod
def STRING(nname, inp_name, reg_name, inp):
Expand Down Expand Up @@ -1212,7 +1211,7 @@ def get_nearest_node(self, context: bpy.types.Context, filter=lambda _: True) ->
@classmethod
def poll(cls, context):
from .tree import TREE_TYPE
return context.space_data.tree_type == TREE_TYPE
return context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == TREE_TYPE

def invoke(self, context: Context, event: Event):
if self.action == "OnlyFocus":
Expand Down Expand Up @@ -1404,7 +1403,8 @@ def unreg(cls):

class Set_Render_Res(bpy.types.Operator):
bl_idname = "sdn.set_render_res"
bl_label = ""
bl_label = "Set Render Resolution"
bl_description = "Set the render resolution to be the same as this node's image"
bl_translation_context = ctxt
node_name: bpy.props.StringProperty(default="")

Expand Down Expand Up @@ -1457,7 +1457,7 @@ def description(cls, context: bpy.types.Context,
@classmethod
def poll(cls, context):
from .tree import TREE_TYPE
return context.space_data.tree_type == TREE_TYPE
return context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == TREE_TYPE

def execute(self, context):
node: NodeBase = get_ctx_node()
Expand Down
16 changes: 8 additions & 8 deletions SDNode/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import typing
import time
import sys
import pickle
from ast import literal_eval as eval
import traceback
import inspect
import types
Expand Down Expand Up @@ -143,12 +143,12 @@ def __repr__(self) -> str:

def _get_id_pool(self) -> set:
if "ID_POOL" not in self.tree:
self.tree["ID_POOL"] = pickle.dumps(set())
self.tree["ID_POOL"] = "set()"
try:
return pickle.loads(self.tree["ID_POOL"])
except pickle.UnpicklingError:
self.tree["ID_POOL"] = pickle.dumps(set())
return pickle.loads(self.tree["ID_POOL"])
return eval(self.tree["ID_POOL"])
except Exception as e:
self.tree["ID_POOL"] = "set()"
return eval(self.tree["ID_POOL"])

def _set_id_pool(self, value):
if not isinstance(value, set):
Expand All @@ -160,7 +160,7 @@ def _set_id_pool(self, value):
Timer.put((self.inner_set, value))

def inner_set(self, value):
self.tree["ID_POOL"] = pickle.dumps(value)
self.tree["ID_POOL"] = str(value)

def get_id_pool(self) -> Pool:
return self.Pool(self)
Expand Down Expand Up @@ -937,7 +937,7 @@ def unreg_switch_update():
class CFNodeCategory(NodeCategory):

def poll(self, context):
return context.space_data.tree_type == TREE_TYPE
return context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == TREE_TYPE

def __init__(self, *args, **kwargs) -> None:
self.menus = kwargs.pop("menus", [])
Expand Down
16 changes: 8 additions & 8 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
bl_info = {
'name': '无限圣杯-节点 (ComfyUI Node Editor)',
'author': '幻之境开发小组-会飞的键盘侠、只剩一瓶辣椒酱',
'version': (1, 5, 4),
'name': 'ComfyUI Node Editor',
'author': '幻之境开发小组-会飞的键盘侠、只剩一瓶辣椒酱、a-One-Fan、DorotaLuna、hugeproblem、heredos、ra100',
'version': (1, 5, 5),
'blender': (3, 0, 0),
'location': '3DView->Panel',
'category': 'AI',
Expand Down Expand Up @@ -41,16 +41,16 @@ def clear_pyc(path=None, depth=2):
from .utils import Icon, FSWatcher, ScopeTimer
from .timer import timer_reg, timer_unreg
from .preference import pref_register, pref_unregister
from .ops import Ops, Ops_Mask, Load_History, Popup_Load, Copy_Tree, Load_Batch, Fetch_Node_Status, Clear_Node_Cache, Sync_Stencil_Image, NodeSearch
from .ui import header_reg, header_unreg, Panel, HISTORY_UL_UIList, HistoryItem
from .ops import Ops, Ops_Mask, Load_History, Popup_Load, Copy_Tree, Load_Batch, Fetch_Node_Status, Clear_Node_Cache, Sync_Stencil_Image, NodeSearch, SDNode_To_Image, Image_To_SDNode, Image_Set_Channel_Packed
from .ui import ui_reg, ui_unreg, Panel, HISTORY_UL_UIList, HistoryItem
from .SDNode.history import History
from .SDNode.rt_tracker import reg_tracker, unreg_tracker
from .SDNode.nodegroup import nodegroup_reg, nodegroup_unreg
from .SDNode.custom_support import custom_support_reg, custom_support_unreg
from .prop import RenderLayerString, MLTWord, Prop
from .Linker import linker_register, linker_unregister
from .hook import use_hook
clss = [Panel, Ops, RenderLayerString, MLTWord, Prop, HISTORY_UL_UIList, HistoryItem, Ops_Mask, Load_History, Popup_Load, Copy_Tree, Load_Batch, Fetch_Node_Status, Clear_Node_Cache, Sync_Stencil_Image, NodeSearch, EnableMLT]
clss = [Panel, Ops, RenderLayerString, MLTWord, Prop, HISTORY_UL_UIList, HistoryItem, Ops_Mask, Load_History, Popup_Load, Copy_Tree, Load_Batch, Fetch_Node_Status, Clear_Node_Cache, Sync_Stencil_Image, NodeSearch, SDNode_To_Image, Image_To_SDNode, Image_Set_Channel_Packed, EnableMLT]
reg, unreg = bpy.utils.register_classes_factory(clss)
from platform import system

Expand Down Expand Up @@ -113,7 +113,7 @@ def register():
from .translations import translations_dict
bpy.app.translations.register(__name__, translations_dict)
reg()
header_reg()
ui_reg()
Icon.set_hq_preview()
TaskManager.run_server(fake=True)
timer_reg()
Expand Down Expand Up @@ -142,7 +142,7 @@ def unregister():
return
bpy.app.translations.unregister(__name__)
unreg()
header_unreg()
ui_unreg()
rtnode_unreg()
timer_unreg()
del bpy.types.Scene.sdn
Expand Down
Loading

0 comments on commit 7cb13c1

Please sign in to comment.