175 Commits
Author SHA1 Message Date
PozzettiAndrea b2e82233cb comfy-env-root.toml: [node_reqs] is now [node_packs]
The section never held nodes -- every entry is a whole pack repo. Read
literally, `[node_reqs]` says "the requirements of my node", which is pip
packages, and that section genuinely exists one file over as [dependencies]
in comfy-env.toml. `[node_packs]` names the unit and sits parallel to the
existing [cuda_packages].

Requires comfy-env >= 0.4.27, which renames the key with no shim: the root
file has a closed schema, so an old comfy-env rejects [node_packs] by name
and a new one rejects [node_reqs] by name. Neither fails silently.
2026-08-24 15:48:51 +02:00
PozzettiAndrea f972dcda49 Drop comfy-3d-viewers, modernise comfy-test.toml
Vendor the viewer JavaScript into javascript/ and drop the
comfy-3d-viewers dependency. The viewers were previously copied into web/ at
every startup by prestartup_script.py, which made the served frontend depend on
a second package resolving at runtime.

Bundles are vendored as .mjs so ComfyUI's **/*.js auto-import glob skips them:
they are iframe-only and must never enter the shared main browser realm. Only
the widget entry points stay .js.

Also replace comfy_env.copy_files with a local helper. Its two extra features
(frame-derived source dir, silent no-op on a missing source) were unused here,
and the asset seeding now resolves the input directory through
folder_paths.get_input_directory() so it follows ComfyUI Desktop and
--input-directory instead of writing into the code tree.

comfy-test.toml moves to the current schema: [test.workflows] cuda (there is no
"gpu" key -- the accelerator is named by backend, and the old spelling parsed to
an empty list, so CUDA runners silently ran the full unfiltered set), an
explicit [test.platforms] platforms allowlist (per-platform booleans are no
longer supported), and the javascript level.
2026-08-22 19:44:03 +02:00
PozzettiAndrea 7ecc6d81ac add comfy-kitchen dep 2026-07-31 16:40:10 +02:00
PozzettiAndrea 67948de30f add gsplat wheel for fallback 2026-06-08 00:09:46 +02:00
PozzettiAndrea bc8f98d214 retry download 2026-06-07 23:16:01 +02:00
PozzettiAndrea d3c12aed8b shrink eth3d asset 2026-06-07 21:59:31 +02:00
PozzettiAndrea f2f0983e2e all workflows tested for gpu 2026-06-07 21:13:58 +02:00
PozzettiAndrea 93ef327b54 fix autocast 2026-06-07 21:12:03 +02:00
PozzettiAndrea 65b63841fa no more cp1252 problems 2026-06-07 21:03:15 +02:00
Andrea Pozzetti e6819a1c6a Update README.md 2026-06-07 20:22:36 +02:00
Andrea Pozzetti 3780b79f82 Update README.md 2026-06-07 20:22:11 +02:00
PozzettiAndrea 7595253bbd delay comfy env update 2026-06-07 20:15:14 +02:00
PozzettiAndrea 8fe04a3d42 new pano wf 2026-06-07 20:14:59 +02:00
PozzettiAndrea 1fe1a33498 remove geometrypack from dependencies 2026-06-07 19:50:22 +02:00
PozzettiAndrea 7a8506a221 any trimesh 2026-06-07 19:44:12 +02:00
PozzettiAndrea 3e54956332 better logging 2026-06-07 16:14:26 +02:00
PozzettiAndrea df4875e44d better depth 2026-06-04 20:36:16 +02:00
PozzettiAndrea d9b842ae95 best pano workflow till now 2026-06-04 19:07:51 +02:00
PozzettiAndrea ad9c5b7012 trimmed python nodes 2026-06-04 15:54:55 +02:00
PozzettiAndrea 6fc8909b44 trim workflows 2026-06-04 15:51:35 +02:00
PozzettiAndrea 8a35d88363 support different formats of K 2026-06-03 11:48:25 +02:00
PozzettiAndrea e258f803a6 final sharp pano 2026-06-02 02:51:24 +02:00
Andrea Pozzetti 04452c15a2 predict_metric_depth: emit layer_0/1_points_raw point-map outputs
Adds two new IMAGE outputs (B, 1536, 1536, 3) — per-pixel (X, Y, Z) in
camera space — alongside the existing scalar metric_depth outputs.
Mirrors MoGe2Inference's depth_raw / points_raw pairing so SHARP can
feed PanoramaDepthMerge.face_points directly.

