Merge pull request #119 from Runware/feature-3DInferenceUpdate
Added new settings for 3D inference
This commit is contained in:
@@ -1934,8 +1934,26 @@ function sourcefulProviderSettingsFontsToggleHandler(fontsNode) {
|
||||
}
|
||||
|
||||
function threeDInferenceToggleHandler(node) {
|
||||
const useSeedWidget = node.widgets.find(w => w && w.name === "useSeed");
|
||||
const seedWidget = node.widgets.find(w => w && w.name === "seed");
|
||||
const useOutputQualityWidget = node.widgets.find(w => w.name === "useOutputQuality");
|
||||
const outputQualityWidget = node.widgets.find(w => w.name === "outputQuality");
|
||||
|
||||
if (useSeedWidget && seedWidget) {
|
||||
function toggleSeed() {
|
||||
const enabled = useSeedWidget.value === true;
|
||||
toggleWidgetEnabled(seedWidget, enabled, node);
|
||||
if (seedWidget.options && seedWidget.options.element) {
|
||||
seedWidget.options.element.disabled = !enabled;
|
||||
seedWidget.options.element.style.opacity = enabled ? "1" : "0.5";
|
||||
seedWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
|
||||
}
|
||||
node.setDirtyCanvas(true);
|
||||
}
|
||||
setTimeout(toggleSeed, 100);
|
||||
appendWidgetCB(useSeedWidget, () => setTimeout(toggleSeed, 50));
|
||||
}
|
||||
|
||||
if (!useOutputQualityWidget || !outputQualityWidget) return;
|
||||
function toggleEnabled() {
|
||||
const enabled = useOutputQualityWidget.value === true;
|
||||
@@ -1952,6 +1970,21 @@ function threeDInferenceSettingsToggleHandler(node) {
|
||||
["useDecimationTarget", "decimationTarget"],
|
||||
["useRemesh", "remesh"],
|
||||
["useResolution", "resolution"],
|
||||
["useImageAutoFix", "imageAutoFix"],
|
||||
["useFaceLimit", "faceLimit"],
|
||||
["useTexture", "texture"],
|
||||
["usePbr", "pbr"],
|
||||
["useTextureSeed", "textureSeed"],
|
||||
["useTextureAlignment", "textureAlignment"],
|
||||
["useTextureQuality", "textureQuality"],
|
||||
["useAutoSize", "autoSize"],
|
||||
["useOrientation", "orientation"],
|
||||
["useQuad", "quad"],
|
||||
["useCompress", "compress"],
|
||||
["useSmartLowPoly", "smartLowPoly"],
|
||||
["useGenerateParts", "generateParts"],
|
||||
["useExportUv", "exportUv"],
|
||||
["useGeometryQuality", "geometryQuality"],
|
||||
];
|
||||
pairs.forEach(([useName, paramName]) => {
|
||||
const useW = node.widgets.find(w => w.name === useName);
|
||||
|
||||
@@ -9,6 +9,7 @@ class threeDInference:
|
||||
THREED_MODELS = {
|
||||
"Meta SAM 3D": "meta:sam@3d",
|
||||
"TRELLIS.2": "microsoft:trellis-2@4b",
|
||||
"Tripo 3D v3.1": "tripo:v3.1@0",
|
||||
}
|
||||
|
||||
# Output formats
|
||||
@@ -27,8 +28,12 @@ class threeDInference:
|
||||
"placeholder": "Describe the 3D object you want to generate...",
|
||||
"tooltip": "A text prompt describing the 3D object to generate."
|
||||
}),
|
||||
"useSeed": ("BOOLEAN", {
|
||||
"tooltip": "Include seed in the API request. Turn off if the model should not receive a seed.",
|
||||
"default": True,
|
||||
}),
|
||||
"seed": ("INT", {
|
||||
"tooltip": "Seed for reproducibility. Use the same seed to get the same result.",
|
||||
"tooltip": "Seed for reproducibility. Only sent when 'Use Seed' is on.",
|
||||
"default": 1,
|
||||
"min": 1,
|
||||
"max": 2147483647,
|
||||
@@ -51,10 +56,10 @@ class threeDInference:
|
||||
"step": 1,
|
||||
}),
|
||||
"inputs": ("RUNWARE3DINFERENCEINPUTS", {
|
||||
"tooltip": "Connect a Runware 3D Inference Inputs node to provide image and mask inputs.",
|
||||
"tooltip": "Connect Runware 3D Inference Inputs for image, mask, meshFile, images (array from images_1…4), etc.",
|
||||
}),
|
||||
"settings": ("RUNWARE3DINFERENCESETTINGS", {
|
||||
"tooltip": "Connect Runware 3D Inference Settings node for textureSize, decimationTarget, remesh, resolution, sparseStructure, shapeSlat, texSlat.",
|
||||
"tooltip": "Connect Runware 3D Inference Settings for textureSize, decimationTarget, remesh, resolution, imageAutoFix, faceLimit, texture, pbr, quad, Tripo options, sparseStructure, shapeSlat, texSlat, etc.",
|
||||
}),
|
||||
},
|
||||
}
|
||||
@@ -70,6 +75,7 @@ class threeDInference:
|
||||
modelName = kwargs.get("Model", "Meta SAM 3D")
|
||||
positivePrompt = kwargs.get("positivePrompt", "")
|
||||
seed = kwargs.get("seed", 1)
|
||||
use_seed = kwargs.get("useSeed", True)
|
||||
outputFormat = kwargs.get("outputFormat", "GLB")
|
||||
use_output_quality = kwargs.get("useOutputQuality", False)
|
||||
output_quality = kwargs.get("outputQuality", 95)
|
||||
@@ -97,8 +103,8 @@ class threeDInference:
|
||||
if positivePrompt and positivePrompt.strip() != "":
|
||||
genConfig[0]["positivePrompt"] = positivePrompt.strip()
|
||||
|
||||
# Add seed
|
||||
genConfig[0]["seed"] = seed
|
||||
if use_seed:
|
||||
genConfig[0]["seed"] = seed
|
||||
|
||||
if use_output_quality:
|
||||
genConfig[0]["outputQuality"] = int(output_quality)
|
||||
|
||||
@@ -1,28 +1,38 @@
|
||||
from .utils import runwareUtils as rwUtils
|
||||
|
||||
_IMAGE_SLOTS = 4
|
||||
|
||||
|
||||
class threeDInferenceInputs:
|
||||
"""3D Inference Inputs node for configuring 3D generation inputs"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
optional = {
|
||||
"image": ("IMAGE", {
|
||||
"tooltip": "Input image for 3D inference. This image will be used as the source for generating the 3D model.",
|
||||
}),
|
||||
"mask": ("IMAGE", {
|
||||
"tooltip": "Optional mask image to specify a region of interest in the input image for 3D generation.",
|
||||
}),
|
||||
"meshFile": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "Base64 data URI of mesh file (.glb or .ply) from Runware Load Mesh.",
|
||||
}),
|
||||
}
|
||||
for i in range(1, _IMAGE_SLOTS + 1):
|
||||
optional[f"images_{i}"] = ("IMAGE", {
|
||||
"tooltip": f"Multi-view image slot {i}; merged in order into inputs.images as a list of data URIs.",
|
||||
})
|
||||
return {
|
||||
"required": {},
|
||||
"optional": {
|
||||
"image": ("IMAGE", {
|
||||
"tooltip": "Input image for 3D inference. This image will be used as the source for generating the 3D model."
|
||||
}),
|
||||
"mask": ("IMAGE", {
|
||||
"tooltip": "Optional mask image to specify a region of interest in the input image for 3D generation."
|
||||
}),
|
||||
"meshFile": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "Base64 data URI of mesh file (.glb or .ply) from Runware Load Mesh.",
|
||||
}),
|
||||
}
|
||||
"optional": optional,
|
||||
}
|
||||
|
||||
DESCRIPTION = "Configure custom inputs for Runware 3D Inference, including image and mask inputs."
|
||||
DESCRIPTION = (
|
||||
"Configure custom inputs for Runware 3D Inference: image, mask, meshFile, and images_1…images_4 "
|
||||
"(merged into inputs.images as an array)."
|
||||
)
|
||||
FUNCTION = "createInputs"
|
||||
RETURN_TYPES = ("RUNWARE3DINFERENCEINPUTS",)
|
||||
RETURN_NAMES = ("Inputs",)
|
||||
@@ -45,6 +55,14 @@ class threeDInferenceInputs:
|
||||
if mesh_file and isinstance(mesh_file, str) and mesh_file.strip():
|
||||
inputs["meshFile"] = mesh_file.strip()
|
||||
|
||||
images_list: list = []
|
||||
for i in range(1, _IMAGE_SLOTS + 1):
|
||||
slot = kwargs.get(f"images_{i}")
|
||||
if slot is not None:
|
||||
images_list.append(rwUtils.convertTensor2IMG(slot))
|
||||
if images_list:
|
||||
inputs["images"] = images_list
|
||||
|
||||
return (inputs,)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"""
|
||||
Runware 3D Inference Settings Node
|
||||
Main settings for 3D inference: textureSize, decimationTarget, remesh, resolution,
|
||||
and sub-configs sparseStructure, shapeSlat, texSlat from connected nodes.
|
||||
imageAutoFix, faceLimit, texture, pbr, Tripo mesh/texture options, and sub-configs
|
||||
sparseStructure, shapeSlat, texSlat from connected nodes.
|
||||
"""
|
||||
|
||||
from typing import Dict, Any
|
||||
@@ -53,6 +54,147 @@ class Runware3DInferenceSettings:
|
||||
"tooltip": "Resolution for 3D generation (512, 1024, or 1536). Only used when enabled.",
|
||||
"default": 1024,
|
||||
}),
|
||||
"useImageAutoFix": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include imageAutoFix in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"imageAutoFix": ("BOOLEAN", {
|
||||
"tooltip": "When true, optimizes the input image for better generation. Only used when 'Use Image Auto Fix' is enabled.",
|
||||
"default": False,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useFaceLimit": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include faceLimit in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"faceLimit": ("INT", {
|
||||
"tooltip": "Limits faces on the output mesh; if unset, face count is adaptive. With smartLowPoly: typically 1000–20000; with quad: 500–10000. Only used when enabled.",
|
||||
"default": 10000,
|
||||
"min": 500,
|
||||
"max": 20000,
|
||||
"step": 100,
|
||||
}),
|
||||
"useTexture": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include texture (enable texturing) in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"texture": ("BOOLEAN", {
|
||||
"tooltip": "Enable texturing. Default API behavior is true; set false for untextured base mesh. Only used when 'Use Texture' is enabled.",
|
||||
"default": True,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"usePbr": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include pbr in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"pbr": ("BOOLEAN", {
|
||||
"tooltip": "Enable PBR materials. Default API behavior is true; set false for no PBR. Only used when 'Use Pbr' is enabled.",
|
||||
"default": True,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useTextureSeed": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include textureSeed in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"textureSeed": ("INT", {
|
||||
"tooltip": "Seed for texture generation. Only used when 'Use Texture Seed' is enabled.",
|
||||
"default": 1,
|
||||
"min": 0,
|
||||
"max": 2147483647,
|
||||
}),
|
||||
"useTextureAlignment": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include textureAlignment in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"textureAlignment": (["original_image", "geometry"], {
|
||||
"tooltip": "original_image: fidelity to source image. geometry: alignment to 3D structure. Only used when 'Use Texture Alignment' is enabled.",
|
||||
"default": "original_image",
|
||||
}),
|
||||
"useTextureQuality": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include textureQuality in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"textureQuality": (["standard", "detailed"], {
|
||||
"tooltip": "Texture quality: standard (default) or detailed (high-res, finer detail). Only used when 'Use Texture Quality' is enabled.",
|
||||
"default": "standard",
|
||||
}),
|
||||
"useAutoSize": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include autoSize in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"autoSize": ("BOOLEAN", {
|
||||
"tooltip": "Scale the model to real-world size (meters). Default false. Only used when 'Use Auto Size' is enabled.",
|
||||
"default": False,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useOrientation": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include orientation in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"orientation": (["default", "align_image"], {
|
||||
"tooltip": "align_image rotates the model to align with the source image. Default: default. Only used when 'Use Orientation' is enabled.",
|
||||
"default": "default",
|
||||
}),
|
||||
"useQuad": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include quad in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"quad": ("BOOLEAN", {
|
||||
"tooltip": "Enable quad mesh output. If quad=true and faceLimit is unset, default faceLimit is 10000. Only used when 'Use Quad' is enabled.",
|
||||
"default": False,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useCompress": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include compress in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"compress": (["meshopt", "geometry"], {
|
||||
"tooltip": "meshopt: default compression. geometry: geometry-based compression (decompress before editing in most DCC tools). Only used when 'Use Compress' is enabled.",
|
||||
"default": "meshopt",
|
||||
}),
|
||||
"useSmartLowPoly": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include smartLowPoly in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"smartLowPoly": ("BOOLEAN", {
|
||||
"tooltip": "Low-poly meshes with hand-crafted topology; simpler inputs work best. Default false. Only used when 'Use Smart Low Poly' is enabled.",
|
||||
"default": False,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useGenerateParts": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include generateParts in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"generateParts": ("BOOLEAN", {
|
||||
"tooltip": "Segmented editable parts. Not compatible with texture/pbr when true, or with quad=true (set texture=false, pbr=false, quad=false). Only used when 'Use Generate Parts' is enabled.",
|
||||
"default": False,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useExportUv": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include exportUv in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"exportUv": ("BOOLEAN", {
|
||||
"tooltip": "Whether UV unwrapping runs during generation. Only used when 'Use Export Uv' is enabled.",
|
||||
"default": True,
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useGeometryQuality": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include geometryQuality in settings.",
|
||||
"default": False,
|
||||
}),
|
||||
"geometryQuality": (["standard", "detailed"], {
|
||||
"tooltip": "standard: balanced (default). detailed: maximum detail (ultra mode). Only used when 'Use Geometry Quality' is enabled.",
|
||||
"default": "standard",
|
||||
}),
|
||||
"sparseStructure": ("RUNWARE3DINFERENCESETTINGSLAT", {
|
||||
"tooltip": "Connect Runware 3D Inference Settings Sparse Structure node.",
|
||||
}),
|
||||
@@ -69,7 +211,11 @@ class Runware3DInferenceSettings:
|
||||
RETURN_NAMES = ("Settings",)
|
||||
FUNCTION = "create"
|
||||
CATEGORY = "Runware"
|
||||
DESCRIPTION = "Configure Runware 3D Inference settings: texture, decimation, remesh, resolution, and lat configs."
|
||||
DESCRIPTION = (
|
||||
"Configure Runware 3D Inference settings: textureSize, decimationTarget, remesh, resolution, imageAutoFix, faceLimit, "
|
||||
"texture, pbr, textureSeed, textureAlignment, textureQuality, autoSize, orientation, quad, compress, "
|
||||
"smartLowPoly, generateParts, exportUv, geometryQuality, and lat configs."
|
||||
)
|
||||
|
||||
def create(self, **kwargs) -> tuple[Dict[str, Any]]:
|
||||
settings: Dict[str, Any] = {}
|
||||
@@ -83,6 +229,37 @@ class Runware3DInferenceSettings:
|
||||
if kwargs.get("useResolution", False):
|
||||
settings["resolution"] = int(kwargs.get("resolution", 1024))
|
||||
|
||||
if kwargs.get("useImageAutoFix", False):
|
||||
settings["imageAutoFix"] = bool(kwargs.get("imageAutoFix", False))
|
||||
if kwargs.get("useFaceLimit", False):
|
||||
settings["faceLimit"] = int(kwargs.get("faceLimit", 10000))
|
||||
if kwargs.get("useTexture", False):
|
||||
settings["texture"] = bool(kwargs.get("texture", True))
|
||||
if kwargs.get("usePbr", False):
|
||||
settings["pbr"] = bool(kwargs.get("pbr", True))
|
||||
if kwargs.get("useTextureSeed", False):
|
||||
settings["textureSeed"] = int(kwargs.get("textureSeed", 1))
|
||||
if kwargs.get("useTextureAlignment", False):
|
||||
settings["textureAlignment"] = kwargs.get("textureAlignment", "original_image")
|
||||
if kwargs.get("useTextureQuality", False):
|
||||
settings["textureQuality"] = kwargs.get("textureQuality", "standard")
|
||||
if kwargs.get("useAutoSize", False):
|
||||
settings["autoSize"] = bool(kwargs.get("autoSize", False))
|
||||
if kwargs.get("useOrientation", False):
|
||||
settings["orientation"] = kwargs.get("orientation", "default")
|
||||
if kwargs.get("useQuad", False):
|
||||
settings["quad"] = bool(kwargs.get("quad", False))
|
||||
if kwargs.get("useCompress", False):
|
||||
settings["compress"] = kwargs.get("compress", "meshopt")
|
||||
if kwargs.get("useSmartLowPoly", False):
|
||||
settings["smartLowPoly"] = bool(kwargs.get("smartLowPoly", False))
|
||||
if kwargs.get("useGenerateParts", False):
|
||||
settings["generateParts"] = bool(kwargs.get("generateParts", False))
|
||||
if kwargs.get("useExportUv", False):
|
||||
settings["exportUv"] = bool(kwargs.get("exportUv", True))
|
||||
if kwargs.get("useGeometryQuality", False):
|
||||
settings["geometryQuality"] = kwargs.get("geometryQuality", "standard")
|
||||
|
||||
sparse = kwargs.get("sparseStructure", None)
|
||||
if sparse is not None and isinstance(sparse, dict) and len(sparse) > 0:
|
||||
settings["sparseStructure"] = sparse
|
||||
|
||||
Reference in New Issue
Block a user