Add new StackOrbitCameraPoses node to auto conditioning StableZero123 & 3DGS etc.

This commit is contained in:
MrForExample
2024-01-10 12:15:02 +01:00
parent fa562f1883
commit 23934c8e65
9 changed files with 1327 additions and 2 deletions
+28 -2
View File
@@ -63,7 +63,10 @@ Copy the files inside folder [__New_ComfyUI_Bats](./_New_ComfyUI_Bats/) to your
### Currently support:
- For use case please check [example workflows](./_Example_Workflows/)
- **Note:** you need to put [Images_enhanced](_Example_Workflows/_Example_Inputs_Files/Images_enhanced) and [Meshes](./_Example_Workflows/_Example_Inputs_Files/Meshes) under ComfyUI Root Directory\ComfyUI\input folder before you can run the example workflow
- **Note:** you need to put [Example Inputs Files & Folders](_Example_Workflows/_Example_Inputs_Files/) under ComfyUI Root Directory\ComfyUI\input folder before you can run the example workflow
- Stack Orbit Camera Poses node to automatically generate all range of camera pose combinations
- You can use it to conditioning the [StableZero123 (You need to Download the checkpoint first)](https://comfyanonymous.github.io/ComfyUI_examples/3d/), with full range of camera poses in one prompt pass
- You can use it to generate the orbit camera poses and directly input to other 3D process node (e.g. GaussianSplatting and BakeTextureToMesh)
- Load 3D file (.obj, .ply, .glb)
- 3D Gaussian Splatting, with:
- [Improved Differential Gaussian Rasterization](https://github.com/ashawkey/diff-gaussian-rasterization)
@@ -80,4 +83,27 @@ Copy the files inside folder [__New_ComfyUI_Bats](./_New_ComfyUI_Bats/) to your
- Add interactive 3D UI inside ComfuUI to visulaize training and generated results for 3D representations
- Add DMTet algorithm to allow convertion from points cloud(Gaussian/.ply) to mesh (.obj, .ply, .glb)
- Add a general SDS/VSD Optimization algorithm to allow training 3D representations with diffusion model, *The real fun begins here* ;)
- Add a few best Nerf algorithms (No idea yet, [instant-ngp](https://github.com/NVlabs/instant-ngp) maybe?)
- Add a few best Nerf algorithms (No idea yet, [instant-ngp](https://github.com/NVlabs/instant-ngp) maybe?)
---
## Tips
* The world & camera coordinate system is the same as OpenGL:
```
World Camera
+y up target
| | /
| | /
|______+x |/______right
/ /
/ /
/ /
+z forward
elevation: in (-90, 90), from +y to -y is (-90, 90)
azimuth: in (-180, 180), from +z to +x is (0, 90)
```
* If you encounter OpenGL errors (e.g., `[F glutil.cpp:338] eglInitialize() failed`), then set `force_cuda_rasterize` to true on corresponding node
@@ -0,0 +1,492 @@
{
"last_node_id": 22,
"last_link_id": 25,
"nodes": [
{
"id": 10,
"type": "PreviewImage",
"pos": [
1410,
-320
],
"size": {
"0": 210,
"1": 246
},
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 4
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 9,
"type": "MaskToImage",
"pos": [
1110,
-320
],
"size": {
"0": 210,
"1": 26
},
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "mask",
"type": "MASK",
"link": 8
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "MaskToImage"
}
},
{
"id": 17,
"type": "[ComfyUI-3D] Save 3DGS",
"pos": [
2122,
54
],
"size": {
"0": 315,
"1": 58
},
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "raw_3DGS",
"type": "GS_RAW",
"link": 21
}
],
"properties": {
"Node name for S&R": "[ComfyUI-3D] Save 3DGS"
},
"widgets_values": [
"MeshTest\\3DGS_01.ply"
]
},
{
"id": 8,
"type": "InvertMask",
"pos": [
746,
-14
],
"size": {
"0": 210,
"1": 26
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "mask",
"type": "MASK",
"link": 2
}
],
"outputs": [
{
"name": "MASK",
"type": "MASK",
"links": [
8,
18
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "InvertMask"
}
},
{
"id": 18,
"type": "[ComfyUI-3D] Gaussian Splatting",
"pos": [
1486,
53
],
"size": {
"0": 468.5999755859375,
"1": 718
},
"flags": {
"collapsed": false
},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "reference_images",
"type": "IMAGE",
"link": 17
},
{
"name": "reference_masks",
"type": "MASK",
"link": 18
},
{
"name": "reference_orbit_camera_poses",
"type": "ORBIT_CAMPOSES",
"link": 25
},
{
"name": "mesh_to_initialize_gaussian",
"type": "MESH",
"link": null
}
],
"outputs": [
{
"name": "raw_3DGS",
"type": "GS_RAW",
"links": [
21
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "[ComfyUI-3D] Gaussian Splatting"
},
"widgets_values": [
49.1,
1000,
1,
10000,
0.2,
3,
0,
0,
0.5,
0.01,
0.05,
0.005,
0.005,
0.001,
0.00002,
0.02,
500,
5000,
3,
0.01,
100,
100000,
100,
700,
0.01,
0
]
},
{
"id": 7,
"type": "VHS_LoadImages",
"pos": [
113,
54
],
"size": [
243.60000610351562,
194
],
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
17,
22
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": [
2
],
"shape": 3,
"slot_index": 1
},
{
"name": "INT",
"type": "INT",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "VHS_LoadImages"
},
"widgets_values": {
"directory": "Images_enhanced",
"image_load_cap": 0,
"skip_first_images": 0,
"select_every_nth": 1,
"choose folder to upload": "image",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"frame_load_cap": 0,
"skip_first_images": 0,
"filename": "Images_enhanced",
"type": "input",
"format": "folder",
"select_every_nth": 1
}
}
}
},
{
"id": 19,
"type": "PreviewImage",
"pos": [
420,
-320
],
"size": {
"0": 210,
"1": 246
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 22
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 13,
"type": "[ComfyUI-3D] Load 3D Mesh",
"pos": [
1100,
315
],
"size": {
"0": 315,
"1": 154
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "mesh",
"type": "MESH",
"links": [],
"shape": 3,
"slot_index": 0
}
],
"title": "Load 3D Mesh [Optional]",
"properties": {
"Node name for S&R": "[ComfyUI-3D] Load 3D Mesh"
},
"widgets_values": [
"Meshes\\Cammy_Uniform.obj",
false,
true,
false,
false
]
},
{
"id": 22,
"type": "[ComfyUI-3D] Stack Orbit Camera Poses",
"pos": [
726,
160
],
"size": {
"0": 315,
"1": 586
},
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "orbit_camposes",
"type": "ORBIT_CAMPOSES",
"links": [
25
],
"shape": 3,
"slot_index": 0
},
{
"name": "orbit_radius_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "elevation_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "azimuth_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "orbit_center_X_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "orbit_center_Y_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "orbit_center_Z_list",
"type": "FLOAT",
"links": null,
"shape": 6
}
],
"properties": {
"Node name for S&R": "[ComfyUI-3D] Stack Orbit Camera Poses"
},
"widgets_values": [
1.75,
1.75,
0.1,
0,
0,
0,
0,
-0.1,
3,
0,
0,
0.1,
0,
0,
0.1,
0,
0,
0.1
]
}
],
"links": [
[
2,
7,
1,
8,
0,
"MASK"
],
[
4,
9,
0,
10,
0,
"IMAGE"
],
[
8,
8,
0,
9,
0,
"MASK"
],
[
17,
7,
0,
18,
0,
"IMAGE"
],
[
18,
8,
0,
18,
1,
"MASK"
],
[
21,
18,
0,
17,
0,
"GS_RAW"
],
[
22,
7,
0,
19,
0,
"IMAGE"
],
[
25,
22,
0,
18,
2,
"ORBIT_CAMPOSES"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
@@ -0,0 +1,610 @@
{
"last_node_id": 41,
"last_link_id": 80,
"nodes": [
{
"id": 15,
"type": "ImageOnlyCheckpointLoader",
"pos": [
-60,
239
],
"size": {
"0": 369.6000061035156,
"1": 98
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
42
],
"shape": 3,
"slot_index": 0
},
{
"name": "CLIP_VISION",
"type": "CLIP_VISION",
"links": [
50
],
"shape": 3,
"slot_index": 1
},
{
"name": "VAE",
"type": "VAE",
"links": [
26,
52
],
"shape": 3,
"slot_index": 2
}
],
"properties": {
"Node name for S&R": "ImageOnlyCheckpointLoader"
},
"widgets_values": [
"stable_zero123.ckpt"
]
},
{
"id": 3,
"type": "KSampler",
"pos": [
864,
344
],
"size": {
"0": 315,
"1": 262
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 42
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 53
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 54
},
{
"name": "latent_image",
"type": "LATENT",
"link": 55
}
],
"outputs": [
{
"name": "LATENT",
"type": "LATENT",
"links": [
7
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "KSampler"
},
"widgets_values": [
999999999,
"fixed",
10,
3,
"euler_ancestral",
"karras",
1
]
},
{
"id": 26,
"type": "StableZero123_Conditioning",
"pos": [
436,
410
],
"size": {
"0": 315,
"1": 194
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "clip_vision",
"type": "CLIP_VISION",
"link": 50
},
{
"name": "init_image",
"type": "IMAGE",
"link": 51
},
{
"name": "vae",
"type": "VAE",
"link": 52
},
{
"name": "elevation",
"type": "FLOAT",
"link": 80,
"widget": {
"name": "elevation"
}
},
{
"name": "azimuth",
"type": "FLOAT",
"link": 79,
"widget": {
"name": "azimuth"
}
}
],
"outputs": [
{
"name": "positive",
"type": "CONDITIONING",
"links": [
53
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative",
"type": "CONDITIONING",
"links": [
54
],
"shape": 3,
"slot_index": 1
},
{
"name": "latent",
"type": "LATENT",
"links": [
55
],
"shape": 3,
"slot_index": 2
}
],
"properties": {
"Node name for S&R": "StableZero123_Conditioning"
},
"widgets_values": [
256,
256,
1,
0,
145
]
},
{
"id": 23,
"type": "LoadImage",
"pos": [
-477,
430
],
"size": {
"0": 316.5220947265625,
"1": 405.7098693847656
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
51
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"Cammy_Style_0-NoBG_Square.png",
"image"
]
},
{
"id": 8,
"type": "VAEDecode",
"pos": [
1280,
258
],
"size": {
"0": 210,
"1": 46
},
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 7
},
{
"name": "vae",
"type": "VAE",
"link": 26
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
49,
74
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "VAEDecode"
}
},
{
"id": 39,
"type": "ImageListToImageBatch",
"pos": [
1584,
491
],
"size": {
"0": 210,
"1": 26
},
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 74
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
75
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageListToImageBatch"
}
},
{
"id": 38,
"type": "VHS_VideoCombine",
"pos": [
1831,
491
],
"size": [
315,
559
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 75
},
{
"name": "audio",
"type": "VHS_AUDIO",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 8,
"loop_count": 0,
"filename_prefix": "StableZero123/Test/Cammy",
"format": "video/h265-mp4",
"pix_fmt": "yuv420p10le",
"crf": 22,
"save_metadata": true,
"pingpong": false,
"save_output": true,
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "Cammy_00492.mp4",
"subfolder": "StableZero123\\Test",
"type": "output",
"format": "video/h265-mp4"
}
}
}
},
{
"id": 25,
"type": "SaveImage",
"pos": [
1582,
121
],
"size": {
"0": 671.7539672851562,
"1": 270.0038757324219
},
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 49
}
],
"properties": {},
"widgets_values": [
"StableZero123/Test/Cammy"
]
},
{
"id": 41,
"type": "[ComfyUI-3D] Stack Orbit Camera Poses",
"pos": [
-10,
540
],
"size": {
"0": 315,
"1": 586
},
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "orbit_camposes",
"type": "ORBIT_CAMPOSES",
"links": null,
"shape": 3
},
{
"name": "orbit_radius_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "elevation_list",
"type": "FLOAT",
"links": [
80
],
"shape": 6,
"slot_index": 2
},
{
"name": "azimuth_list",
"type": "FLOAT",
"links": [
79
],
"shape": 6,
"slot_index": 3
},
{
"name": "orbit_center_X_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "orbit_center_Y_list",
"type": "FLOAT",
"links": null,
"shape": 6
},
{
"name": "orbit_center_Z_list",
"type": "FLOAT",
"links": null,
"shape": 6
}
],
"properties": {
"Node name for S&R": "[ComfyUI-3D] Stack Orbit Camera Poses"
},
"widgets_values": [
0,
0,
0.1,
-45,
45,
45,
0,
0.1,
-45,
0,
0,
0.1,
0,
0,
0.1,
0,
0,
0.1
]
}
],
"links": [
[
7,
3,
0,
8,
0,
"LATENT"
],
[
26,
15,
2,
8,
1,
"VAE"
],
[
42,
15,
0,
3,
0,
"MODEL"
],
[
49,
8,
0,
25,
0,
"IMAGE"
],
[
50,
15,
1,
26,
0,
"CLIP_VISION"
],
[
51,
23,
0,
26,
1,
"IMAGE"
],
[
52,
15,
2,
26,
2,
"VAE"
],
[
53,
26,
0,
3,
1,
"CONDITIONING"
],
[
54,
26,
1,
3,
2,
"CONDITIONING"
],
[
55,
26,
2,
3,
3,
"LATENT"
],
[
74,
8,
0,
39,
0,
"IMAGE"
],
[
75,
39,
0,
38,
0,
"IMAGE"
],
[
79,
41,
3,
26,
4,
"FLOAT"
],
[
80,
41,
2,
26,
3,
"FLOAT"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 955 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+197
View File
@@ -1,8 +1,12 @@
import os
import re
import math
import copy
from enum import Enum
import folder_paths as comfy_paths
import torch
import numpy as np
from .diff_rast.diff_texturing import DiffTextureBaker
from .shared_utils.common_utils import cstr
@@ -23,6 +27,11 @@ SUPPORTED_3D_EXTENSIONS = (
'.glb',
)
ELEVATION_MIN = -90
ELEVATION_MAX = 90.0
AZIMUTH_MIN = -180.0
AZIMUTH_MAX = 180.0
class Load_3D_Mesh:
@classmethod
@@ -127,6 +136,194 @@ class Save_3DGS:
return ()
class Stack_Orbit_Camera_Poses:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"orbit_radius_start": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_radius_stop": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_radius_step": ("FLOAT", {"default": 0.1, 'step': 0.0001}),
"elevation_start": ("FLOAT", {"default": 0.0, "min": ELEVATION_MIN, "max": ELEVATION_MAX, 'step': 0.0001}),
"elevation_stop": ("FLOAT", {"default": 0.0, "min": ELEVATION_MIN, "max": ELEVATION_MAX, 'step': 0.0001}),
"elevation_step": ("FLOAT", {"default": 0.0, "min": ELEVATION_MIN, "max": ELEVATION_MAX, 'step': 0.0001}),
"azimuth_start": ("FLOAT", {"default": 0.0, "min": AZIMUTH_MIN, "max": AZIMUTH_MAX, 'step': 0.0001}),
"azimuth_stop": ("FLOAT", {"default": 0.0, "min": AZIMUTH_MIN, "max": AZIMUTH_MAX, 'step': 0.0001}),
"azimuth_step": ("FLOAT", {"default": 0.0, "min": AZIMUTH_MIN, "max": AZIMUTH_MAX, 'step': 0.0001}),
"orbit_center_X_start": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_center_X_stop": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_center_X_step": ("FLOAT", {"default": 0.1, 'step': 0.0001}),
"orbit_center_Y_start": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_center_Y_stop": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_center_Y_step": ("FLOAT", {"default": 0.1, 'step': 0.0001}),
"orbit_center_Z_start": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_center_Z_stop": ("FLOAT", {"default": 0.0, 'step': 0.0001}),
"orbit_center_Z_step": ("FLOAT", {"default": 0.1, 'step': 0.0001}),
},
}
RETURN_TYPES = (
"ORBIT_CAMPOSES", # (orbit radius, elevation, azimuth, orbit center X, orbit center Y, orbit center Z)
"FLOAT",
"FLOAT",
"FLOAT",
"FLOAT",
"FLOAT",
"FLOAT",
)
RETURN_NAMES = (
"orbit_camposes",
"orbit_radius_list",
"elevation_list",
"azimuth_list",
"orbit_center_X_list",
"orbit_center_Y_list",
"orbit_center_Z_list",
)
OUTPUT_IS_LIST = (
False,
True,
True,
True,
True,
True,
True,
)
FUNCTION = "get_camposes"
CATEGORY = "ComfyUI3D/Preprocessor"
class Pose_Config(Enum):
STOP_LARGER_STEP_POS = 0
START_LARGER_STEP_POS = 1
START_LARGER_STEP_NEG = 2
STOP_LARGER_STEP_NEG = 3
class Pose_Type:
def __init__(self, start, stop, step, min_value=-math.inf, max_value=math.inf, is_linear = True):
if abs(step) < 0.0001:
step = 0.0001 * (-1.0 if step < 0 else 1.0)
if is_linear and ( (step > 0 and stop < start) or (step < 0 and stop > start)):
cstr(f"[{self.__class__.__name__}] stop value: {stop} cannot be reached from start value {start} with step value {step}, will reverse the sign of step value to {-step}").warning.print()
self.step = -step
else:
self.step = step
self.start = start
self.stop = stop
self.min = min_value
self.max = max_value
self.is_linear = is_linear # linear or circular (i.e. min and max value are connected, e.g. -180 & 180 degree in azimuth angle) value
def stack_camposes(self, pose_type_index=None, last_camposes=[[]]):
if pose_type_index == None:
pose_type_index = len(self.all_pose_types) - 1
if pose_type_index == -1:
return last_camposes
else:
current_pose_type = self.all_pose_types[pose_type_index]
all_camposes = []
# There are four different kind of situation we need to deal with to make this function generalize for any combination of inputs
if current_pose_type.step > 0:
if current_pose_type.start < current_pose_type.stop or current_pose_type.is_linear:
pose_config = Stack_Orbit_Camera_Poses.Pose_Config.STOP_LARGER_STEP_POS
else:
pose_config = Stack_Orbit_Camera_Poses.Pose_Config.START_LARGER_STEP_POS
else:
if current_pose_type.start > current_pose_type.stop or current_pose_type.is_linear:
pose_config = Stack_Orbit_Camera_Poses.Pose_Config.START_LARGER_STEP_NEG
else:
pose_config = Stack_Orbit_Camera_Poses.Pose_Config.STOP_LARGER_STEP_NEG
p = current_pose_type.start
p_passed_min_max_seam = False
while ( (pose_config == Stack_Orbit_Camera_Poses.Pose_Config.STOP_LARGER_STEP_POS and p <= current_pose_type.stop) or
(pose_config == Stack_Orbit_Camera_Poses.Pose_Config.START_LARGER_STEP_POS and (not p_passed_min_max_seam or p <= current_pose_type.stop)) or
(pose_config == Stack_Orbit_Camera_Poses.Pose_Config.START_LARGER_STEP_NEG and p >= current_pose_type.stop) or
(pose_config == Stack_Orbit_Camera_Poses.Pose_Config.STOP_LARGER_STEP_NEG and (not p_passed_min_max_seam or p >= current_pose_type.stop)) ):
# If current pose value surpass the either min/max value then we map its vaule to the oppsite sign
if pose_config == Stack_Orbit_Camera_Poses.Pose_Config.START_LARGER_STEP_POS and p > current_pose_type.max:
p = current_pose_type.min + p % current_pose_type.max
p_passed_min_max_seam = True
elif pose_config == Stack_Orbit_Camera_Poses.Pose_Config.STOP_LARGER_STEP_NEG and p < current_pose_type.min:
p = current_pose_type.max + p % current_pose_type.min
p_passed_min_max_seam = True
new_camposes = copy.deepcopy(last_camposes)
for campose in new_camposes:
campose.insert(0, p)
all_camposes.extend(new_camposes)
p += current_pose_type.step
return self.stack_camposes(pose_type_index-1, all_camposes)
def get_camposes(self,
orbit_radius_start,
orbit_radius_stop,
orbit_radius_step,
elevation_start,
elevation_stop,
elevation_step,
azimuth_start,
azimuth_stop,
azimuth_step,
orbit_center_X_start,
orbit_center_X_stop,
orbit_center_X_step,
orbit_center_Y_start,
orbit_center_Y_stop,
orbit_center_Y_step,
orbit_center_Z_start,
orbit_center_Z_stop,
orbit_center_Z_step):
"""
Return the combination of all the pose types interpolation values
Return values in two ways:
orbit_camposes: CAMPOSES type list can directly input to other 3D process node (e.g. GaussianSplatting)
all the camera pose types seperated in different list, becasue some 3D model's conditioner only takes a sub set of all camera pose types (e.g. StableZero123)
"""
orbit_radius_list = []
elevation_list = []
azimuth_list = []
orbit_center_X_list = []
orbit_center_Y_list = []
orbit_center_Z_list = []
self.all_pose_types = []
self.all_pose_types.append( Stack_Orbit_Camera_Poses.Pose_Type(orbit_radius_start, orbit_radius_stop, orbit_radius_step) )
self.all_pose_types.append( Stack_Orbit_Camera_Poses.Pose_Type(elevation_start, elevation_stop, elevation_step, ELEVATION_MIN, ELEVATION_MAX) )
self.all_pose_types.append( Stack_Orbit_Camera_Poses.Pose_Type(azimuth_start, azimuth_stop, azimuth_step, AZIMUTH_MIN, AZIMUTH_MAX, False) )
self.all_pose_types.append( Stack_Orbit_Camera_Poses.Pose_Type(orbit_center_X_start, orbit_center_X_stop, orbit_center_X_step) )
self.all_pose_types.append( Stack_Orbit_Camera_Poses.Pose_Type(orbit_center_Y_start, orbit_center_Y_stop, orbit_center_Y_step) )
self.all_pose_types.append( Stack_Orbit_Camera_Poses.Pose_Type(orbit_center_Z_start, orbit_center_Z_stop, orbit_center_Z_step) )
orbit_camposes = self.stack_camposes()
for campose in orbit_camposes:
orbit_radius_list.append(campose[0])
elevation_list.append(campose[1])
azimuth_list.append(campose[2])
orbit_center_X_list.append(campose[3])
orbit_center_Y_list.append(campose[4])
orbit_center_Z_list.append(campose[5])
return (orbit_camposes, orbit_radius_list, elevation_list, azimuth_list, orbit_center_X_list, orbit_center_Y_list, orbit_center_Z_list, )
class Generate_Orbit_Camera_Poses:
@classmethod