Motivation: PanoramaDepthMerge.face_points expects a 3D point map, not
a depth scalar. Wiring layer_0_metric_depth (which is depth replicated
to 3 channels for IMAGE compatibility) into face_points silently
produced wrong geometry: the merger's ||points|| computation gave
||(d, d, d)|| = d × sqrt(3) per pixel and treated it as ray distance,
inflating everything by ~73% with no shape-mismatch error.

The new points are computed as:
  x_cam = (u - cx) / fx
  y_cam = (v - cy) / fy
  points[u, v] = (x_cam * Z, y_cam * Z, Z)
By construction ||points|| equals the correct ray distance — what
PanoramaDepthMerge consumes via np.linalg.norm. Intrinsics rescaled to
the 1536² depth grid via the same sx/sy ratio used elsewhere; relies
on the existing fx<2.0 normalized-K sniff at the top of execute() so
PanoPack-style normalized K is auto-converted before the math runs.

Output socket order: layer_0_metric_depth, layer_1_metric_depth,
extrinsics_mdepth, intrinsics_mdepth, layer_0_points_raw,
layer_1_points_raw. New outputs appended at the END so existing
workflows that wired extrinsics_mdepth / intrinsics_mdepth by slot
index continue to work — those slots (2, 3) are unchanged.

Log line gains a ||v|| range for the layer-0 point map so the user can
sanity-check that depth × unprojection produced scene-scale 3D
positions (||v|| ≈ Z at face centers, ~sqrt(3)·Z at 90° face corners).
2026-05-29 08:54:41 +02:00
PozzettiAndrea 082d755b03 pano 2026-05-29 00:24:18 +02:00
Andrea Pozzetti c37c544b33 Add SharpRayToPlanarDepth — standalone ray-distance → planar-Z node
Single-responsibility conversion node that sits between a depth source
(e.g. PanoramaSplit on an equirect depth pano) and SHARP's predict
node. Makes the convention boundary visible in the graph instead of
hiding it as a 'depth_convention' toggle inside the predict node.

Inputs:
  image       IMAGE       — per-face depth in ray-distance convention
  intrinsics  INTRINSICS  — per-face K (normalized or pixel, auto-detected)
  extrinsics  EXTRINSICS  — pass-through (optional, not used in the math)

Outputs:
  image       IMAGE       — per-face depth in planar-Z convention
  extrinsics  EXTRINSICS  — pass-through
  intrinsics  INTRINSICS  — pass-through, rescaled to pixel-K if input
                            was normalized (consistent units downstream)

Math: planar_z = ray_distance × cos_map where
  cos_map[u, v] = 1 / sqrt(((u-cx)/fx)² + ((v-cy)/fy)² + 1)

Inherits the same fx<2.0 normalized-K sniff added to the three Sharp
predict nodes earlier this cycle, so workflows that wire PanoPack's
utils3d-style normalized intrinsics get auto-rescaled to pixel-K.

Predict-side note: SharpPredictGaussiansFromMetricDepth still has the
'depth_convention' input -- now redundant when this node is used.
Workflows can drop the toggle (use default planar_z) and instead wire
ray-distance depth through SharpRayToPlanarDepth first. Keeping the
toggle in place so existing workflows don't break; deprecation /
removal is a later cleanup.
2026-05-29 00:17:23 +02:00
Andrea Pozzetti e4521fd768 Apply same normalized-K sniff to predict_gaussian_attrs
predict_gaussian_attrs.py had the same f_px = K[0,0] * (1536/width)
pattern as predict_metric_depth.py and predict_gaussians_from_depth.py
-- silent collapse to ~0 depth when fed PanoPack's normalized K.

