Add new StackOrbitCameraPoses node to auto conditioning StableZero123 & 3DGS etc.
This commit is contained in:
@@ -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
|
||||
+492
@@ -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.
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user