diff --git a/blender/ops_group.py b/blender/ops_group.py
index 211e8f3..45766f9 100644
--- a/blender/ops_group.py
+++ b/blender/ops_group.py
@@ -8,5 +8,6 @@ class GroupOps(blender_node.ObjectOps):
RETURN_TYPES = (blender_node.BPY_OBJS,)
def blender_process(self, bpy, BPY_OBJ, BPY_OBJ2, **props):
- return ([BPY_OBJ, BPY_OBJ2],)
+ prop_values = props.values()
+ return ([BPY_OBJ, BPY_OBJ2, *prop_values],)
diff --git a/js/index.js b/js/index.js
index 3aa93d9..b8d80cb 100644
--- a/js/index.js
+++ b/js/index.js
@@ -73,15 +73,15 @@ LGraphGroup.prototype.repositionNodes = function () {
let sortedNodes = this._nodes.sort((a, b) => a.pos[1] - b.pos[1]);
// Separate input and output nodes from the rest
const inputNodes = sortedNodes.filter(
- (node) => node.properties.routeType === "input",
+ (node) => node.properties.routeType === "input"
);
const outputNodes = sortedNodes.filter(
- (node) => node.properties.routeType === "output",
+ (node) => node.properties.routeType === "output"
);
const otherNodes = sortedNodes.filter(
(node) =>
node.properties.routeType !== "input" &&
- node.properties.routeType !== "output",
+ node.properties.routeType !== "output"
);
// Concatenate the arrays so that input nodes are first and output nodes are last
@@ -215,7 +215,7 @@ function openInAvatechEditor(url, fileName) {
blendshapes: targetNode.val.widgets.find((x) => x.name === "shape_flow")
.value,
},
- "*",
+ "*"
);
}
@@ -288,7 +288,7 @@ function showMyImageEditor(node) {
.then(() => {
showLoading.val = false;
const v = JSON.parse(
- node.widgets.find((x) => x.name === "image_prompts_json").value,
+ node.widgets.find((x) => x.name === "image_prompts_json").value
);
if (!Array.isArray(v)) {
@@ -305,13 +305,13 @@ function showMyImageEditor(node) {
showImageEditor.val = true;
imageUrl.val = api.apiURL(
`/view?filename=${encodeURIComponent(
- connectedImageFileName,
- )}&type=input&subfolder=${split.length > 1 ? split[0] : ""}`,
+ connectedImageFileName
+ )}&type=input&subfolder=${split.length > 1 ? split[0] : ""}`
);
const embeedingUrl = api.apiURL(
`/view?filename=${encodeURIComponent(
- `${id}_${modelType}.npy`,
- )}&type=output&subfolder=`,
+ `${id}_${modelType}.npy`
+ )}&type=output&subfolder=`
);
loadNpyTensor(embeedingUrl).then((tensor) => {
embeddings.val = tensor;
@@ -354,7 +354,7 @@ const ext = {
targetNode.val = node;
openInAvatechEditor(
"https://editor.avatech.ai?comfyui=true",
- fileName.val,
+ fileName.val
);
// openInAvatechEditor("http://localhost:3006?comfyui=true", fileName.val);
});
@@ -387,6 +387,24 @@ const ext = {
widget: btn,
};
},
+ GROUP_OPS(node, inputName, inputData, app) {
+ const btn = node.addWidget("button", "Add OBJ", "", () => {
+ node.addInput("BPY_OBJ" + (node.inputs.length + 1), "BPY_OBJ");
+ node.graph.change();
+ });
+ return {
+ widget: btn,
+ };
+ },
+ GROUP_OPS_DELETE(node, inputName, inputData, app) {
+ const btn = node.addWidget("button", "Delete OBJ", "", () => {
+ node.removeInput(node.inputs.length - 1);
+ node.graph.change();
+ });
+ return {
+ widget: btn,
+ };
+ },
};
},
@@ -412,13 +430,13 @@ const ext = {
window.addEventListener("message", (event) => {
if (!event.data.flow || Object.entries(event.data.flow).length <= 0)
return;
- updateBlendshapesPrompts(event.data.flow);
+ updateBlendshapesPrompts(event.data.flow);
});
api.addEventListener("executed", (evt) => {
if (evt.detail?.output.gltfFilename) {
const viewer = document.getElementById(
- "avatech-viewer-iframe",
+ "avatech-viewer-iframe"
).contentWindow;
const gltfFilename =
@@ -446,7 +464,7 @@ const ext = {
avatarURL: gltfFilename,
blendshapes: evt.detail?.output.SHAPE_FLOW[0],
}),
- "*",
+ "*"
);
}
});
@@ -474,7 +492,7 @@ const ext = {
},
{
capture: true,
- },
+ }
);
graphCanvas.addEventListener("keydown", (event) => {
@@ -550,7 +568,7 @@ const ext = {
a.href = url;
a.setAttribute(
"download",
- new URLSearchParams(url.search).get("filename"),
+ new URLSearchParams(url.search).get("filename")
);
document.body.append(a);
a.click();
@@ -580,7 +598,7 @@ const ext = {
a.href = url;
a.setAttribute(
"download",
- new URLSearchParams(url.search).get("filename"),
+ new URLSearchParams(url.search).get("filename")
);
document.body.append(a);
a.click();
@@ -593,7 +611,7 @@ const ext = {
callback: () => {
openInAvatechEditor(
"http://localhost:3006?comfyui=true",
- gltfFilename,
+ gltfFilename
);
},
});
@@ -603,7 +621,7 @@ const ext = {
callback: () => {
openInAvatechEditor(
"https://editor.avatech.ai?comfyui=true",
- gltfFilename,
+ gltfFilename
);
},
});
@@ -629,6 +647,9 @@ const ext = {
nodeData.input.required.obj = ["MESH_GROUP_CONFIG"];
nodeData.input.required.del_obj = ["MESH_GROUP_DELETE"];
break;
+ case "GroupOps":
+ nodeData.input.required.obj = ["GROUP_OPS"];
+ nodeData.input.required.del_obj = ["GROUP_OPS_DELETE"];
default:
break;
}
@@ -659,7 +680,7 @@ export async function uploadPreview() {
infoDialog.show(
`Preview avatar url: https://editor.avatech.ai/viewer?avatarId=` +
labData.modelId +
- ``,
+ ``
);
previewModelId.val = labData.modelId;
}
@@ -713,7 +734,7 @@ function injectUIComponentToComfyuimenu() {
"https://labs.avatech.ai/api/share?id=" + previewModelId.val,
{
method: "GET",
- },
+ }
).then((e) => e.json());
await fetch(labData.url, {
@@ -730,13 +751,13 @@ function injectUIComponentToComfyuimenu() {
"https://labs.avatech.ai/api/purgecdn?id=" + previewModelId.val,
{
method: "GET",
- },
+ }
).catch((error) => console.error(error));
infoDialog.show(
`Preview updated: https://editor.avatech.ai/viewer?avatarId=` +
labData.modelId +
- "\n Remember to hard refresh before checking out the new preview!",
+ "\n Remember to hard refresh before checking out the new preview!"
);
shareLoading.val = false;
@@ -751,7 +772,7 @@ function injectUIComponentToComfyuimenu() {
event: e,
scale: 1.3,
},
- window,
+ window
);
menu.root.classList.add("popup");
};
@@ -776,7 +797,7 @@ function injectUIComponentToComfyuimenu() {
infoDialog.show(
`Preview avatar url: https://editor.avatech.ai/viewer?avatarId=` +
previewModelId.val +
- ``,
+ ``
);
}
};