Skip to content

Feature/heart shape tool integration#4167

Open
Ayush2k02 wants to merge 2 commits into
GraphiteEditor:masterfrom
Ayush2k02:feature/heart-shape-tool-integration
Open

Feature/heart shape tool integration#4167
Ayush2k02 wants to merge 2 commits into
GraphiteEditor:masterfrom
Ayush2k02:feature/heart-shape-tool-integration

Conversation

@Ayush2k02
Copy link
Copy Markdown
Contributor

Add Heart drawing mode to the Shape tool with gizmo registration

@Ayush2k02 Ayush2k02 force-pushed the feature/heart-shape-tool-integration branch from c8f4faa to 125a795 Compare May 25, 2026 09:36
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 7 files

Confidence score: 3/5

  • There is a concrete medium-severity risk in node-graph/nodes/vector/src/generator_nodes.rs: when cleavage_angle is 0, the handles collapse to the same side of the anchor, creating a cusp (tangent reversal) instead of the documented smooth join behavior.
  • Because this is high-confidence (9/10) and affects generated curve geometry, it could produce visible user-facing shape artifacts if merged as-is.
  • This looks contained to a specific parameter/behavior rather than a broad architectural problem, so the PR may still be mergeable with a targeted fix or follow-up.
  • Pay close attention to node-graph/nodes/vector/src/generator_nodes.rs - verify cleavage_angle=0 handling matches the doc contract and avoids cusp formation.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="node-graph/nodes/vector/src/generator_nodes.rs">

<violation number="1" location="node-graph/nodes/vector/src/generator_nodes.rs:196">
P2: Doc comment for `cleavage_angle` claims zero produces a smooth join, but when angle is zero both in and out handles collapse to the same point on the same side of the anchor, producing a cusp (180° tangent reversal) instead of a smooth curve</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

#[hard_min(0.)]
#[hard_max(0.6)]
cleavage_depth: f64,
/// Half-angle of the top V. Zero collapses the V into a smooth join.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Doc comment for cleavage_angle claims zero produces a smooth join, but when angle is zero both in and out handles collapse to the same point on the same side of the anchor, producing a cusp (180° tangent reversal) instead of a smooth curve

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At node-graph/nodes/vector/src/generator_nodes.rs, line 196:

<comment>Doc comment for `cleavage_angle` claims zero produces a smooth join, but when angle is zero both in and out handles collapse to the same point on the same side of the anchor, producing a cusp (180° tangent reversal) instead of a smooth curve</comment>

<file context>
@@ -179,6 +179,110 @@ fn regular_polygon<T: AsU64>(
+	#[hard_min(0.)]
+	#[hard_max(0.6)]
+	cleavage_depth: f64,
+	/// Half-angle of the top V. Zero collapses the V into a smooth join.
+	#[default(45.)]
+	#[range((0., 89.))]
</file context>

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new parametric Heart shape to the vector toolset. The implementation includes a new heart generator node with extensive parametric controls for cleavage, lobes, shoulders, and taper, alongside the necessary integration into the shape tool UI, FSM, and gizmo management system. Review feedback highlights a potential division-by-zero error when drawing shapes with zero dimensions and suggests a vertical offset adjustment in the generator node to ensure the heart is correctly centered within its local coordinate space.

Comment on lines +90 to +98
let mut scale = DVec2::ONE;
let radius: f64;
if dimensions.x > dimensions.y {
scale.x = dimensions.x / dimensions.y;
radius = dimensions.y / 2.;
} else {
scale.y = dimensions.y / dimensions.x;
radius = dimensions.x / 2.;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Potential division by zero or NaN result if dimensions.x or dimensions.y is zero (e.g., if the user clicks without dragging). This can lead to invalid transforms and rendering issues. A check should be added to ensure dimensions are non-zero before calculating the scale.

			if dimensions.x < 1e-6 || dimensions.y < 1e-6 {
				return;
			}

			let mut scale = DVec2::ONE;
			let radius: f64;
			if dimensions.x > dimensions.y {
				scale.x = dimensions.x / dimensions.y;
				radius = dimensions.y / 2.;
			} else {
				scale.y = dimensions.y / dimensions.x;
				radius = dimensions.x / 2.;
			}

Comment on lines +255 to +258
// Anchor points for the right half plus the y-axis cusps, in normalized coordinates (y points downward).
let top = DVec2::new(0., -1. + cleavage_depth);
let shoulder = DVec2::new(shoulder_width, -shoulder_height);
let bottom = DVec2::new(0., 1.);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The heart shape is not centered at (0, 0) in its local coordinate space. The vertical range is from -1 + cleavage_depth to 1, meaning the midpoint is at cleavage_depth / 2. This causes the heart to appear shifted when drawn from the center or within a bounding box. It's better to offset the Y coordinates by cleavage_depth / 2 to center the shape.

Suggested change
// Anchor points for the right half plus the y-axis cusps, in normalized coordinates (y points downward).
let top = DVec2::new(0., -1. + cleavage_depth);
let shoulder = DVec2::new(shoulder_width, -shoulder_height);
let bottom = DVec2::new(0., 1.);
// Anchor points for the right half plus the y-axis cusps, in normalized coordinates (y points downward).
let y_offset = cleavage_depth / 2.;
let top = DVec2::new(0., -1. + cleavage_depth - y_offset);
let shoulder = DVec2::new(shoulder_width, -shoulder_height - y_offset);
let bottom = DVec2::new(0., 1. - y_offset);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants