feat(cutout): implement boundary padding for cutout textures
- Introduced a new `Boundary Padding` preference in the Cutout Tool with a default of 2 px and a configurable range of 1-4 px. - Updated the Cutout client to establish inward mapping from the final Mask, sampling in a fixed direction and processing independent material RGBA and Depth. - Enhanced the handling of RGBA and Depth during cutout operations, ensuring proper mapping and preservation of source data. - Added tests to validate the new boundary padding functionality and its integration with existing cutout processes. feat(geometry): remove overall mesh smoothing from geometry nodes - Removed the `Smooth` input from several geometry node groups to eliminate unnecessary overall mesh smoothing. - Retained `Smooth Weight` for depth nodes while removing it from Cutout and Relief Plane nodes. - Ensured that boundary, normal, and fill smoothing behaviors remain intact and consistent. - Updated tests and documentation to reflect the changes in node interfaces and behaviors. feat(normals): scale tangent normals with depth - Reused the existing `o_normal_reduction` attribute to adjust Tangent Normal strength based on the geometry's `Depth Scale`. - Ensured that Tangent Normal strength is consistent with the geometry depth, preserving full strength for materials that do not provide the attribute. - Updated tests to verify the correct behavior of normal strength adjustments in both Tangent and Object Space.
This commit is contained in:
2
openspec/changes/auto-crop-panorama-input/.openspec.yaml
Normal file
2
openspec/changes/auto-crop-panorama-input/.openspec.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-09-14
|
||||
45
openspec/changes/auto-crop-panorama-input/design.md
Normal file
45
openspec/changes/auto-crop-panorama-input/design.md
Normal file
@@ -0,0 +1,45 @@
|
||||
## Context
|
||||
|
||||
Convert to Panorama currently validates `width == height * 2` before it exports the source color image. The shared color-input helper already accepts pixel bounds and uses the resulting file for both material color and AI analysis, so the crop can be applied once at the Blender boundary without changing the server job or duplicating image processing.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Derive a deterministic, centered, exact 2:1 integer-pixel crop from any usable static source image.
|
||||
- Use the same cropped pixels for AI analysis and the generated panorama material.
|
||||
- Warn users whenever the prepared input omits source pixels.
|
||||
- Keep exact 2:1 inputs unchanged.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Padding, stretching, resampling, or content-aware crop positioning.
|
||||
- Repairing an image that is not actually an equirectangular panorama.
|
||||
- Changing server inference, panorama fusion, output metadata, or node groups.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Compute the largest centered exact 2:1 pixel rectangle
|
||||
|
||||
Let `crop_height = min(source_height, source_width // 2)` and `crop_width = crop_height * 2`. Center these dimensions independently within the source using integer offsets. This retains the maximum possible source area, handles both wide and tall images, and removes one unavoidable column from odd-width inputs. Integer floor placement gives deterministic bounds when the discarded pixels cannot be split equally.
|
||||
|
||||
Padding would preserve all pixels but introduce artificial panorama regions. Resizing would distort the projection. Both are less faithful than an explicit crop.
|
||||
|
||||
### Select bounds before preparing the shared color input
|
||||
|
||||
Add a small reusable image-bound calculation in the appropriate `common` image module, then pass those bounds to `prepare_material_color_input`. `material_analysis_input` will continue to derive its input from that exported color file. This guarantees that inference and the material see identical framing while retaining existing HDR, color-space, alpha, temporary-file, and cleanup behavior.
|
||||
|
||||
Cropping only the analysis preview was rejected because the generated material and inferred geometry would then use different angular content.
|
||||
|
||||
### Warn at the public operator boundary
|
||||
|
||||
`ConvertToPanorama` will emit one Blender `WARNING` report after determining that the crop differs from the source. The message will state original and cropped pixel dimensions. Exact 2:1 sources will not report a warning. Animated images and inputs for which the computed crop has zero width or height remain errors.
|
||||
|
||||
The warning belongs at the public operator boundary because that is where source dimensions and user feedback are both available; it does not need to become part of the job protocol.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Centered cropping can remove important edge content] → Make the crop explicit through a warning with dimensions; interactive crop selection remains outside this change.
|
||||
- [Odd discarded pixel counts make perfect geometric centering impossible] → Use stable integer floor offsets and test the exact bounds.
|
||||
- [Very narrow images cannot yield a positive 2:1 integer crop] → Keep a clear validation error for widths below two pixels or otherwise invalid dimensions.
|
||||
- [Warning timing could imply success before setup or submission later fails] → Report the warning as part of input preparation, while preserving normal error reporting for subsequent failures.
|
||||
27
openspec/changes/auto-crop-panorama-input/proposal.md
Normal file
27
openspec/changes/auto-crop-panorama-input/proposal.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## Why
|
||||
|
||||
Convert to Panorama currently rejects any image whose pixel dimensions are not exactly 2:1, so even a nearly compliant panorama cannot be processed. Panorama conversion should accept arbitrary static image aspect ratios by preparing a valid 2:1 input automatically while making the loss of edge content visible to the user.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Accept static panorama source images regardless of their original aspect ratio.
|
||||
- Center-crop the source to the largest integer-pixel 2:1 region before preparing both the AI analysis input and panorama color material.
|
||||
- Report a warning when any rows or columns are removed, including the original and cropped dimensions.
|
||||
- Preserve the existing behavior without a warning when the source dimensions are already exactly 2:1.
|
||||
- Continue rejecting animated or unusably small images that cannot produce a positive 2:1 crop.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `panorama-input-cropping`: Defines validation, centered 2:1 crop selection, prepared panorama inputs, and user warning behavior.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
None.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affects the Blender-side Convert to Panorama operator and shared material color input preparation used by its job submission.
|
||||
- Adds focused operator and image-preparation tests for wide, tall, odd-width, already-2:1, animated, and unusably small inputs.
|
||||
- Does not change the panorama job protocol, server geometry pipeline, model dependencies, or node assets.
|
||||
@@ -0,0 +1,42 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Panorama input uses an exact centered 2:1 crop
|
||||
The system SHALL prepare panorama conversion from the largest centered integer-pixel rectangle whose width is exactly twice its height. The prepared color material and AI analysis input MUST use the same cropped pixels without stretching, padding, or aspect-ratio resampling.
|
||||
|
||||
#### Scenario: Source is wider than 2:1
|
||||
- **WHEN** a user converts a usable static image whose width is greater than twice its height
|
||||
- **THEN** the system crops columns equally where possible from the left and right and prepares an exact 2:1 input at the source height
|
||||
|
||||
#### Scenario: Source is narrower than 2:1
|
||||
- **WHEN** a user converts a usable static image whose width is less than twice its height
|
||||
- **THEN** the system crops rows equally where possible from the top and bottom and prepares the largest exact 2:1 input at or below the source width
|
||||
|
||||
#### Scenario: Source width is odd
|
||||
- **WHEN** a usable static source has an odd width that cannot be part of an exact integer-pixel 2:1 rectangle
|
||||
- **THEN** the system omits the unmatched column as part of its deterministic centered crop
|
||||
|
||||
#### Scenario: Source is already 2:1
|
||||
- **WHEN** a user converts a usable static image whose width is exactly twice its height
|
||||
- **THEN** the system prepares the full source image without removing pixels
|
||||
|
||||
### Requirement: Panorama crop is disclosed to the user
|
||||
The system SHALL issue one warning whenever panorama input preparation removes source pixels, and the warning MUST identify both the original and cropped pixel dimensions.
|
||||
|
||||
#### Scenario: Conversion requires cropping
|
||||
- **WHEN** the computed 2:1 bounds differ from the source bounds
|
||||
- **THEN** the system reports a warning containing the source width and height and the cropped width and height
|
||||
|
||||
#### Scenario: Conversion does not require cropping
|
||||
- **WHEN** the source bounds already form an exact 2:1 image
|
||||
- **THEN** the system does not report a crop warning
|
||||
|
||||
### Requirement: Unsupported panorama sources remain rejected
|
||||
The system MUST reject animated images and images too small to produce a positive integer-pixel 2:1 crop before submitting panorama generation.
|
||||
|
||||
#### Scenario: Source is animated
|
||||
- **WHEN** a user attempts to convert an animated image
|
||||
- **THEN** the system reports an error and does not submit panorama generation
|
||||
|
||||
#### Scenario: Source cannot produce a positive crop
|
||||
- **WHEN** a source image cannot provide at least a 2-pixel-wide by 1-pixel-high crop
|
||||
- **THEN** the system reports an error and does not submit panorama generation
|
||||
15
openspec/changes/auto-crop-panorama-input/tasks.md
Normal file
15
openspec/changes/auto-crop-panorama-input/tasks.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## 1. Crop Bounds
|
||||
|
||||
- [x] 1.1 Add a common helper that returns the largest deterministic centered exact 2:1 integer-pixel bounds and rejects dimensions that cannot produce a positive crop
|
||||
- [x] 1.2 Add focused tests for exact, wide, tall, odd-width, uneven-margin, and unusably small dimension cases
|
||||
|
||||
## 2. Panorama Conversion
|
||||
|
||||
- [x] 2.1 Update Convert to Panorama to keep animated-image validation, compute the crop bounds, and pass them into the shared material color input preparation
|
||||
- [x] 2.2 Report one crop warning with original and cropped dimensions only when pixels are removed
|
||||
- [x] 2.3 Update panorama operator tests to verify arbitrary aspect ratios submit cropped color and analysis inputs, exact 2:1 input stays unchanged, and unsupported sources remain rejected
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 Run the related common image and panorama conversion test suites and confirm they pass
|
||||
- [x] 3.2 Inspect the final diff and search the panorama conversion path to confirm the strict 2:1 rejection and stale expectations are removed
|
||||
Reference in New Issue
Block a user