Same fix: rescale to pixel-K once before computing f_px. Logged via
the existing _p() helper. Now all three predict nodes accept either
pixel-K (Sharp's native convention) or normalized-K (PanoPack /
utils3d) without manual conversion in the workflow.

predict.py (single-image SharpPredict) uses K[0,0] directly with no
rescale, so it'd fail differently with normalized K -- but that path
isn't used from panorama workflows so leaving it alone.
2026-05-28 23:18:54 +02:00
Andrea Pozzetti cae22441a8 Fix blank depth from SharpPredictMetricDepth on normalized PanoPack K
Same root cause as the prior NaN-cascade fix in
predict_gaussians_from_depth.py: PanoPack's PanoramaSplit emits K via
utils3d.np.intrinsics_from_fov which is normalized (fx≈0.5, cx≈0.5
for 90° fov in [0,1] units). Sharp's predict path assumes pixel-K
(fx≈hundreds). With normalized K:
  f_px = K[0,0] * (1536 / width) = 0.5 * 1 = 0.5
  disparity_factor_scalar = 0.5 / 1536 ≈ 3.3e-4
  metric_depth = 3.3e-4 / disparity ≈ 0
Result: depth maps come out blank (all near-zero).

Add the same fx<2.0 sniff at the top of execute(), in the else-branch
of 'if intrinsics is None'. Rescales K to pixel-K for the face image's
(width, height) before any downstream code touches it -- so f_px, the
per-face disparity-to-depth division, and _rescale_K to 1536² all see
the same convention.

Also retitle the no-K-wired log line from 'SharpPanoramaIcosahedronSplit'
to 'PanoramaSplit' since the former was deleted in the previous commit.
2026-05-28 23:17:48 +02:00
Andrea Pozzetti 6e9355250c Fix NaN cascade from normalized intrinsics + delete unused nodes
Two fixes in one commit since they're related to the user's panorama
pipeline:

1. predict_gaussians_from_depth.py: detect normalized intrinsics.
   PanoPack's PanoramaSplit emits K via utils3d.np.intrinsics_from_fov
   which returns NORMALIZED K (fx=0.5, cx=0.5 for 90 deg fov, units in
   [0,1]). Sharp's predict node assumed pixel-K (fx=hundreds). With the
   new ray_distance cos_map this produced:
     x_cam at uu=1535 = (1535 - 0.5)/0.5 = 3069
     cos_map at corner = 1/sqrt(2*3069^2 + 1) = 0.0002
   The depth was then multiplied by ~0 and SHARP's unprojection
   exploded to NaN. Add a one-line sniff (fx < 2.0 => normalized) at
   the top of the intrinsics path that rescales to pixel-K once. All
   downstream uses (f_px, cos_map, unprojection K) see the same
   pixel-K convention.

2. Delete three nodes per user request:
     - SharpPanoramaIcosahedronSplit (panorama_icosahedron_split.py)
     - SharpDepthMerge              (depth_merge.py)
     - SharpBuildMesh               (build_mesh.py)
   Their functionality lives in ComfyUI-PanoPack (PanoramaSplit,
   PanoramaDepthMerge) and the mesh path moved elsewhere. nodes/__init__.py
   loses six import lines + six update lines for the three modules. The
   prior commit on this branch had already pruned the imports + the
   NODE_CLASS_MAPPINGS.update calls, but left orphan
   NODE_DISPLAY_NAME_MAPPINGS.update lines referring to the now-undefined
   variables -- which broke the pack's import chain at startup. Pruned
   those too.

