mirror of
https://git.datalinker.icu/kijai/ComfyUI-Hunyuan3DWrapper.git
synced 2026-01-23 07:04:25 +08:00
Add upload mesh node
This commit is contained in:
parent
205be20e08
commit
7bba1dd89a
37
nodes.py
37
nodes.py
@ -958,6 +958,41 @@ class Hy3DLoadMesh:
|
||||
|
||||
return (mesh,)
|
||||
|
||||
class Hy3DUploadMesh:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
mesh_extensions = ['glb', 'gltf']
|
||||
input_dir = folder_paths.get_input_directory()
|
||||
files = []
|
||||
for f in os.listdir(input_dir):
|
||||
if os.path.isfile(os.path.join(input_dir, f)):
|
||||
file_parts = f.split('.')
|
||||
if len(file_parts) > 1 and (file_parts[-1] in mesh_extensions):
|
||||
files.append(f)
|
||||
return {
|
||||
"required": {
|
||||
"mesh": (sorted(files),),
|
||||
}
|
||||
}
|
||||
RETURN_TYPES = ("HY3DMESH",)
|
||||
RETURN_NAMES = ("mesh",)
|
||||
OUTPUT_TOOLTIPS = ("The glb model with mesh to texturize.",)
|
||||
|
||||
FUNCTION = "load"
|
||||
CATEGORY = "Hunyuan3DWrapper"
|
||||
DESCRIPTION = "Loads a glb model from the given path."
|
||||
|
||||
def load(self, mesh):
|
||||
path = mesh.strip()
|
||||
if path.startswith("\""):
|
||||
path = path[1:]
|
||||
if path.endswith("\""):
|
||||
path = path[:-1]
|
||||
mesh_file = folder_paths.get_annotated_filepath(path)
|
||||
loaded_mesh = trimesh.load(mesh_file, force="mesh")
|
||||
|
||||
return (loaded_mesh,)
|
||||
|
||||
|
||||
class Hy3DGenerateMesh:
|
||||
@classmethod
|
||||
@ -1504,6 +1539,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"Hy3DTorchCompileSettings": Hy3DTorchCompileSettings,
|
||||
"Hy3DPostprocessMesh": Hy3DPostprocessMesh,
|
||||
"Hy3DLoadMesh": Hy3DLoadMesh,
|
||||
"Hy3DUploadMesh": Hy3DUploadMesh,
|
||||
"Hy3DCameraConfig": Hy3DCameraConfig,
|
||||
"Hy3DMeshUVWrap": Hy3DMeshUVWrap,
|
||||
"Hy3DSampleMultiView": Hy3DSampleMultiView,
|
||||
@ -1534,6 +1570,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Hy3DTorchCompileSettings": "Hy3D Torch Compile Settings",
|
||||
"Hy3DPostprocessMesh": "Hy3D Postprocess Mesh",
|
||||
"Hy3DLoadMesh": "Hy3D Load Mesh",
|
||||
"Hy3DUploadMesh": "Hy3D Upload Mesh",
|
||||
"Hy3DCameraConfig": "Hy3D Camera Config",
|
||||
"Hy3DMeshUVWrap": "Hy3D Mesh UV Wrap",
|
||||
"Hy3DSampleMultiView": "Hy3D Sample MultiView",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { api } from "../../../scripts/api.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "HY3D.jsnodes",
|
||||
@ -25,8 +26,100 @@ app.registerExtension({
|
||||
this.outputs[2]["name"] = values[1] + " faces"
|
||||
return r
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "Hy3DUploadMesh":
|
||||
addUploadWidget(nodeType, nodeData, "mesh");
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
//file upload code from VHS nodes: https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite
|
||||
async function uploadFile(file) {
|
||||
//TODO: Add uploaded file to cache with Cache.put()?
|
||||
try {
|
||||
// Wrap file in formdata so it includes filename
|
||||
const body = new FormData();
|
||||
const i = file.webkitRelativePath.lastIndexOf('/');
|
||||
const subfolder = file.webkitRelativePath.slice(0,i+1)
|
||||
const new_file = new File([file], file.name, {
|
||||
type: file.type,
|
||||
lastModified: file.lastModified,
|
||||
});
|
||||
body.append("image", new_file);
|
||||
if (i > 0) {
|
||||
body.append("subfolder", subfolder);
|
||||
}
|
||||
const resp = await api.fetchApi("/upload/image", {
|
||||
method: "POST",
|
||||
body,
|
||||
});
|
||||
|
||||
if (resp.status === 200) {
|
||||
return resp
|
||||
} else {
|
||||
alert(resp.status + " - " + resp.statusText);
|
||||
}
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
}
|
||||
}
|
||||
|
||||
function addUploadWidget(nodeType, nodeData, widgetName) {
|
||||
chainCallback(nodeType.prototype, "onNodeCreated", function() {
|
||||
const pathWidget = this.widgets.find((w) => w.name === widgetName);
|
||||
const fileInput = document.createElement("input");
|
||||
chainCallback(this, "onRemoved", () => {
|
||||
fileInput?.remove();
|
||||
});
|
||||
|
||||
Object.assign(fileInput, {
|
||||
type: "file",
|
||||
accept: ".glb,.gltf,model/gltf-binary,model/gltf+json",
|
||||
style: "display: none",
|
||||
onchange: async () => {
|
||||
if (fileInput.files.length) {
|
||||
let resp = await uploadFile(fileInput.files[0])
|
||||
if (resp.status != 200) {
|
||||
//upload failed and file can not be added to options
|
||||
return;
|
||||
}
|
||||
const filename = (await resp.json()).name;
|
||||
pathWidget.options.values.push(filename);
|
||||
pathWidget.value = filename;
|
||||
if (pathWidget.callback) {
|
||||
pathWidget.callback(filename)
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
console.log(this)
|
||||
document.body.append(fileInput);
|
||||
let uploadWidget = this.addWidget("button", "choose glb file to upload", "image", () => {
|
||||
//clear the active click event
|
||||
app.canvas.node_widget = null
|
||||
|
||||
fileInput.click();
|
||||
});
|
||||
uploadWidget.options.serialize = false;
|
||||
});
|
||||
}
|
||||
|
||||
function chainCallback(object, property, callback) {
|
||||
if (object == undefined) {
|
||||
//This should not happen.
|
||||
console.error("Tried to add callback to non-existant object")
|
||||
return;
|
||||
}
|
||||
if (property in object && object[property]) {
|
||||
const callback_orig = object[property]
|
||||
object[property] = function () {
|
||||
const r = callback_orig.apply(this, arguments);
|
||||
callback.apply(this, arguments);
|
||||
return r
|
||||
};
|
||||
} else {
|
||||
object[property] = callback;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user