mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-06-02 01:22:11 +08:00

* Add Ideogram generate node. * Add staging api. * Add API_NODE and common error for missing auth token (#5) * Add Minimax Video Generation + Async Task queue polling example (#6) * [Minimax] Show video preview and embed workflow in ouput (#7) * Remove uv.lock * Remove polling operations. * Revert "Remove polling operations." This reverts commit 8415404ce8fbc0262b7de54fc700c5c8854a34fc. * Update stubs. * Added Ideogram and Minimax back in. * Added initial BFL Flux 1.1 [pro] Ultra node (#11) * Manually add BFL polling status response schema (#15) * Add function for uploading files. (#18) * Add Luma nodes (#16) Co-authored-by: Robin Huang <robin.j.huang@gmail.com> * Refactor util functions (#20) * Add rest of Luma node functionality (#19) Co-authored-by: Robin Huang <robin.j.huang@gmail.com> * Fix image_luma_ref not working (#28) Co-authored-by: Robin Huang <robin.j.huang@gmail.com> * [Bug] Remove duplicated option T2V-01 in MinimaxTextToVideoNode (#31) * add veo2, bump av req (#32) * Add Recraft nodes (#29) * Add Kling Nodes (#12) * Add Camera Concepts (luma_concepts) to Luma Video nodes (#33) Co-authored-by: Robin Huang <robin.j.huang@gmail.com> * Add Runway nodes (#17) * Convert Minimax node to use VIDEO output type (#34) * Standard `CATEGORY` system for api nodes (#35) * Set `Content-Type` header when uploading files (#36) * add better error propagation to veo2 (#37) * Add Realistic Image and Logo Raster styles for Recraft v3 (#38) * Fix runway image upload and progress polling (#39) * Fix image upload for Luma: only include `Content-Type` header field if it's set explicitly (#40) * Moved Luma nodes to nodes_luma.py (#47) * Moved Recraft nodes to nodes_recraft.py (#48) * Move and fix BFL nodes to node_bfl.py (#49) * Move and edit Minimax node to nodes_minimax.py (#50) * Add Recraft Text to Vector node, add Save SVG node to handle its output (#53) * Added pixverse_template support to Pixverse Text to Video node (#54) * Added Recraft Controls + Recraft Color RGB nodes (#57) * split remaining nodes out of nodes_api, make utility lib, refactor ideogram (#61) * Set request type explicitly (#66) * Add `control_after_generate` to all seed inputs (#69) * Fix bug: deleting `Content-Type` when property does not exist (#73) * Add Pixverse and updated Kling types (#75) * Added Recraft Style - Infinite Style Library node (#82) * add ideogram v3 (#83) * [Kling] Split Camera Control config to its own node (#81) * Add Pika i2v and t2v nodes (#52) * Remove Runway nodes (#88) * Fix: Prompt text can't be validated in Kling nodes when using primitive nodes (#90) * Update Pika Duration and Resolution options (#94) * Removed Infinite Style Library until later (#99) * fix multi image return (#101) close #96 * Serve SVG files directly (#107) * Add a bunch of nodes, 3 ready to use, the rest waiting for endpoint support (#108) * Revert "Serve SVG files directly" (#111) * Expose 4 remaining Recraft nodes (#112) * [Kling] Add `Duration` and `Video ID` outputs (#105) * Add Kling nodes: camera control, start-end frame, lip-sync, video extend (#115) * Fix error for Recraft ImageToImage error for nonexistent random_seed param (#118) * Add remaining Pika nodes (#119) * Make controls input work for Recraft Image to Image node (#120) * Fix: Nested `AnyUrl` in request model cannot be serialized (Kling, Runway) (#129) * Show errors and API output URLs to the user (change log levels) (#131) * Apply small fixes and most prompt validation (if needed to avoid API error) (#135) * Node name/category modifications (#140) * Add back Recraft Style - Infinite Style Library node (#141) * [Kling] Fix: Correct/verify supported subset of input combos in Kling nodes (#149) * Remove pixverse_template from PixVerse Transition Video node (#155) * Use 3.9 compat syntax (#164) * Handle Comfy API key based authorizaton (#167) Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com> * [BFL] Print download URL of successful task result directly on nodes (#175) * Show output URL and progress text on Pika nodes (#168) * [Ideogram] Print download URL of successful task result directly on nodes (#176) * [Kling] Print download URL of successful task result directly on nodes (#181) * Merge upstream may 14 25 (#186) Co-authored-by: comfyanonymous <comfyanonymous@protonmail.com> Co-authored-by: AustinMroz <austinmroz@utexas.edu> Co-authored-by: comfyanonymous <121283862+comfyanonymous@users.noreply.github.com> Co-authored-by: Benjamin Lu <benceruleanlu@proton.me> Co-authored-by: Andrew Kvochko <kvochko@users.noreply.github.com> Co-authored-by: Pam <42671363+pamparamm@users.noreply.github.com> Co-authored-by: chaObserv <154517000+chaObserv@users.noreply.github.com> Co-authored-by: Yoland Yan <4950057+yoland68@users.noreply.github.com> Co-authored-by: guill <guill@users.noreply.github.com> Co-authored-by: Chenlei Hu <hcl@comfy.org> Co-authored-by: Terry Jia <terryjia88@gmail.com> Co-authored-by: Silver <65376327+silveroxides@users.noreply.github.com> Co-authored-by: catboxanon <122327233+catboxanon@users.noreply.github.com> Co-authored-by: liesen <liesen.dev@gmail.com> Co-authored-by: Kohaku-Blueleaf <59680068+KohakuBlueleaf@users.noreply.github.com> Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com> Co-authored-by: Robin Huang <robin.j.huang@gmail.com> Co-authored-by: thot experiment <94414189+thot-experiment@users.noreply.github.com> Co-authored-by: blepping <157360029+blepping@users.noreply.github.com> * Update instructions on how to develop API Nodes. (#171) * Add Runway FLF and I2V nodes (#187) * Add OpenAI chat node (#188) * Update README. * Add Google Gemini API node (#191) * Add Runway Gen 4 Text to Image Node (#193) * [Runway, Gemini] Update node display names and attributes (#194) * Update path from "image-to-video" to "image_to_video" (#197) * [Runway] Split I2V nodes into separate gen3 and gen4 nodes (#198) * Update runway i2v ratio enum (#201) * Rodin3D: implement Rodin3D API Nodes (#190) Co-authored-by: WhiteGiven <c15838568211@163.com> Co-authored-by: Robin Huang <robin.j.huang@gmail.com> * Add Tripo Nodes. (#189) Co-authored-by: Robin Huang <robin.j.huang@gmail.com> * Change casing of categories "3D" => "3d" (#208) * [tripo] fix negtive_prompt and mv2model (#212) * [tripo] set default param to None (#215) * Add description and tooltip to Tripo Refine model. (#218) * Update. * Fix rebase errors. * Fix rebase errors. * Update templates. * Bump frontend. * Add file type info for file inputs. --------- Co-authored-by: Christian Byrne <cbyrne@comfy.org> Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com> Co-authored-by: Chenlei Hu <hcl@comfy.org> Co-authored-by: thot experiment <94414189+thot-experiment@users.noreply.github.com> Co-authored-by: comfyanonymous <comfyanonymous@protonmail.com> Co-authored-by: AustinMroz <austinmroz@utexas.edu> Co-authored-by: comfyanonymous <121283862+comfyanonymous@users.noreply.github.com> Co-authored-by: Benjamin Lu <benceruleanlu@proton.me> Co-authored-by: Andrew Kvochko <kvochko@users.noreply.github.com> Co-authored-by: Pam <42671363+pamparamm@users.noreply.github.com> Co-authored-by: chaObserv <154517000+chaObserv@users.noreply.github.com> Co-authored-by: Yoland Yan <4950057+yoland68@users.noreply.github.com> Co-authored-by: guill <guill@users.noreply.github.com> Co-authored-by: Terry Jia <terryjia88@gmail.com> Co-authored-by: Silver <65376327+silveroxides@users.noreply.github.com> Co-authored-by: catboxanon <122327233+catboxanon@users.noreply.github.com> Co-authored-by: liesen <liesen.dev@gmail.com> Co-authored-by: Kohaku-Blueleaf <59680068+KohakuBlueleaf@users.noreply.github.com> Co-authored-by: blepping <157360029+blepping@users.noreply.github.com> Co-authored-by: Changrz <51637999+WhiteGiven@users.noreply.github.com> Co-authored-by: WhiteGiven <c15838568211@163.com> Co-authored-by: seed93 <liangding1990@163.com>
463 lines
15 KiB
Python
463 lines
15 KiB
Python
"""
|
|
ComfyUI X Rodin3D(Deemos) API Nodes
|
|
|
|
Rodin API docs: https://developer.hyper3d.ai/
|
|
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
from inspect import cleandoc
|
|
from comfy.comfy_types.node_typing import IO
|
|
import folder_paths as comfy_paths
|
|
import requests
|
|
import os
|
|
import datetime
|
|
import shutil
|
|
import time
|
|
import io
|
|
import logging
|
|
import math
|
|
from PIL import Image
|
|
from comfy_api_nodes.apis.rodin_api import (
|
|
Rodin3DGenerateRequest,
|
|
Rodin3DGenerateResponse,
|
|
Rodin3DCheckStatusRequest,
|
|
Rodin3DCheckStatusResponse,
|
|
Rodin3DDownloadRequest,
|
|
Rodin3DDownloadResponse,
|
|
JobStatus,
|
|
)
|
|
from comfy_api_nodes.apis.client import (
|
|
ApiEndpoint,
|
|
HttpMethod,
|
|
SynchronousOperation,
|
|
PollingOperation,
|
|
)
|
|
|
|
|
|
COMMON_PARAMETERS = {
|
|
"Seed": (
|
|
IO.INT,
|
|
{
|
|
"default":0,
|
|
"min":0,
|
|
"max":65535,
|
|
"display":"number"
|
|
}
|
|
),
|
|
"Material_Type": (
|
|
IO.COMBO,
|
|
{
|
|
"options": ["PBR", "Shaded"],
|
|
"default": "PBR"
|
|
}
|
|
),
|
|
"Polygon_count": (
|
|
IO.COMBO,
|
|
{
|
|
"options": ["4K-Quad", "8K-Quad", "18K-Quad", "50K-Quad", "200K-Triangle"],
|
|
"default": "18K-Quad"
|
|
}
|
|
)
|
|
}
|
|
|
|
def create_task_error(response: Rodin3DGenerateResponse):
|
|
"""Check if the response has error"""
|
|
return hasattr(response, "error")
|
|
|
|
|
|
|
|
class Rodin3DAPI:
|
|
"""
|
|
Generate 3D Assets using Rodin API
|
|
"""
|
|
RETURN_TYPES = (IO.STRING,)
|
|
RETURN_NAMES = ("3D Model Path",)
|
|
CATEGORY = "api node/3d/Rodin"
|
|
DESCRIPTION = cleandoc(__doc__ or "")
|
|
FUNCTION = "api_call"
|
|
API_NODE = True
|
|
|
|
def tensor_to_filelike(self, tensor, max_pixels: int = 2048*2048):
|
|
"""
|
|
Converts a PyTorch tensor to a file-like object.
|
|
|
|
Args:
|
|
- tensor (torch.Tensor): A tensor representing an image of shape (H, W, C)
|
|
where C is the number of channels (3 for RGB), H is height, and W is width.
|
|
|
|
Returns:
|
|
- io.BytesIO: A file-like object containing the image data.
|
|
"""
|
|
array = tensor.cpu().numpy()
|
|
array = (array * 255).astype('uint8')
|
|
image = Image.fromarray(array, 'RGB')
|
|
|
|
original_width, original_height = image.size
|
|
original_pixels = original_width * original_height
|
|
if original_pixels > max_pixels:
|
|
scale = math.sqrt(max_pixels / original_pixels)
|
|
new_width = int(original_width * scale)
|
|
new_height = int(original_height * scale)
|
|
else:
|
|
new_width, new_height = original_width, original_height
|
|
|
|
if new_width != original_width or new_height != original_height:
|
|
image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
|
|
|
img_byte_arr = io.BytesIO()
|
|
image.save(img_byte_arr, format='PNG') # PNG is used for lossless compression
|
|
img_byte_arr.seek(0)
|
|
return img_byte_arr
|
|
|
|
def check_rodin_status(self, response: Rodin3DCheckStatusResponse) -> str:
|
|
has_failed = any(job.status == JobStatus.Failed for job in response.jobs)
|
|
all_done = all(job.status == JobStatus.Done for job in response.jobs)
|
|
status_list = [str(job.status) for job in response.jobs]
|
|
logging.info(f"[ Rodin3D API - CheckStatus ] Generate Status: {status_list}")
|
|
if has_failed:
|
|
logging.error(f"[ Rodin3D API - CheckStatus ] Generate Failed: {status_list}, Please try again.")
|
|
raise Exception("[ Rodin3D API ] Generate Failed, Please Try again.")
|
|
elif all_done:
|
|
return "DONE"
|
|
else:
|
|
return "Generating"
|
|
|
|
def CreateGenerateTask(self, images=None, seed=1, material="PBR", quality="medium", tier="Regular", mesh_mode="Quad", **kwargs):
|
|
if images == None:
|
|
raise Exception("Rodin 3D generate requires at least 1 image.")
|
|
if len(images) >= 5:
|
|
raise Exception("Rodin 3D generate requires up to 5 image.")
|
|
|
|
path = "/proxy/rodin/api/v2/rodin"
|
|
operation = SynchronousOperation(
|
|
endpoint=ApiEndpoint(
|
|
path=path,
|
|
method=HttpMethod.POST,
|
|
request_model=Rodin3DGenerateRequest,
|
|
response_model=Rodin3DGenerateResponse,
|
|
),
|
|
request=Rodin3DGenerateRequest(
|
|
seed=seed,
|
|
tier=tier,
|
|
material=material,
|
|
quality=quality,
|
|
mesh_mode=mesh_mode
|
|
),
|
|
files=[
|
|
(
|
|
"images",
|
|
open(image, "rb") if isinstance(image, str) else self.tensor_to_filelike(image)
|
|
)
|
|
for image in images if image is not None
|
|
],
|
|
content_type = "multipart/form-data",
|
|
auth_kwargs=kwargs,
|
|
)
|
|
|
|
response = operation.execute()
|
|
|
|
if create_task_error(response):
|
|
error_message = f"Rodin3D Create 3D generate Task Failed. Message: {response.message}, error: {response.error}"
|
|
logging.error(error_message)
|
|
raise Exception(error_message)
|
|
|
|
logging.info("[ Rodin3D API - Submit Jobs ] Submit Generate Task Success!")
|
|
subscription_key = response.jobs.subscription_key
|
|
task_uuid = response.uuid
|
|
logging.info(f"[ Rodin3D API - Submit Jobs ] UUID: {task_uuid}")
|
|
return task_uuid, subscription_key
|
|
|
|
def poll_for_task_status(self, subscription_key, **kwargs) -> Rodin3DCheckStatusResponse:
|
|
|
|
path = "/proxy/rodin/api/v2/status"
|
|
|
|
poll_operation = PollingOperation(
|
|
poll_endpoint=ApiEndpoint(
|
|
path = path,
|
|
method=HttpMethod.POST,
|
|
request_model=Rodin3DCheckStatusRequest,
|
|
response_model=Rodin3DCheckStatusResponse,
|
|
),
|
|
request=Rodin3DCheckStatusRequest(
|
|
subscription_key = subscription_key
|
|
),
|
|
completed_statuses=["DONE"],
|
|
failed_statuses=["FAILED"],
|
|
status_extractor=self.check_rodin_status,
|
|
poll_interval=3.0,
|
|
auth_kwargs=kwargs,
|
|
)
|
|
|
|
logging.info("[ Rodin3D API - CheckStatus ] Generate Start!")
|
|
|
|
return poll_operation.execute()
|
|
|
|
|
|
|
|
def GetRodinDownloadList(self, uuid, **kwargs) -> Rodin3DDownloadResponse:
|
|
logging.info("[ Rodin3D API - Downloading ] Generate Successfully!")
|
|
|
|
path = "/proxy/rodin/api/v2/download"
|
|
operation = SynchronousOperation(
|
|
endpoint=ApiEndpoint(
|
|
path=path,
|
|
method=HttpMethod.POST,
|
|
request_model=Rodin3DDownloadRequest,
|
|
response_model=Rodin3DDownloadResponse,
|
|
),
|
|
request=Rodin3DDownloadRequest(
|
|
task_uuid=uuid
|
|
),
|
|
auth_kwargs=kwargs
|
|
)
|
|
|
|
return operation.execute()
|
|
|
|
def GetQualityAndMode(self, PolyCount):
|
|
if PolyCount == "200K-Triangle":
|
|
mesh_mode = "Raw"
|
|
quality = "medium"
|
|
else:
|
|
mesh_mode = "Quad"
|
|
if PolyCount == "4K-Quad":
|
|
quality = "extra-low"
|
|
elif PolyCount == "8K-Quad":
|
|
quality = "low"
|
|
elif PolyCount == "18K-Quad":
|
|
quality = "medium"
|
|
elif PolyCount == "50K-Quad":
|
|
quality = "high"
|
|
else:
|
|
quality = "medium"
|
|
|
|
return mesh_mode, quality
|
|
|
|
def DownLoadFiles(self, Url_List):
|
|
Save_path = os.path.join(comfy_paths.get_output_directory(), "Rodin3D", datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
|
|
os.makedirs(Save_path, exist_ok=True)
|
|
model_file_path = None
|
|
for Item in Url_List.list:
|
|
url = Item.url
|
|
file_name = Item.name
|
|
file_path = os.path.join(Save_path, file_name)
|
|
if file_path.endswith(".glb"):
|
|
model_file_path = file_path
|
|
logging.info(f"[ Rodin3D API - download_files ] Downloading file: {file_path}")
|
|
max_retries = 5
|
|
for attempt in range(max_retries):
|
|
try:
|
|
with requests.get(url, stream=True) as r:
|
|
r.raise_for_status()
|
|
with open(file_path, "wb") as f:
|
|
shutil.copyfileobj(r.raw, f)
|
|
break
|
|
except Exception as e:
|
|
logging.info(f"[ Rodin3D API - download_files ] Error downloading {file_path}:{e}")
|
|
if attempt < max_retries - 1:
|
|
logging.info("Retrying...")
|
|
time.sleep(2)
|
|
else:
|
|
logging.info(f"[ Rodin3D API - download_files ] Failed to download {file_path} after {max_retries} attempts.")
|
|
|
|
return model_file_path
|
|
|
|
|
|
class Rodin3D_Regular(Rodin3DAPI):
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"Images":
|
|
(
|
|
IO.IMAGE,
|
|
{
|
|
"forceInput":True,
|
|
}
|
|
)
|
|
},
|
|
"optional": {
|
|
**COMMON_PARAMETERS
|
|
},
|
|
"hidden": {
|
|
"auth_token": "AUTH_TOKEN_COMFY_ORG",
|
|
"comfy_api_key": "API_KEY_COMFY_ORG",
|
|
},
|
|
}
|
|
|
|
def api_call(
|
|
self,
|
|
Images,
|
|
Seed,
|
|
Material_Type,
|
|
Polygon_count,
|
|
**kwargs
|
|
):
|
|
tier = "Regular"
|
|
num_images = Images.shape[0]
|
|
m_images = []
|
|
for i in range(num_images):
|
|
m_images.append(Images[i])
|
|
mesh_mode, quality = self.GetQualityAndMode(Polygon_count)
|
|
task_uuid, subscription_key = self.CreateGenerateTask(images=m_images, seed=Seed, material=Material_Type, quality=quality, tier=tier, mesh_mode=mesh_mode, **kwargs)
|
|
self.poll_for_task_status(subscription_key, **kwargs)
|
|
Download_List = self.GetRodinDownloadList(task_uuid, **kwargs)
|
|
model = self.DownLoadFiles(Download_List)
|
|
|
|
return (model,)
|
|
|
|
class Rodin3D_Detail(Rodin3DAPI):
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"Images":
|
|
(
|
|
IO.IMAGE,
|
|
{
|
|
"forceInput":True,
|
|
}
|
|
)
|
|
},
|
|
"optional": {
|
|
**COMMON_PARAMETERS
|
|
},
|
|
"hidden": {
|
|
"auth_token": "AUTH_TOKEN_COMFY_ORG",
|
|
"comfy_api_key": "API_KEY_COMFY_ORG",
|
|
},
|
|
}
|
|
|
|
def api_call(
|
|
self,
|
|
Images,
|
|
Seed,
|
|
Material_Type,
|
|
Polygon_count,
|
|
**kwargs
|
|
):
|
|
tier = "Detail"
|
|
num_images = Images.shape[0]
|
|
m_images = []
|
|
for i in range(num_images):
|
|
m_images.append(Images[i])
|
|
mesh_mode, quality = self.GetQualityAndMode(Polygon_count)
|
|
task_uuid, subscription_key = self.CreateGenerateTask(images=m_images, seed=Seed, material=Material_Type, quality=quality, tier=tier, mesh_mode=mesh_mode, **kwargs)
|
|
self.poll_for_task_status(subscription_key, **kwargs)
|
|
Download_List = self.GetRodinDownloadList(task_uuid, **kwargs)
|
|
model = self.DownLoadFiles(Download_List)
|
|
|
|
return (model,)
|
|
|
|
class Rodin3D_Smooth(Rodin3DAPI):
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"Images":
|
|
(
|
|
IO.IMAGE,
|
|
{
|
|
"forceInput":True,
|
|
}
|
|
)
|
|
},
|
|
"optional": {
|
|
**COMMON_PARAMETERS
|
|
},
|
|
"hidden": {
|
|
"auth_token": "AUTH_TOKEN_COMFY_ORG",
|
|
"comfy_api_key": "API_KEY_COMFY_ORG",
|
|
},
|
|
}
|
|
|
|
def api_call(
|
|
self,
|
|
Images,
|
|
Seed,
|
|
Material_Type,
|
|
Polygon_count,
|
|
**kwargs
|
|
):
|
|
tier = "Smooth"
|
|
num_images = Images.shape[0]
|
|
m_images = []
|
|
for i in range(num_images):
|
|
m_images.append(Images[i])
|
|
mesh_mode, quality = self.GetQualityAndMode(Polygon_count)
|
|
task_uuid, subscription_key = self.CreateGenerateTask(images=m_images, seed=Seed, material=Material_Type, quality=quality, tier=tier, mesh_mode=mesh_mode, **kwargs)
|
|
self.poll_for_task_status(subscription_key, **kwargs)
|
|
Download_List = self.GetRodinDownloadList(task_uuid, **kwargs)
|
|
model = self.DownLoadFiles(Download_List)
|
|
|
|
return (model,)
|
|
|
|
class Rodin3D_Sketch(Rodin3DAPI):
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"Images":
|
|
(
|
|
IO.IMAGE,
|
|
{
|
|
"forceInput":True,
|
|
}
|
|
)
|
|
},
|
|
"optional": {
|
|
"Seed":
|
|
(
|
|
IO.INT,
|
|
{
|
|
"default":0,
|
|
"min":0,
|
|
"max":65535,
|
|
"display":"number"
|
|
}
|
|
)
|
|
},
|
|
"hidden": {
|
|
"auth_token": "AUTH_TOKEN_COMFY_ORG",
|
|
"comfy_api_key": "API_KEY_COMFY_ORG",
|
|
},
|
|
}
|
|
|
|
def api_call(
|
|
self,
|
|
Images,
|
|
Seed,
|
|
**kwargs
|
|
):
|
|
tier = "Sketch"
|
|
num_images = Images.shape[0]
|
|
m_images = []
|
|
for i in range(num_images):
|
|
m_images.append(Images[i])
|
|
material_type = "PBR"
|
|
quality = "medium"
|
|
mesh_mode = "Quad"
|
|
task_uuid, subscription_key = self.CreateGenerateTask(images=m_images, seed=Seed, material=material_type, quality=quality, tier=tier, mesh_mode=mesh_mode, **kwargs)
|
|
self.poll_for_task_status(subscription_key, **kwargs)
|
|
Download_List = self.GetRodinDownloadList(task_uuid, **kwargs)
|
|
model = self.DownLoadFiles(Download_List)
|
|
|
|
return (model,)
|
|
|
|
# A dictionary that contains all nodes you want to export with their names
|
|
# NOTE: names should be globally unique
|
|
NODE_CLASS_MAPPINGS = {
|
|
"Rodin3D_Regular": Rodin3D_Regular,
|
|
"Rodin3D_Detail": Rodin3D_Detail,
|
|
"Rodin3D_Smooth": Rodin3D_Smooth,
|
|
"Rodin3D_Sketch": Rodin3D_Sketch,
|
|
}
|
|
|
|
# A dictionary that contains the friendly/humanly readable titles for the nodes
|
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
"Rodin3D_Regular": "Rodin 3D Generate - Regular Generate",
|
|
"Rodin3D_Detail": "Rodin 3D Generate - Detail Generate",
|
|
"Rodin3D_Smooth": "Rodin 3D Generate - Smooth Generate",
|
|
"Rodin3D_Sketch": "Rodin 3D Generate - Sketch Generate",
|
|
}
|