From 61dfd039455493e460fde11825222cf9eb4be58b Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Mon, 6 Apr 2026 09:45:32 +0530 Subject: [PATCH 1/3] Added new settings for 3D inf --- clientlibs/utils.js | 15 +++ modules/threeDInference.py | 3 +- modules/threeDInferenceSettings.py | 181 ++++++++++++++++++++++++++++- 3 files changed, 196 insertions(+), 3 deletions(-) diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 56f3f67..27df2d4 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -1943,6 +1943,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); diff --git a/modules/threeDInference.py b/modules/threeDInference.py index 64f247f..ee60822 100644 --- a/modules/threeDInference.py +++ b/modules/threeDInference.py @@ -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 @@ -54,7 +55,7 @@ class threeDInference: "tooltip": "Connect a Runware 3D Inference Inputs node to provide image and mask inputs.", }), "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, decimation, remesh, resolution, imageAutoFix, faceLimit, texture, pbr, quad, Tripo options, sparseStructure, shapeSlat, texSlat, etc.", }), }, } diff --git a/modules/threeDInferenceSettings.py b/modules/threeDInferenceSettings.py index 03d75fb..f4b4004 100644 --- a/modules/threeDInferenceSettings.py +++ b/modules/threeDInferenceSettings.py @@ -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": "Quad mesh output; forces FBX. If quad=true and faceLimit 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, decimation, 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 From a4daeb5febdd15c229335153c63b4508c93a625a Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Tue, 7 Apr 2026 00:04:50 +0530 Subject: [PATCH 2/3] Fixed additional params --- clientlibs/utils.js | 18 +++++++++++++ modules/threeDInference.py | 13 +++++++--- modules/threeDInferenceInputs.py | 44 ++++++++++++++++++++++---------- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 27df2d4..cfc49fb 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -1925,8 +1925,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; diff --git a/modules/threeDInference.py b/modules/threeDInference.py index ee60822..a7ab4dd 100644 --- a/modules/threeDInference.py +++ b/modules/threeDInference.py @@ -28,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, @@ -52,7 +56,7 @@ 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 for textureSize, decimation, remesh, resolution, imageAutoFix, faceLimit, texture, pbr, quad, Tripo options, sparseStructure, shapeSlat, texSlat, etc.", @@ -71,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) @@ -98,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) diff --git a/modules/threeDInferenceInputs.py b/modules/threeDInferenceInputs.py index 626c481..46236b1 100644 --- a/modules/threeDInferenceInputs.py +++ b/modules/threeDInferenceInputs.py @@ -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,) From 467a7a2cd9b5385c179d2ca69173f38a87b3078d Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Tue, 7 Apr 2026 00:14:49 +0530 Subject: [PATCH 3/3] Fixed param names --- modules/threeDInference.py | 2 +- modules/threeDInferenceSettings.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/threeDInference.py b/modules/threeDInference.py index a7ab4dd..8184e54 100644 --- a/modules/threeDInference.py +++ b/modules/threeDInference.py @@ -59,7 +59,7 @@ class threeDInference: "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 for textureSize, decimation, remesh, resolution, imageAutoFix, faceLimit, texture, pbr, quad, Tripo options, sparseStructure, shapeSlat, texSlat, etc.", + "tooltip": "Connect Runware 3D Inference Settings for textureSize, decimationTarget, remesh, resolution, imageAutoFix, faceLimit, texture, pbr, quad, Tripo options, sparseStructure, shapeSlat, texSlat, etc.", }), }, } diff --git a/modules/threeDInferenceSettings.py b/modules/threeDInferenceSettings.py index f4b4004..d3c3993 100644 --- a/modules/threeDInferenceSettings.py +++ b/modules/threeDInferenceSettings.py @@ -144,7 +144,7 @@ class Runware3DInferenceSettings: "default": False, }), "quad": ("BOOLEAN", { - "tooltip": "Quad mesh output; forces FBX. If quad=true and faceLimit unset, default faceLimit is 10000. Only used when 'Use Quad' is enabled.", + "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", @@ -212,7 +212,7 @@ class Runware3DInferenceSettings: FUNCTION = "create" CATEGORY = "Runware" DESCRIPTION = ( - "Configure Runware 3D Inference settings: textureSize, decimation, remesh, resolution, imageAutoFix, faceLimit, " + "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." )