Skip to content

Avoid changing scan path when stripping segments with duplicate positions#33

Open
MattRolchigo wants to merge 2 commits intomainfrom
fixup_strip_dup_locs
Open

Avoid changing scan path when stripping segments with duplicate positions#33
MattRolchigo wants to merge 2 commits intomainfrom
fixup_strip_dup_locs

Conversation

@MattRolchigo
Copy link

Previously, the short dwells added to the start of each layer would be stripped from the scan path, as they have the same x,y,z position as the subsequent segment. The modification to add_power_off_entry slightly perturbs the x position of these entries to avoid being stripped.

The modification to strip_duplicate_locations ensures that only consecutive dwells are combined, as combining multiple scan segments or combining scan segments with dwells will modify the scan path itself (could remove dwells or change the beam velocity between events). This is again accomplished by slightly perturbing the x positions of events.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts toolpath event generation/deduplication to prevent start-of-layer “power-off” dwells from being stripped and to avoid scan-path modifications caused by overly aggressive duplicate-position collapsing.

Changes:

  • Perturbs the x-position of the initial “power-off” entry added at the start of each layer to keep it from being removed as a duplicate location.
  • Updates strip_duplicate_locations so only consecutive dwells are merged; non-dwell duplicates are preserved by perturbing x to maintain event separation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +168 to +178
# This entry is as the same position as the one after it
# If both entries are dwells, they can be combined
# Otherwise, combining entries will change the scan path itself
# To avoid this, slightly perturb the position rather than combining entries
# This is necessary as adamantine cannot handle consecutive entries with the same position
if entry[2] != 0 or out[-1][2] != 0:
# Slightly perturb x position
modified_position = (entry[1][0] + eps, entry[1][1], entry[1][2])
modified_entry = (entry[0], modified_position, entry[2])
# Append this modified event
out.append(modified_entry)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

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

When two consecutive entries share the same position and one is a dwell (power==0) while the other is powered (power!=0), this logic always perturbs the earlier entry. That can end up perturbing powered scan points (e.g., where a powered point is immediately followed by a power-off point at the same location in the input layer files), which contradicts the goal of avoiding scan-path changes under power. Consider instead perturbing the dwell entry (power==0) regardless of ordering (which may require modifying out[-1] instead of entry when the dwell is the later element).

Suggested change
# This entry is as the same position as the one after it
# If both entries are dwells, they can be combined
# Otherwise, combining entries will change the scan path itself
# To avoid this, slightly perturb the position rather than combining entries
# This is necessary as adamantine cannot handle consecutive entries with the same position
if entry[2] != 0 or out[-1][2] != 0:
# Slightly perturb x position
modified_position = (entry[1][0] + eps, entry[1][1], entry[1][2])
modified_entry = (entry[0], modified_position, entry[2])
# Append this modified event
out.append(modified_entry)
# This entry is at the same position as the one after it
# If both entries are dwells, they can be combined (by dropping one)
# Otherwise, combining entries will change the scan path itself
# To avoid this, slightly perturb the position rather than combining entries.
# This is necessary as adamantine cannot handle consecutive entries with the same position.
# Prefer perturbing a dwell (power == 0) rather than a powered point.
if entry[2] == 0 and out[-1][2] == 0:
# Both entries are dwells: combine by keeping only the later one in time (already in out)
# Do not append the earlier dwell entry.
continue
elif entry[2] == 0 and out[-1][2] != 0:
# Current entry is a dwell and the later entry is powered: perturb this dwell
modified_position = (entry[1][0] + eps, entry[1][1], entry[1][2])
modified_entry = (entry[0], modified_position, entry[2])
out.append(modified_entry)
elif entry[2] != 0 and out[-1][2] == 0:
# Current entry is powered and the later entry is a dwell: perturb the dwell in-place
prev_time, prev_pos, prev_power = out[-1]
modified_position = (prev_pos[0] + eps, prev_pos[1], prev_pos[2])
out[-1] = (prev_time, modified_position, prev_power)
# Append the powered entry unchanged
out.append(entry)
else:
# Both entries are powered: perturb the earlier entry as before
modified_position = (entry[1][0] + eps, entry[1][1], entry[1][2])
modified_entry = (entry[0], modified_position, entry[2])
out.append(modified_entry)

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

It doesn't matter which entry or entries get perturbed, since the perturbation is small enough as to not affect the scan path. As long as consecutive entries do not have the same position, it is fine.

Comment on lines +167 to +178
else:
# This entry is as the same position as the one after it
# If both entries are dwells, they can be combined
# Otherwise, combining entries will change the scan path itself
# To avoid this, slightly perturb the position rather than combining entries
# This is necessary as adamantine cannot handle consecutive entries with the same position
if entry[2] != 0 or out[-1][2] != 0:
# Slightly perturb x position
modified_position = (entry[1][0] + eps, entry[1][1], entry[1][2])
modified_entry = (entry[0], modified_position, entry[2])
# Append this modified event
out.append(modified_entry)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

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

Because duplicates are resolved in a single reverse pass, perturbing an entry to avoid a scan/dwell collision can prevent earlier consecutive dwells from being combined. Example pattern: dwell@P, dwell@P, scan@P will perturb the second dwell (to avoid matching the scan) and then the first dwell no longer matches it, so the two dwells are not combined and an extra micro-move is introduced during power-off time. To ensure only consecutive dwells are combined, consider collapsing adjacent dwell runs (power==0) at identical positions before applying the non-dwell perturbation rule (or do a forward pass that handles dwell/dwell first).

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

A situation where multiple consecutive segments at the same location occur with non-zero and zero power would be rare, and whether or not the dwells are combined in such a case won't affect the overall result as the applied perturbation to the location is minor to begin with

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