Workflows that referenced the deleted classes will show broken nodes
until edited to use PanoPack equivalents -- this is expected and
matches the explicit deletion request.
2026-05-28 23:07:17 +02:00
Andrea Pozzetti 7df471a42c Move ray-distance -> planar-Z conversion into the depth consumer
The cos-map conversion that turned equirect ray-distance depth into
per-face planar-Z used to live as a 'convert_distance_to_planar'
toggle on SharpPanoramaIcosahedronSplit. That node is supposed to be
a generic pano->faces resampler; depth semantics aren't its concern.

Move the conversion onto SharpPredictGaussiansFromMetricDepth, which
is the actual depth consumer and already receives the per-face
intrinsics it needs to build the same cos-map. Add a
'depth_convention' combo input there ('planar_z' default, or
'ray_distance' for panorama-derived depth). cos-map is applied at
the depth's native resolution before the resize to 1536^2, so the
convention boundary isn't smeared by bilinear interp. Falls back to
a synthetic K from focal_length_mm + (width,height) if intrinsics
isn't wired -- never silently skips when the user asked for the
conversion.

SharpPanoramaIcosahedronSplit loses the toggle, the conditional
cos-map block, and the parameter -- back to being a pure resampler.

Workflow JSONs updated: pano.json (split id=48 / predict id=53) and
final.json (splits 87 + 134, predicts 83 + 118). The two splits that
previously had convert_distance_to_planar=True now feed predicts
configured with depth_convention='ray_distance'; the one split
(node 134) that had it False loses the toggle without downstream
changes.

Pre-existing bug NOT touched here: final.json node id=118's
widgets_values has been misaligned vs its schema since
snap_to_external_depth was added -- value 0 reads as 30 at the
snap slot. My edit inserted 'ray_distance' at the correct
structural position; the schema mismatch on the OTHER positions
predates this commit.
2026-05-28 22:51:54 +02:00
PozzettiAndrea 1da605ee28 add panopack to comfy env root 2026-05-28 22:37:21 +02:00
PozzettiAndrea 9dc08bccb9 pano update 2026-05-28 22:37:01 +02:00
PozzettiAndrea b1eb58128c final splat with locked gaussian depth 2026-05-27 22:05:03 +02:00
PozzettiAndrea 87e198137a update readme 2026-05-27 18:11:57 +02:00
PozzettiAndrea 33385a6657 add sharp arch diagram as docs 2026-05-27 18:11:47 +02:00
PozzettiAndrea 184a384cb9 bunch of useful nodes 2026-05-27 15:51:17 +02:00
PozzettiAndrea 9ae3009584 add open3d to conda deps 2026-05-27 13:14:42 +02:00
PozzettiAndrea 495d44bf81 demoted some prints to debug level 2026-05-27 13:08:58 +02:00
PozzettiAndrea 1146850fae add trimesh to base 2026-05-27 13:07:48 +02:00
PozzettiAndrea b4059ea8ff no open3d 2026-05-27 13:02:40 +02:00
PozzettiAndrea 73ab7b9a68 added mesh building 2026-05-27 12:59:35 +02:00
PozzettiAndrea 344051f3e2 added icosahedron merge 2026-05-26 22:50:11 +02:00
PozzettiAndrea 695987087b bump 2026-05-19 17:52:04 +02:00
PozzettiAndrea 6891efa5b5 docs: warn about experimental comfy-env install in README + pyproject 2026-05-16 21:38:31 +02:00
PozzettiAndrea 164f0e71c0 trigger ci (comfy-test v0.3.103) 2026-05-15 11:00:39 +02:00
PozzettiAndrea 03f1f97c25 comfy-env 0.3.89 2026-05-15 08:19:06 +02:00
PozzettiAndrea e63db66b51 comfy-env 0.3.88 2026-05-15 07:16:52 +02:00
PozzettiAndrea f1783e1843 bump 2026-05-14 14:26:22 +02:00
PozzettiAndrea a957ef25c4 bump 2026-05-13 12:58:01 +02:00
PozzettiAndrea 34a5ac7a2d add transformers 2026-05-13 10:17:39 +02:00
PozzettiAndrea 9ee023dd89 comfy-env 0.3.87 2026-05-13 09:47:09 +02:00