fix(assembly): update flip-detection baseline during drag steps #312

Merged
forbes merged 1 commits from fix/assembly-drag-flip-detection into main 2026-02-21 15:59:57 +00:00
Owner

Problem

During drag operations, validateNewPlacements() compared each solver result against the pre-drag positions saved once in preDrag(). As the user dragged further, the cumulative rotation from that fixed baseline easily exceeded the 91-degree threshold, causing valid intermediate results to be rejected with "flipped orientation" warnings (107–155+ degrees observed) and making parts appear to explode.

Root Cause

preDrag() calls savePlacementsForUndo() once to capture baseline positions. Each doDragStep() then calls validateNewPlacements() which compares the solver result against that fixed baseline. For large or rotational drags, the cumulative angle from pre-drag to current state easily exceeds 91 degrees — even though each incremental step is small and valid.

Fix

Call savePlacementsForUndo() after each accepted drag step (after setNewPlacements() succeeds in doDragStep()). This updates the baseline so the flip check compares against the last accepted state rather than the original pre-drag origin.

The non-drag solve() path is unaffected — it still saves once before solving and validates against that single baseline, which is correct for one-shot solves.

Testing

  1. Open an assembly with joints
  2. Drag a constrained part through a large rotation (>90 degrees)
  3. Before fix: Part "explodes" with warnings like Ignoring bad solve, part (X) flipped orientation (155.5 degrees)
  4. After fix: Part follows the drag smoothly through the full rotation
## Problem During drag operations, `validateNewPlacements()` compared each solver result against the pre-drag positions saved once in `preDrag()`. As the user dragged further, the cumulative rotation from that fixed baseline easily exceeded the 91-degree threshold, causing valid intermediate results to be rejected with "flipped orientation" warnings (107–155+ degrees observed) and making parts appear to explode. ## Root Cause `preDrag()` calls `savePlacementsForUndo()` once to capture baseline positions. Each `doDragStep()` then calls `validateNewPlacements()` which compares the solver result against that fixed baseline. For large or rotational drags, the cumulative angle from pre-drag to current state easily exceeds 91 degrees — even though each incremental step is small and valid. ## Fix Call `savePlacementsForUndo()` after each accepted drag step (after `setNewPlacements()` succeeds in `doDragStep()`). This updates the baseline so the flip check compares against the last accepted state rather than the original pre-drag origin. The non-drag `solve()` path is unaffected — it still saves once before solving and validates against that single baseline, which is correct for one-shot solves. ## Testing 1. Open an assembly with joints 2. Drag a constrained part through a large rotation (>90 degrees) 3. **Before fix:** Part "explodes" with warnings like `Ignoring bad solve, part (X) flipped orientation (155.5 degrees)` 4. **After fix:** Part follows the drag smoothly through the full rotation
forbes added 1 commit 2026-02-21 15:59:23 +00:00
fix(assembly): update flip-detection baseline during drag steps
Some checks failed
Build and Test / build (pull_request) Has been cancelled
5d55f091d0
During drag operations, validateNewPlacements() compared each solver
result against the pre-drag positions saved once in preDrag().  As the
user dragged further, the cumulative rotation from that fixed baseline
easily exceeded the 91-degree threshold, causing valid intermediate
results to be rejected with 'flipped orientation' warnings and making
parts appear to explode.

Fix: call savePlacementsForUndo() after each accepted drag step so
that the flip check compares against the last accepted state rather
than the original pre-drag origin.
forbes merged commit f65a4a5e2b into main 2026-02-21 15:59:57 +00:00
forbes deleted branch fix/assembly-drag-flip-detection 2026-02-21 15:59:57 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#312