Compare commits

..

159 Commits

Author SHA1 Message Date
Joseph Robertson
ac9b5433b7 Belt printer: regression fixes + Belt Printer Brims (#15155) fixes (#15156)
## Summary

Fixes for the `belt-printer` branch ahead of upstreaming, in two groups
(10 commits). Targets `belt-printer` (not `main`) since group 2 fixes
the not-yet-merged Belt Printer Brims feature.

Every fix keeps non-belt (and brim-disabled) output unchanged; belt-only
behavior is corrected. All changed translation units and the two test
files were type-checked (`-fsyntax-only`); a full build + `ctest` still
needs to run in an environment with current deps.

## Group 1 — pre-existing belt-printer regressions

- **[HIGH] BuildVolume belt state not reset when leaving belt mode** —
toggling belt off (or switching belt→normal with matching bed geometry)
left the `BuildVolume` with `m_is_belt_printer=true` and inflated Y
bounds, so out-of-bounds objects were treated as printable on a normal
printer.
- **[HIGH] `GCodeProcessorResult::reset()` didn't clear belt fields**
(`belt_tilt_angle`, `belt_z_origin`, `preslice_remap_*`) — a reused
result corrupted a normal print's start-gcode preview Z.
- **[LOW-MED] `TreeSupport::drop_nodes`** — restored the single critical
section around node invalidation (the two `valid=false` writes had been
moved outside the mutex on the shared tree-support path); removed an
unused local.
- **[LOW] Support overhang hot paths** — avoid unconditional lower-layer
polygon copies when there is no build-plate tilt (`SupportMaterial`,
`TreeSupport3D`); untilted output matches upstream exactly.
- **[LOW] Render loop** — hoisted the frame-invariant slope
`up_direction`/`normal_z` (and their per-volume config lookup) out of
the per-volume loop.
- **[LOW] FDM-support "select by angle"** — restored the exact upstream
threshold when the build plate is untilted (the generalized form
differed for non-uniformly-scaled objects); tilted-gravity form kept
only under tilt.
- **[LOW] Printer tab tilt sync** — only clears the belt-derived
`build_plate_tilt` on a genuine in-place belt→off toggle (tracked,
seeded on preset load), no longer wiping a manually-set tilt.
- **[LOW / opt-in] Axis-remap G-code emission** — always emit full XYZ
under an active `gcode_remap_*`, apply the remap on all base
`travel_to_xyz` destinations, fall back to a linear lift for spiral/arc
under remap, sync `set_axis_remap` each export; fixed belt first-layer
travel speed. Identity/default output unchanged.

## Group 2 — Belt Printer Brims (#15155) fixes

- **[CRITICAL] Dropped brim at first belt contact** — a coincident brim
band on an object layer with no extrusion pass (zero-extrusion leading
slice, or belt support below the Z=0 floor with no coinciding object
extrusion) was never emitted. Now each coincident band's brim filament
is registered in `ToolOrdering`, each band is emitted exactly once in
its brim-filament pass, and an end-of-layer orphan sweep emits any band
whose object layer produced no visit.
- **[Multi-extruder] Wrong tool / double emission** — apron and
coincident bands now print once, in the correct brim-filament pass,
brim-first (were previously emitted with the active tool and could
double-emit per filament plan). Single-extruder / single-object output
is byte-identical apart from the previously-dropped bands now printing.
- **Inner-only predicate** — `has_belt_brim()` no longer reports a brim
(and no longer rejects the prime tower / spiral vase) for `inner_only` +
`brim_width=0` + leading/extra > 0, which produces no inner geometry;
mirrored in `wants_brim`.
- **ToolOrdering raft-gap comment** — clarified why raft-gap synthesis
is suppressed for all belt printers (belt has no rafts;
sub-object-bottom layers are apron / belt-support-below-floor /
lead-in). No behavior change.
- **Tests** — deterministic coverage: brim present at first belt contact
(support on/off), brim-before-perimeters once (no drop/double), single-
and multi-extruder tool selection with no doubling, multi-object
per-filament ordering, inner-only+leading-only not rejecting prime
tower/spiral, and inner-ring / leading-edge-only geometry units.

## Testing

- `-fsyntax-only` passes for all 16 changed source TUs + 2 test TUs
against this branch.
- Please run the full build and `ctest -R 'SkirtBrim|BeltBrim'` before
merging.

## Known follow-up (out of scope)

`extrude_arc_to_xy` does not remap its I-J center, so arc-fitted
*extrusions* under standalone axis-remap would be geometrically wrong —
a separate fix if that combination is supported.

Opened as **draft**.
2026-08-06 17:38:11 -05:00
harrierpigeon
a453cb1eba tests: cover belt-brim first-contact emission, tool selection, inner/leading-edge, and predicate (E)
Deterministic tests for: coincident brim at first belt contact not dropped
(C), single- and multi-extruder brim tool selection with no doubling (B),
multi-object apron ordering, inner-only+leading-only not rejecting prime
tower/spiral (D), and inner/holed + leading-edge-only geometry.
2026-08-06 15:40:04 -05:00
harrierpigeon
1bd3404c03 Fix belt brim emission: dropped first-contact bands, tool selection, inner-only predicate (A,B,C,D)
- Emit coincident belt_brim_by_layer bands even when the leading object layer
  has no InstanceVisit (zero-extrusion lead-in / no coinciding support), so the
  brim at first belt contact is no longer dropped.
- Register each coincident band's brim filament in ToolOrdering and emit each
  band exactly once, in its brim-filament pass; emit ordinary-layer aprons in
  the brim pass before object extrusion (correct tool, brim-first) instead of
  with whatever tool was active.
- has_belt_brim(): inner-only brims need brim_width>0 (leading/extra produce no
  inner geometry), fixing spurious prime-tower/spiral rejection; mirror in
  wants_brim. Single-extruder/single-object output is unchanged except
  previously-dropped bands now print.
2026-08-06 15:40:04 -05:00
harrierpigeon
c1a90fc451 Fix: correct axis-remap G-code emission and belt first-layer travel speed (B2, B3)
- BeltGCodeWriter::travel_to_xyz final branch used config.travel_speed
  instead of the computed first-layer-aware travel_speed.
- extrude_to_xyz decided emit_xyz vs emit_xy from pre-remap Z; emit full
  XYZ whenever an axis remap is active so remapped machine-Z is never
  dropped.
- base travel_to_xyz now applies apply_axis_remap() on all emitted
  destinations (standalone remap on non-belt printers was unremapped).
- spiral/arc travels fall back to normal linear lift under active remap
  (endpoint-only remap can't preserve arc plane/I-J).
- set_axis_remap() is now synced unconditionally each export to avoid a
  reused writer retaining a stale non-identity mapping.
2026-08-06 14:26:45 -05:00
harrierpigeon
7fc86db5f0 Fix: only clear belt-derived build_plate_tilt on genuine belt->off transition (R8)
update_fff() zeroed any build_plate_tilt matching the dormant belt-derived
tilt (default X/45) within 0.01, wiping a legitimate manual tilt on a
non-belt tilted-bed printer. Track the belt->non-belt transition and the
exact values belt-sync wrote, clearing only those on an in-place toggle;
reset tracking on preset load so preset switches never wipe tilt.
2026-08-06 14:26:45 -05:00
harrierpigeon
6fd2de76e6 Fix: preserve upstream select-by-angle behavior when build plate is untilted (R7)
select_facets_by_angle replaced upstream's limit.dot(down) threshold with
cos(threshold), changing facet selection for non-uniformly-scaled/mirror
objects on ALL printers. Restore the exact upstream computation when no
build-plate tilt is active; keep the tilted-gravity form only under tilt.
2026-08-06 14:26:45 -05:00
harrierpigeon
f8fe5a07cd Perf: hoist frame-invariant slope up_direction/normal_z out of the per-volume render loop (R6)
Belt slope-shading changes recomputed up_direction (with a printer-preset
config lookup) and normal_z per volume; both are frame-invariant. Compute
once before the to_render loop and reuse the already-hoisted
support_normal_z. Uniforms are still set per volume; visuals unchanged.
2026-08-06 14:26:45 -05:00
harrierpigeon
049612022a Perf: avoid unconditional lower-layer polygon copies in support overhang paths (R4, R5)
SupportMaterial::detect_overhangs copied lower_layer_polygons per region
even without build-plate tilt; hoist the tilted copy out of the region
loop and use the original polygons directly when untilted. TreeSupport3D
flattened lslices_extrudable to Polygons unconditionally; restore the
upstream ExPolygons offset on the untilted path.
2026-08-06 14:26:45 -05:00
harrierpigeon
10810908a9 Fix: restore atomic node invalidation in TreeSupport::drop_nodes + drop unused var (R3, R9)
The 2-node merge moved the two valid=false writes outside the mutex that
upstream held together with the contact_nodes push_back; restore a single
critical section per branch (belt branch also guards to_buildplate).
Remove an unused top_interface_layers local in drop_nodes.
2026-08-06 14:26:45 -05:00
harrierpigeon
0d92180325 Fix: clear belt fields in GCodeProcessorResult::reset() (R2)
reset() cleared the sibling machine_frame_transform_active but not
belt_tilt_angle/belt_z_origin/preslice_remap_*; a reused result carried
stale belt metadata into a subsequent normal print, flipping the store_z
branch and corrupting start-gcode preview Z for non-belt prints.
2026-08-06 14:26:45 -05:00
harrierpigeon
88d5e9e442 Fix: reset BuildVolume belt state when leaving belt mode (R1)
Non-belt branch of set_bed_shape reset only the 3DBed renderer, not the
BuildVolume; Bed3D::set_shape early-returns on unchanged bed, so a
belt->normal switch or in-place belt toggle-off left the BuildVolume with
m_is_belt_printer=true and inflated Y bounds -> out-of-bounds objects
treated as printable on a normal printer.
2026-08-06 14:26:45 -05:00
Joseph Robertson
c51d19f6b2 Add Belt Printer Brims (#15155)
# Description

This adds brim support to belt printers.

Added a new belt printer specific mode, Leading Edge Only and two new
belt-specific parameters, Leading Edge Brim Length, which increases the
number of brim lines on the side of the part printed first, and Extra
Brim Width, which increases the width of brims along the X axis. Because
belt printer first layers are effectively a single line, getting them to
stick properly can be a pain. This PR aims to help alleviate that, or at
least give more options for control.


<img width="1849" height="1043" alt="Screenshot from 2026-08-06
12-20-21"
src="https://github.com/user-attachments/assets/f963ed8e-53e7-48f8-a495-123cb9ae27f7"
/>



[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-08-06 14:18:21 -05:00
harrierpigeon
849e6493f8 Belt brim: offer "Leading edge only" only on belt printers
"Leading edge only" describes where a part meets a moving belt, so it has no
meaning on a fixed bed and should not clutter the Brim type dropdown there.

Filtered the same way support_style and wipe_tower_wall_type already are a few
lines above in TabPrint::toggle_options(): the field holds its own copy of the
option definition, and Choice maps the combobox selection straight onto that
copy's enum_values, so rewriting the values, the labels and the combobox items
together keeps the mapping correct.

The entry is kept when it is the current value, so opening a project that uses
it on a non-belt printer cannot leave the control displaying an option it does
not offer - which would silently rewrite the setting on the next edit.
Print::validate() already warns that it prints as an ordinary outer brim there.

Matches the scope of the existing precedents: the per-object override panel is
not filtered.
2026-08-06 03:54:19 -05:00
harrierpigeon
b1905ebc20 Belt brim: fixes from review
Six issues found by reviewing the previous commit against belt-printer, two of
them release-blocking.

Data race (high).  Print::process() runs generate_support_material() for all
objects in a tbb::parallel_for, and make_belt_brim() runs at its tail, but
belt_brim_obstacles() read every OTHER object's support_layers() - which a
concurrent task may be inside clear_support_layers() deleting.  That is a
use-after-free, and even when it survives, the obstacle set depends on which
object finishes first.  Only this object's own supports are consulted now; they
are complete at that point.  Foreign objects still contribute their slices,
which are finished and immutable before the support phase.

Apron bands dropped (high), two separate causes.  An apron band prints below
its own object's first layer, but another object can already be printing at
that print_z, in which case process_layer() takes the ordinary path and never
emitted the band - the emission is now shared by both paths.  Separately, a
band whose print_z matched a support layer of the SAME object was overwritten
in the print-wide merge, which keeps one record per object per z and could not
detect the collision because LayerToPrint::layer() is null for a band.  The
per-object pairing loop is now a three-way merge over object, support and apron
streams, so each object contributes at most one record per z.

Multi-instance was far too strict (medium).  It refused belt brim for every
multi-instance object, killing plain brim width and inner brim too, and only
warned when a leading length was set.  Only movement ALONG the belt changes an
instance's belt-floor Z, so copies side by side ACROSS the belt share one set of
bands perfectly well; belt_brim_instances_compatible() now tests just that, and
the warning fires whenever the brim is actually suppressed.

Apron layer bookkeeping (medium).  Apron layers count toward m_layer_count and
advance m_layer_index, but emitted no Z/height tags, left m_last_layer_z,
m_max_layer_z and m_last_height stale - so the first object layer computed its
height against a pre-apron Z - and skipped before_layer_change_gcode and
layer_change_gcode entirely.  All of that now matches the ordinary path.

Obstacle cost (low).  belt_brim_obstacles() ran a full-plate union per band.
A bounding-box pre-filter drops non-overlapping objects before materialising any
polygon, and the union is skipped for trivial inputs.

Deliberately unchanged: every apron band still reports cooling layer_id 0.
CoolingBuffer uses it for the initial_layer_fan_speed override and the
close_fan_the_first_x_layers gate, and every band lies on the belt plane itself,
so it is all first-layer material by the only definition that means anything on
a belt.  Numbering the bands would ramp the fan up while still printing on the
belt.  Now documented at the assignment rather than left implicit.
2026-08-06 01:08:44 -05:00
harrierpigeon
55b4dca9bc Belt printers: brim laid onto the tilted belt, with a leading apron
A belt printer slices in a rotated frame, so the belt surface is a tilted
plane rather than the Z=0 bed plane.  Each slicing layer touches the belt
only along a narrow strip at its leading edge - about 0.2mm at 45 degrees -
so a part's first layer is really a first line, with almost no contact patch
to hold it down while the belt drags it forward.  Brim was hard-disabled on
belt printers, leaving no remedy at all.

Generate the brim on the belt plane instead.  The object's belt footprint is
the union over layers of each slice clipped to that layer's contact band; the
brim is offset from it in a "flattened" frame where the shear axis is
stretched by 1/cos(tilt), so ordinary Clipper offsets measure true on-belt
distance.  It is emitted as cross-belt lines, one per layer band, anchored to
a fixed fraction of the band so every line shares a nozzle-to-belt clearance
and therefore comes out the same width; flow is matched to the resulting band
pitch, keeping the sheet uniform and gap-free.

Three new controls, all belt-only:

  * Leading brim length - extends the brim ahead of the part along the belt,
    on every downhill-facing edge of its contact area.  This apron necessarily
    prints BELOW the object's first layer, since layer 0 is the part's leading
    contact, so it needs brim-only bands of its own.
  * Extra brim width - widens the brim sideways across the belt only.
  * Brim type "Leading edge only" - brim at the part's first belt contact and
    nothing after it.  Appended last in BrimType so no existing value shifts;
    degrades to an outer brim off belt printers, with a warning.

The apron bands are lightweight records rather than a Layer subclass, so no
fabricated Layer::id() can leak into initial-layer temperature selection, the
spiral vase probe, cooling or gradual interpolation.  They are generated in
posSupportMaterial because their print_z values must exist before ToolOrdering
is built at psWipeTower, and they are emitted from a short dedicated branch in
process_layer that runs before any layer pointer is dereferenced.

The footprint is closed before offsetting outwards: a belt contact patch is
often a broken-up strip, and the merged offset rings of two islands closer
than 2 x brim_width would otherwise fill the space between them - space that
lies under the part.

Also fixes a pre-existing bug where PrintObject::get_first_layer_bbox()
overwrote a valid bbox with an unassigned one on any belt printer with a brim
configured, because has_brim() was true while make_brim() returned early.

Belt brim is refused alongside the prime tower and spiral vase, and requires
one instance per PrintObject - translating an instance along the belt axis
changes its physical belt-floor Z.  Untilted belt printers are unchanged: they
still get no brim, since the plate brim is emitted out of skirt_brim_groups(),
which _make_skirt() never builds for a belt printer.
2026-08-06 01:08:44 -05:00
Joseph Robertson
386364f84b belt profiles: fix belt printer CI failures (slice check + setting_id) (#15127)
The belt-printer branch is failing two profile gates. Both stem from the
three belt-only vendors (Custom's generic belt printer, IdeaFormer,
Printcepts) not existing upstream, so upstream maintenance passed them
by.

Slice check: 4 of 1015 printers failed - Custom's MyBeltPrinter 0.2/0.4/
0.6/0.8 nozzle all fell back to "Default Setting". No process profile in
the Custom vendor listed any MyBeltPrinter in compatible_printers, and
Custom's fdm_belt_common pointed default_print_profile at "0.20mm
Standard @System", which does not exist in that vendor's index, so the
generic belt printer had no usable process at all. This gap dates to
when MyBeltPrinter was added (2026-04-07); it only started failing now
because the slice-check job is newer than that.

Adds two process profiles modelled on the sibling @MyKlipper ones:
  - 0.20mm Standard @MyBeltPrinter - 0.4/0.6/0.8 nozzles
  - 0.12mm Fine @MyBeltPrinter     - 0.2/0.4 nozzles
The split is forced by hardware: the 0.2 nozzle preset caps
max_layer_height at 0.16, so a single 0.20mm profile cannot legally
cover
it. fdm_belt_common now defaults to the standard profile and the 0.2
nozzle preset overrides to the fine one.

setting_id: 14 files failed the rules introduced in #14432. That
migration renumbered 7425 files across 61 vendors but skipped these
three, leaving BabyBelt Pro, IdeaFormer IR3 V2 and MyBeltPrinter
squatting the "G*" id space reserved for Bambu (GMPC0BBP01, GMIF001,
GM_BELT_00x) and four instantiated filament/process presets carrying no
setting_id at all. Regenerated with
scripts/assign_vendor_setting_ids.py.

Also repoints the identical dangling "0.20mm Standard @System" in
Printcepts' and IdeaFormer's fdm_belt_common at their own real process
profiles. That is a no-op today because both concrete printers override
it, but it is the same landmine that took out MyBeltPrinter.

Vendor index versions bumped so check_installed_vendor_profiles() will
re-install the corrected profiles over an existing install.

Note: changing a shipped preset's setting_id can orphan user presets
that reference it as base_id. #14432 accepted that tradeoff for 61
vendors; this keeps these three consistent with the rest.

Verified: orca_extra_profile_check.py reports 0 errors across 66 vendors
(was 14 files with errors), and OrcaSlicer_profile_validator -s slices
all 1015 printer presets successfully (was 4 failures).


[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-08-04 17:16:14 -05:00
harrierpigeon
725df64108 profiles: fix belt printer CI failures (slice check + setting_id)
The belt-printer branch is failing two profile gates. Both stem from the
three belt-only vendors (Custom's generic belt printer, IdeaFormer,
Printcepts) not existing upstream, so upstream maintenance passed them by.

Slice check: 4 of 1015 printers failed - Custom's MyBeltPrinter 0.2/0.4/
0.6/0.8 nozzle all fell back to "Default Setting". No process profile in
the Custom vendor listed any MyBeltPrinter in compatible_printers, and
Custom's fdm_belt_common pointed default_print_profile at
"0.20mm Standard @System", which does not exist in that vendor's index,
so the generic belt printer had no usable process at all. This gap dates
to when MyBeltPrinter was added (2026-04-07); it only started failing now
because the slice-check job is newer than that.

Adds two process profiles modelled on the sibling @MyKlipper ones:
  - 0.20mm Standard @MyBeltPrinter - 0.4/0.6/0.8 nozzles
  - 0.12mm Fine @MyBeltPrinter     - 0.2/0.4 nozzles
The split is forced by hardware: the 0.2 nozzle preset caps
max_layer_height at 0.16, so a single 0.20mm profile cannot legally cover
it. fdm_belt_common now defaults to the standard profile and the 0.2
nozzle preset overrides to the fine one.

setting_id: 14 files failed the rules introduced in #14432. That
migration renumbered 7425 files across 61 vendors but skipped these three,
leaving BabyBelt Pro, IdeaFormer IR3 V2 and MyBeltPrinter squatting the
"G*" id space reserved for Bambu (GMPC0BBP01, GMIF001, GM_BELT_00x) and
four instantiated filament/process presets carrying no setting_id at all.
Regenerated with scripts/assign_vendor_setting_ids.py.

Also repoints the identical dangling "0.20mm Standard @System" in
Printcepts' and IdeaFormer's fdm_belt_common at their own real process
profiles. That is a no-op today because both concrete printers override
it, but it is the same landmine that took out MyBeltPrinter.

Vendor index versions bumped so check_installed_vendor_profiles() will
re-install the corrected profiles over an existing install.

Note: changing a shipped preset's setting_id can orphan user presets that
reference it as base_id. #14432 accepted that tradeoff for 61 vendors;
this keeps these three consistent with the rest.

Verified: orca_extra_profile_check.py reports 0 errors across 66 vendors
(was 14 files with errors), and OrcaSlicer_profile_validator -s slices all
1015 printer presets successfully (was 4 failures).
2026-08-04 17:15:20 -05:00
Joseph Robertson
c5bf238859 Update Belt-Printer Branch (#15087)
gets belt-printer on top of upstream again.
2026-08-03 02:09:41 -05:00
harrierpigeon
f563df04f6 belt: default first_layer_plane to Auto, not BeltAffine
BeltAffine activates the FirstLayerPlane evaluator unconditionally, so on a
non-belt printer on_first_layer(point) stopped agreeing with the legacy
slicing-layer-0 test. Every per-path first-layer call site in _extrude then
took the non-first-layer branch, and first-layer speeds were skipped: brim
came out at the volumetric fallback (24.6 mm/s) instead of initial_layer_speed
(10 mm/s). This is the shared speed path, so it affected all printers on this
branch, not just belt ones.

Auto resolves to BeltAffine only when belt_printer is set with a non-zero
slicing rotation, and to XY (evaluator inactive, legacy behaviour) otherwise --
exactly what the option's own description already promised.

Caught by "Brim uses first layer speed" (upstream #14616), which arrived with
the upstream merge; the bad default dates back to a9bae54f20 (#30). Verified
against a pristine upstream/main build, which passes the same test.

tests/fff_print: 100/100 test cases, 1085 assertions (was 99/100).
Both belt regression tests still pass, confirming Auto still resolves to
BeltAffine for belt printers.

Note: this changes a config default. Projects and profiles that stored
first_layer_plane explicitly are unaffected; those relying on the default will
now get correct first-layer speeds on non-belt printers, so their G-code
changes accordingly.
2026-08-03 01:52:43 -05:00
harrierpigeon
613dad92a1 Add belt-printer regression test for prepare-stage move Z
Processes a minimal belt start sequence through GCodeProcessor::process_buffer
and asserts the move preceding the first extrusion keeps its real Z, so it can
no longer back-transform to model Y~=0 and produce the phantom extrusion line.

Belt printers are non-Bambu, so the processor uses the compatible reserved
tags ("TYPE:"); the test sets s_IsBBLPrinter=false (saved/restored via an RAII
guard) to mirror the real printer. Proven to fail without the fix (the
prepare-stage move's Z is pinned to the first-layer height, 0 here) and pass
with it.
2026-08-03 01:18:55 -05:00
harrierpigeon
a83cd8aa29 Fix belt printer phantom extrusion line from Y=0 in preview
On a belt printer the sliced preview drew a stray extrusion-colored line
from Y~=0 to the model, rendered in the first extrusion role's color. It is
not a travel and does not occur on non-belt printers.

GCodeProcessor::store_move_vertex pins a move's stored Z to the first-layer
height during the start-G-code "prepare" stage. That is a harmless cosmetic
tidy-up on a normal printer, but on a belt printer the designed-view
back-transform couples machine Z into the rendered model Y (the belt tilt
mixes the height and belt-feed axes). Pinning Z back-transforms the last
prepare-stage move (the unretract before the first extrusion) to model
Y ~= 0, and libvgcode then draws a phantom extrusion segment from Y ~= 0 to
the first real toolpath.

Keep the real Z for belt printers (gated on belt_tilt_angle, parsed from the
G-code header before the body) so prepare-stage moves back-transform
correctly. Non-belt processing is byte-identical. The emitted G-code was
already correct; this is a preview-geometry fix.
2026-08-03 01:09:23 -05:00
harrierpigeon
02e313a115 Add belt-printer regression test for start-of-print gantry move
Locks in the fix from the previous commit. A fresh BeltGCodeWriter has an
unestablished planar position (is_current_position_clear() == false) and its
m_pos.xy is the origin (0,0). With a pending NormalLift z-hop, travel_to_xyz
used to lift in place via _travel_to_z(), which in belt mode shears the origin
into a machine Y ~= the layer Z — a move far up the gantry.

The test configures an X-tilt 45 deg belt transform, defers a z-hop via
lazy_lift, travels to a near-belt first point (transformed gantry Y ~= 1mm),
and asserts no emitted move has Y anywhere near the layer Z. Verified to fail
without the fix (max emitted Y = 100.0 vs the destination's ~1.0) and pass with
it.
2026-08-03 01:09:11 -05:00
harrierpigeon
04554abae6 Fix belt printer illegal gantry move at print start
On a belt printer the first travel of the print emitted a bogus move to
the bed corner with the nozzle far up the gantry, e.g.
  G1 X95 Y168.19 Z237.857 F12000
right after the first "; printing object" line. Y168 (≈ the layer Z)
is out of the gantry's range.

Root cause: the layer-change z-hop is deferred via lazy_lift and consumed
by the first BeltGCodeWriter::travel_to_xyz, whose NormalLift branch does a
separate lift-in-place via _travel_to_z(target.z()). On a normal printer
_travel_to_z emits a Z-only move, but in belt mode Z is coupled to Y/X, so
_travel_to_z re-emits the current m_pos through the belt shear. At print
start (and after custom gcode) m_pos.xy is still the uninitialised origin
(0,0), which the back-transform + axis-remap shear into machine
(X=bed_max, Y=layer_z) — the illegal move.

Guard the NormalLift branch on is_current_position_clear(), matching the
SlopeLift branch directly above it which already does so. When the position
isn't established there is nothing to lift over, and the xy_z_move that
follows travels straight to the destination with full XYZ, establishing the
correct position. Bookkeeping is unaffected: in this path m_lifted stays 0,
so no spurious restore move is produced.

Verified by re-slicing the repro project: the start-of-print move is now
G1 X44.946 Y.621 Z237.857 (straight to the first object point), no move
touches the bed-max X edge, and the max Y over the whole file is 62.8mm
(printable_height 100).
2026-08-03 00:15:24 -05:00
HarrierPigeon
0342e06d87 last step in fixing the g-code stuff up 2026-08-02 22:13:34 -05:00
HarrierPigeon
79fd847ce3 fix pre-slice warnings 2026-08-02 22:12:46 -05:00
HarrierPigeon
8f6802fff8 step one: post-process analysis 2026-08-02 22:12:09 -05:00
harrierpigeon
b61ba98183 belt: adapt BeltGCodeWriter to upstream's per-extruder speed options
Upstream retyped travel_speed and travel_speed_z to ConfigOptionFloatsNullable
and initial_layer_travel_speed to ConfigOptionFloatsOrPercentsNullable, so the
scalar .value / get_abs_value() accessors no longer compile. BeltGCodeWriter.cpp
is belt-only and merged without conflict, so this only surfaced at build time.

Index them the way the base GCodeWriter does -- .get_at(m_cached_extruder_idx)
and get_abs_value_at(..., m_cached_extruder_idx) -- keeping belt's per-point
first_layer_for_point test rather than the base class's m_is_first_layer.

m_cached_extruder_idx moves from private to the existing protected block that
already exposes writer state to subclasses, so the belt writer resolves the
per-extruder index identically to the base writer instead of guessing one.
2026-08-02 16:20:22 -05:00
harrierpigeon
175075fd08 Merge upstream/main into belt-printer
Brings the belt-printer work up to date with 591 upstream commits.

Conflict resolutions (12 files, 42 hunks):

- GCode.cpp: adopted upstream's per-filament/per-nozzle config refactor
  (get_filament_config_index, NOZZLE_CONFIG), the extracted
  generate_timelapse_gcode + farthest-point timelapse, and the
  ConfigOptionFloatsNullable calibration options. Re-applied the belt
  hooks on top: init_belt_writer / axis remap / FirstLayerPlane setup,
  on_set_origin, the belt-corrected calib_z for the volumetric speed
  tower, and path_on_first_layer (belt's per-path first-layer test) in
  place of upstream's layer-index on_first_layer() in the acceleration,
  jerk and overhang-detection paths. Swept upstream's new m_writer.
  uses to m_writer-> since belt holds the writer by unique_ptr.
- interpolate_value_across_layers: kept upstream's banded stepping and
  belt's object-Z-span ratio; dropped upstream's duplicate ratio decl.
- Plater.cpp: took upstream's guarded add_model(...) early-returns and
  the VFA vfa_layer_height plumbing; kept the belt temp-tower path,
  _calib_apply_belt_mode and belt_calib_flip_ringing_tower. Dropped the
  VFA "cut upper" block, superseded upstream by model scaling.
- Brim.cpp: upstream's ObjectInstanceID-keyed brimAreaMap, keeping the
  belt early-return.
- 3DScene.cpp: kept both the belt build-plate tilt up_direction and
  upstream's per-extruder printable-height shading.
- GCodeViewer.cpp: kept upstream's dim-previous-layers setup and belt's
  exemption from the same-result early return.
- TreeSupport.cpp: upstream's >= 0 roof-layer fix inside belt's
  belt-floor branch.
- calib.cpp / GCode.hpp / GCodeWriter.{cpp,hpp} / Print.hpp: upstream's
  additions adapted to belt's pointer-held writer and helpers.
- Custom.json: kept profile version 02.04.00.03 (belt) over upstream's
  02.04.00.01; both bumped from 02.04.00.00.

Building this tree needs the wxInspector dependency, which upstream
added in the interim (python3 and wxWidgets 3.3.2 were already present
in the shared deps prefix).
2026-08-02 16:09:27 -05:00
SoftFever
ea7117b7ca Fix stringing between the model and the wipe tower (#15038)
# Description

On multi-tool printers using the type 2 wipe tower, the travel to the
tower ignored the configured Z hop type and always used a plain vertical
hop, so the nozzle rose in place over the part and oozed instead of
lifting away with the travel. It now follows the filament's Z hop
setting, matching what the type 1 tower already does.
Only toolchange travels to a type 2 tower change. Normal Lift and z_hop
= 0 are unaffected, and no extrusion moves change in any mode.

# Screenshots/Recordings/Graphs


## Tests

<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->

<!--
> A guide for users on how to download the artifacts from this PR.
-->

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-07-31 18:26:48 +08:00
SoftFever
603a8f9c8f Fix stringing between the model and the wipe tower
The tower travel took retract()'s default vertical Z hop instead of the
configured one, so the nozzle rose in place over the part and oozed
rather than departing with the travel. Pass the filament's z_hop_types
through, mapping Auto to a spiral lift as append_tcr does.
2026-07-31 18:16:06 +08:00
SoftFever
6a2a57bdf4 Bring the rib wall and skip-points prime tower to all printers (#15035)
* Sync WipeTower from BambuStudio(through ca1881761)

* Fix post-slice self-invalidation on custom multi-extruder printers

* Complete the rib wipe tower port in WipeTower2

The rib tower is now always square (prime_tower_width is ignored, as the
GUI already implies), carries the rib origin offset like the BBL tower so
the rib tips sit inside the configured position, clamps the rib length to
the tower diagonal, and extends the ribs for short towers.

* Use the squared rib tower size in arrange estimates

estimate_wipe_tower_polygon reserved the arrange footprint and clamped the
tower X position with the raw prime_tower_width, under-reserving space
whenever the rib wall squares the tower to a different width.

* Print the WipeTower2 shell with a non-support, non-soluble filament

Like the BBL tower: the layer's sparse infill, wall, and brim go to the
first toolchange to a non-support/non-soluble filament, or are printed
with the incoming filament before any toolchange. The minimal-purge
clamp now also covers toolchanges that get no finish-layer saving.
Output is unchanged when no support/soluble filament is used.

* Port the skip-points gap wall to WipeTower2

prime_tower_skip_points was stubbed for Type2 towers: the wall call
hard-coded skip_points=false, the gap cutter received an empty vector,
and append_tcr2 never routed the entry travel. Now the toolchange entry
positions are precomputed from the finalized plan, the wall is cut open
at each entry, and the entry travel approaches around the tower bounding
box through the opening when it starts outside the tower. The geometry
helpers are re-synced with the BBL versions (add_extra_point guards,
per-point side selection). The cone wall keeps its separate path, where
the option stays inert.

Behavior change: non-BBL towers now honor the (default-on) checkbox with
gap walls and routed entries; with the option off the output is
unchanged, and the BBL tower path is untouched.

* Route the in-place toolchange tower entry through the skip-point gap

On multi-tool printers without ramming the tool changes away from the
tower and the entry travel is the tcr's own positioning move, which went
straight across the printed wall. Append the avoid-perimeter path to the
change-filament gcode instead, so the head approaches around the tower
and enters through the wall opening (append_tcr parity).

* Iron the purge start out through the skip-point gap in WipeTower2

Port the BBL tower's entry line ironing: extrude the first 3 mm of the
purge, retract, drag the nozzle 1.5x back out through the wall gap at
F600, creep back at F240 and unretract, so the toolchange start blob
ends up in the gap instead of on the wall. Fires only when the purge
starts at the left-edge entry heading right (in-place toolchangers);
SEMM ram/cooling wipes start mid-box and the priming line has no wall,
so both keep their previous output.

* Reserve WipeTower2 toolchange depth to match the printed purge

The planner reserved ramming rows gated only on enable_filament_ramming and
sized them with the SEMM 0.25s time step, while toolchange_Unload rams on
(semm && enable_filament_ramming) || filament_multitool_ramming with the
multitool time step. Disabling multitool ramming therefore left ~3 unprinted
rows per toolchange as blank bands in the tower. Without ramming the first
wipe line also needs reserved depth of its own (it no longer rides the last
ramming row), plus the y_step/2 offset the wipe start inherits from the
ramming start position - otherwise the tightened boxes truncate the ordered
purge at the box edge.

* Tile WipeTower2 purge rows contiguously across toolchange blocks

Without ramming, each purge block reserved one wipe pitch more than its
rows occupy (ceil+1 rounding plus the ram-geometry start offset), and the
wipe began a full pitch inside the block, leaving a blank band of exactly
two pitches between adjacent blocks. Plan the block as whole wipe rows,
start the first row so the row lattice continues across the block
boundary, and fill the reserved box instead of stopping at the ordered
volume, mirroring how the BBL WipeTower keeps planned depth identical to
printed rows. Ram-printing toolchanges (SEMM with ramming enabled,
multitool ramming) are unchanged.

* Scrub the WipeTower2 toolchange entry with the BBL flat-ironing spiral

The entry scrub now matches the BBL tower's toolchange_wipe_new sequence:
after the ironing drag the retracted nozzle runs a dry expanding-square
spiral centred on the wall-gap entry point before resuming the purge row.
The spiral runs whenever the gap wall is on (disable per filament via
filament_tower_ironing_area = 0); WipeTower2 no longer reads
prime_tower_flat_ironing.

* Restart the WipeTower2 wipe at the box boundary after multitool ramming

With the gap wall on a multi-tool printer, quantize the ram band up to its
whole reserved rows (as the BBL tower does for the old-tool purge) and start
CP TOOLCHANGE WIPE at the left-edge boundary on a fresh row below it instead
of continuing from wherever the ram serpentine ended. The entry scrub then
runs at the wall gap on ram toolchanges too, and the wipe box is whole rows,
so it is filled completely like the no-ram case. SEMM and skip-points-off
behavior is unchanged.

* Move the WipeTower2 wall gap to the wipe start row for ram toolchanges

* code cleanup

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix typo

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-31 18:08:55 +08:00
SoftFever
c8aacea176 fix typo 2026-07-31 18:07:46 +08:00
SoftFever
4824a171f1 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-31 15:34:04 +08:00
Ian Chua
101f43b2d8 fix: resolve plugins that are missing locally (physical file deleted) (#14861)
* fix: resolve plugins that are missing locally (physical file deleted)

* fix: don't treat file not found as an error
2026-07-31 14:15:51 +08:00
Ian Chua
e01ac1f0a6 fix: keep orphaned cloud plugins runnable (#14859)
* fix: keep orphaned cloud plugins runnable

* fix: tests
2026-07-31 14:15:22 +08:00
Ian Chua
b51db32bb5 fix: ota profile race (#14993)
# Description

<!--
> Please provide a summary of the changes made in this PR. Include
details such as:
  > * What issue does this PR address or fix?
  > * What new features or enhancements does this PR introduce?
> * Are there any breaking changes or dependencies that need to be
considered?
-->
This PR updates OTA vendor profile handling and fixes a Windows-only
startup race that could terminate OrcaSlicer silently.

## Changes
- Correct vendor profile version comparison logic.
- Trigger vendor profile synchronization after the startup printer
preset is restored.
- Remove duplicate vendor synchronization from the general startup
updater.
- Replace global temporary archive cleanup with targeted per-vendor
cleanup.
- Add updater-thread exception handling to prevent uncaught filesystem
errors from terminating the process.

# Screenshots/Recordings/Graphs

<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->

## Tests

<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->

<!--
> A guide for users on how to download the artifacts from this PR.
-->

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-07-31 14:14:34 +08:00
Ian Chua
603b02f0e7 Merge branch 'main' into fix/ota-profile-race 2026-07-31 14:14:23 +08:00
Kiss Lorand
54dc5a2f1d Hungarian localization overhaul (#15024) 2026-07-30 15:08:04 -03:00
Kris Austin
303be94262 feat(msix): add execution alias and web link associations to the Store package (#14799) 2026-07-30 10:02:44 -03:00
Ian Bassi
58bad17af9 AI translation update (#15018) 2026-07-29 18:09:32 -03:00
Nathan Schulte
ddce030322 add space after "Arranging" message (#15017) 2026-07-29 17:37:23 -03:00
Ian Bassi
2d4b431d5f Improve dimmed layers (#15001)
Co-authored-by: yw4z <yw4z@outlook.com>
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-07-29 16:27:15 -03:00
Ian Chua
27c468754c feat(plugin): expose orca.host.app_language() for plugin localization (#14997)
# Description

Python plugins currently have no way to localize their own dialogs to
match the app: the UI language is stored in `OrcaSlicer.conf`, which the
plugin audit hook deny-lists by design (the file sits next to cloud
secrets), and the host API exposes no app info. As a result, localized
plugins have to guess the language from the OS locale, which does not
always match the slicer UI (and the embedded interpreter often gets no
`LANG` at all in GUI sessions).

This PR adds a minimal read-only accessor:

```python
orca.host.app_language()   # -> "en_US", "ru_RU", ...
```

It returns `GUI_App::current_language_code_safe()` — only the language
code string, nothing else from the config, so the audit-hook security
model is untouched.

No breaking changes; one file, +10 lines.

# Screenshots/Recordings/Graphs

(screenshots of the test dialog will be attached below)

## Tests

- Built on macOS (arm64, Ninja) with this change — compiles clean.
- Ran a minimal script-capability plugin calling
`orca.host.app_language()` on a system with Russian UI: the dialog shows
`'ru_RU'`.
- Guard before GUI init follows the same exception pattern as the
neighbouring `plater()`/`preset_bundle()` accessors.
<img width="903" height="826" alt="Снимок экрана 2026-07-28 в 23 10 48"
src="https://github.com/user-attachments/assets/27088265-b55d-4958-8602-7c3ab4993003"
/>
<img width="437" height="276" alt="Снимок экрана 2026-07-28 в 23 10 56"
src="https://github.com/user-attachments/assets/9845b401-dc8e-4353-aa24-5ace678270d6"
/>
2026-07-30 01:19:09 +08:00
SoftFever
3ab9cf53d0 code cleanup 2026-07-30 00:55:09 +08:00
Bartok
88632710d5 docs: add Microsoft Store install path for Windows (#15009)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
Signed-off-by: Bartok <danielrpike9@gmail.com>
2026-07-29 10:53:20 -03:00
Nathan Schulte
d434e35488 fix STEP progress message percent format (#14994) 2026-07-29 10:48:01 -03:00
yw4z
7bd53b1283 Fix cannot type values to spin control if first digit of desired value is less then min value (#15002) 2026-07-29 10:19:10 -03:00
SoftFever
252df70ec4 Move the WipeTower2 wall gap to the wipe start row for ram toolchanges 2026-07-29 20:58:21 +08:00
Ian Bassi
6489b4cad3 Fix: Only one wall top surfaces (#14929) 2026-07-29 09:23:35 -03:00
SoftFever
086bbf986b Restart the WipeTower2 wipe at the box boundary after multitool ramming
With the gap wall on a multi-tool printer, quantize the ram band up to its
whole reserved rows (as the BBL tower does for the old-tool purge) and start
CP TOOLCHANGE WIPE at the left-edge boundary on a fresh row below it instead
of continuing from wherever the ram serpentine ended. The entry scrub then
runs at the wall gap on ram toolchanges too, and the wipe box is whole rows,
so it is filled completely like the no-ram case. SEMM and skip-points-off
behavior is unchanged.
2026-07-29 19:59:33 +08:00
SoftFever
67e1ce03a6 Scrub the WipeTower2 toolchange entry with the BBL flat-ironing spiral
The entry scrub now matches the BBL tower's toolchange_wipe_new sequence:
after the ironing drag the retracted nozzle runs a dry expanding-square
spiral centred on the wall-gap entry point before resuming the purge row.
The spiral runs whenever the gap wall is on (disable per filament via
filament_tower_ironing_area = 0); WipeTower2 no longer reads
prime_tower_flat_ironing.
2026-07-29 18:48:10 +08:00
SoftFever
36bd453ac8 Tile WipeTower2 purge rows contiguously across toolchange blocks
Without ramming, each purge block reserved one wipe pitch more than its
rows occupy (ceil+1 rounding plus the ram-geometry start offset), and the
wipe began a full pitch inside the block, leaving a blank band of exactly
two pitches between adjacent blocks. Plan the block as whole wipe rows,
start the first row so the row lattice continues across the block
boundary, and fill the reserved box instead of stopping at the ordered
volume, mirroring how the BBL WipeTower keeps planned depth identical to
printed rows. Ram-printing toolchanges (SEMM with ramming enabled,
multitool ramming) are unchanged.
2026-07-29 16:37:06 +08:00
SoftFever
9292db2f9f Reserve WipeTower2 toolchange depth to match the printed purge
The planner reserved ramming rows gated only on enable_filament_ramming and
sized them with the SEMM 0.25s time step, while toolchange_Unload rams on
(semm && enable_filament_ramming) || filament_multitool_ramming with the
multitool time step. Disabling multitool ramming therefore left ~3 unprinted
rows per toolchange as blank bands in the tower. Without ramming the first
wipe line also needs reserved depth of its own (it no longer rides the last
ramming row), plus the y_step/2 offset the wipe start inherits from the
ramming start position - otherwise the tightened boxes truncate the ordered
purge at the box edge.
2026-07-29 13:23:29 +08:00
Kiss Lorand
29d4513694 Fix overlapping brims (#14991) 2026-07-28 17:46:14 -03:00
Ru
0dc14aa876 feat(plugin): expose orca.host.app_language() for plugin localization
Plugins have no way to localize their own dialogs: the UI language lives in
OrcaSlicer.conf, which the plugin audit hook deny-lists because the file sits
next to cloud secrets. Add a read-only host accessor that returns just the
language code (current_language_code_safe), so plugins can match the app
language without touching the config file.
2026-07-28 23:11:05 +03:00
SoftFever
bef47b2c70 Iron the purge start out through the skip-point gap in WipeTower2
Port the BBL tower's entry line ironing: extrude the first 3 mm of the
purge, retract, drag the nozzle 1.5x back out through the wall gap at
F600, creep back at F240 and unretract, so the toolchange start blob
ends up in the gap instead of on the wall. Fires only when the purge
starts at the left-edge entry heading right (in-place toolchangers);
SEMM ram/cooling wipes start mid-box and the priming line has no wall,
so both keep their previous output.
2026-07-28 21:21:50 +08:00
peachismomo
013a9452af fix: prevent Windows OTA vendor profile update race 2026-07-28 19:48:10 +08:00
SoftFever
5b475e5e98 Route the in-place toolchange tower entry through the skip-point gap
On multi-tool printers without ramming the tool changes away from the
tower and the entry travel is the tcr's own positioning move, which went
straight across the printed wall. Append the avoid-perimeter path to the
change-filament gcode instead, so the head approaches around the tower
and enters through the wall opening (append_tcr parity).
2026-07-28 00:15:59 +08:00
SoftFever
56810c8c7f Port the skip-points gap wall to WipeTower2
prime_tower_skip_points was stubbed for Type2 towers: the wall call
hard-coded skip_points=false, the gap cutter received an empty vector,
and append_tcr2 never routed the entry travel. Now the toolchange entry
positions are precomputed from the finalized plan, the wall is cut open
at each entry, and the entry travel approaches around the tower bounding
box through the opening when it starts outside the tower. The geometry
helpers are re-synced with the BBL versions (add_extra_point guards,
per-point side selection). The cone wall keeps its separate path, where
the option stays inert.

Behavior change: non-BBL towers now honor the (default-on) checkbox with
gap walls and routed entries; with the option off the output is
unchanged, and the BBL tower path is untouched.
2026-07-27 21:18:53 +08:00
SoftFever
c3c37e474a Print the WipeTower2 shell with a non-support, non-soluble filament
Like the BBL tower: the layer's sparse infill, wall, and brim go to the
first toolchange to a non-support/non-soluble filament, or are printed
with the incoming filament before any toolchange. The minimal-purge
clamp now also covers toolchanges that get no finish-layer saving.
Output is unchanged when no support/soluble filament is used.
2026-07-27 12:30:57 +08:00
SoftFever
1696d5ca39 Use the squared rib tower size in arrange estimates
estimate_wipe_tower_polygon reserved the arrange footprint and clamped the
tower X position with the raw prime_tower_width, under-reserving space
whenever the rib wall squares the tower to a different width.
2026-07-27 03:08:47 +08:00
SoftFever
466c36eaa3 Complete the rib wipe tower port in WipeTower2
The rib tower is now always square (prime_tower_width is ignored, as the
GUI already implies), carries the rib origin offset like the BBL tower so
the rib tips sit inside the configured position, clamps the rib length to
the tower diagonal, and extends the ribs for short towers.
2026-07-27 03:07:07 +08:00
SoftFever
5792fef805 Merge branch 'main' into feature/update_wipetower 2026-07-27 00:51:29 +08:00
SoftFever
bc016af1c9 Fix post-slice self-invalidation on custom multi-extruder printers 2026-07-27 00:49:08 +08:00
SoftFever
7a378d2fc4 Sync WipeTower from BambuStudio(through ca1881761) 2026-07-27 00:48:44 +08:00
Joseph Robertson
5428a0715d update belt-printer (#14446)
[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-06-26 23:02:49 -05:00
Joseph Robertson
75770321dd Update Belt-Printer (#14425) 2026-06-25 22:40:26 -05:00
Joseph Robertson
c950c3fb6b Add BabyBelt Pro Profile, Courtesy of Rexit (#14424) 2026-06-25 22:39:12 -05:00
Joseph Robertson
2ca843a38e Belt Printing: Bugfix: Solid Organic Tree Base, Slim Tree Skirt, Renderer (#14395)
* fix tree support brim
* treesupport3d part 1: more diagnostic logging.  (todo once things are fixed: remove this / gate it properly)
* make area under Z=0 in rotated slice pipeline not solid
* fix solid Z=0 layer for belt printers
* fix renderer
* clean up logging
* final review pass
2026-06-24 22:01:29 -05:00
Joseph Robertson
0ef7c6d581 Belt Printing: Update (#14393)
# Description

<!--
> Please provide a summary of the changes made in this PR. Include
details such as:
  > * What issue does this PR address or fix?
  > * What new features or enhancements does this PR introduce?
> * Are there any breaking changes or dependencies that need to be
considered?
-->

# Screenshots/Recordings/Graphs

<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->

## Tests

<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->

<!--
> A guide for users on how to download the artifacts from this PR.
-->

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-06-24 21:34:53 -05:00
Joseph Robertson
34b0d36cda Belt Printer Initial Push (#14385)
# Description

Initial push - documentation available at #12998 

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-06-24 09:42:40 -05:00
Joseph Robertson
d619c7e19c Merge branch 'belt-printer' into belt/baseChanges 2026-06-24 09:42:25 -05:00
Joseph Robertson
31b44cb731 Merge pull request #66 from HarrierPigeon/belt/tommyb-rendererChanges
Clean up and implement @tommasobbianchi's belt renderer changes
2026-06-23 00:27:39 -05:00
harrierpigeon
ddbee84e68 render the G-code preview upright (designed view) + toggle UI 2026-06-23 00:14:17 -05:00
Joseph Robertson
bf6cce1f40 Merge pull request #45 from tommasobbianchi/feat/belt-gcode-cartesian-preview
belt: render the G-code preview upright (model/Cartesian space)
2026-06-22 19:59:27 -05:00
Joseph Robertson
8bdf0df00a Merge branch 'main' into belt/baseChanges 2026-06-22 19:36:17 -05:00
Joseph Robertson
d6c9187c71 Merge branch 'main' into belt/baseChanges 2026-06-22 19:36:17 -05:00
Ian Bassi
0cdfb88357 Lang: Gettext update (#14361) 2026-06-22 20:16:55 -03:00
foXaCe
14cec7239b i18n(fr): translate strings added after the post-refactor sync (#14304) 2026-06-22 20:13:19 -03:00
Heiko Liebscher
86c6a1a66f Improve German (de) translation (#14352)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:40:14 -03:00
SoftFever
07f08dfe40 bump version to 2.5.0-dev 2026-06-22 00:50:51 +08:00
Noisyfox
a4fb5af9e1 Don't allow adding more colors for non-semm printers on obj import color remapping dialog (#14275) 2026-06-21 18:20:58 +08:00
Tommaso Bianchi
8593d66a39 belt: correct the designed-view preview's belt-Z origin and reject mis-mapped outliers
The Cartesian designed-view preview over-extended the toolpaths past the model
shell by a height-proportional amount (up to ~20mm tall parts), most visibly on
long multi-part prints; compact parts like a calibration cube looked fine.

Two coupled causes:
- Belt start G-code that primes with a Z advance and a 'G92 Z0' reset leaves a
  constant machine-Z origin in the GCodeProcessor, so move positions are stored as
  gcode_Z + origin. The linear back-transform mixes that constant with the
  gantry-Y term, leaving a per-move designed-Y error that min-corner anchoring
  cannot cancel when an elevated move (e.g. a bridge) happens to cancel it at the
  bbox minimum. Expose GCodeProcessorResult::belt_z_origin (the m_origin[Z] left by
  the start G-code) and subtract it before the back-transform.
- Elevated features (bridges/overhangs) are mis-mapped by the linear inverse to
  outside the model body; build the anchor bbox only from moves within model_bb +/-
  10mm, with a fallback to the full bbox when the clip would drop the bulk (object
  placed away from the belt entry) so the gross-offset case still anchors.

Preview-only; G-code output is unchanged.
2026-06-21 06:48:44 +02:00
Tommaso Bianchi
3fc3b8a8ae belt: anchor the designed-view G-code preview onto the model bounding box
The belt designed (upright) preview back-transforms the machine-frame G-code
into model space with the linear belt inverse. That inverse recovers the
print's shape and orientation, but not the per-object placement/lift
translation: the object's position on the belt, the BeltSliceStrategy min-Z
lift, and the centering pre-translate are applied OUTSIDE
build_forward_transform() (see PrintObjectSlice.cpp), so its linear inverse
cannot undo them. The result was a constant offset (~20 mm on the belt-advance
axis) of the toolpaths from the model shell, on every model.

Recover the missing translation generally — independent of the offset's exact
source or the axis remap — by anchoring the back-transformed object body
(extrusions on layer_id >= 1, i.e. excluding the layer-0 prime/skirt) onto the
upright model bounding box, the same space the shells render in, and folding
that translation into the belt inverse before converting to libvgcode.

Replaces the previous Y=0 anchoring in LibVGCodeWrapper, which pinned the
toolpaths to the belt entry rather than to the model and so left the offset in
place for any object not sitting at the origin.
2026-06-21 06:48:44 +02:00
Tommaso Bianchi
695a1f897a belt: render the G-code preview in model (Cartesian) space
On a belt printer the emitted G-code is in the machine frame (45-deg sheared,
axis-remapped, scaled), so the toolpath preview shows the print as a sheared
slab floating off the bed. Map each toolpath vertex back to model/Cartesian
space for the "designed" view.

The back-transform is the inverse of the full G-code forward pipeline
(BeltGCodeWriter::to_machine_coords):
  model = [BeltForward^-1 if !gcode_back_transform] . AxisRemap^-1 . MachineFrame^-1
built from config, so it handles any rotation / shear / scale / axis-remap
combination, not just plain 45-deg belt slicing. Computed in load_as_gcode()
from print.config() and applied per-vertex inside libvgcode::convert (display
position only; layer_id, times and the volumetric/flow math keep the raw
machine values, so the layer slider and stats are unaffected).

- Toggle with the existing "Show designed view" checkbox / hotkey B; off shows
  the raw machine-frame G-code (useful for debugging the transform itself).
  Defaults to on.
- Belt printers skip the same-result-id load cache so the upright view applies
  and the toggle takes effect even when the G-code is unchanged.
- The object extrusions (layer_id >= 1) are anchored to the belt entry to drop
  the constant machine-origin offset (start-G-code belt advance) that the linear
  back-transform alone does not capture; start-G-code prime lines are excluded
  so they don't steal the anchor.
2026-06-21 06:48:44 +02:00
Tommaso Bianchi
2d69f6e17c belt: expose MachineFrameTransform's composed matrix
Add a const accessor for the shear*scale transform so the G-code viewer can
build the machine->model back-transform for the upright belt preview.
2026-06-21 06:48:44 +02:00
Joseph Robertson
340ce575e2 Merge branch 'main' into belt/baseChanges 2026-06-20 15:56:59 -05:00
Joseph Robertson
d795900fcf Merge pull request #64 from tommasobbianchi/feat/esun-pla-maxvolspeed-tuning
IdeaFormer IR3 V2: tune eSUN PLA white speed from HW max-vol-speed calibration
2026-06-18 09:42:19 -05:00
Joseph Robertson
9b1fb2217a Merge branch 'main' into belt/baseChanges 2026-06-18 09:41:14 -05:00
Tommaso Bianchi
ef6f65eacc IdeaFormer IR3 V2: tune eSUN PLA white speed from HW max-vol-speed calibration
Physical max-volumetric-speed test (belt #62 v4 asset) on the IR3 V2 with eSUN
PLA white: the wall stayed clean up to ~100 mm/s = ~20 mm3/s before
under-extrusion. The shipped cap of 10 mm3/s was ~half the real ceiling and
was silently throttling infill.

- eSUN PLA @IdeaFormer IR3 V2: filament_max_volumetric_speed 10 -> 20
- 0.20mm Standard @IdeaFormer IR3 V2: sparse_infill_speed 200 (~18 mm3/s at the
  new cap, no longer throttled). Outer wall (45), PA (0.12), accel (1000)
  unchanged — accuracy preserved.
- IdeaFormer.json version bump for profile-cache refresh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 07:13:59 +02:00
Joseph Robertson
0add523e1b Merge branch 'main' into belt/baseChanges 2026-06-13 08:23:47 -05:00
Joseph Robertson
375036f330 Merge pull request #44 from tommasobbianchi/feat/belt-skip-height-check
belt: don't reject long objects (skip build-height check on belt printers)
2026-06-13 08:23:26 -05:00
Joseph Robertson
fbbeb1fab0 Merge pull request #58 from HarrierPigeon/belt/tempTower-TommyB
Belt/temp tower tommy b
2026-06-12 05:53:32 -05:00
harrierpigeon
0bca3fd2e5 make belt printer specific temp tower only accessible to belt printers 2026-06-12 05:13:08 -05:00
Tommaso Bianchi
85fd613cf7 feat(belt/calib): add Overhang temperature-tower model (selectable) (#48)
Belt printers can't slice a tall vertical temperature tower. This adds a
belt-specific temperature-tower model — a row of discrete, individually
engraved provini laid along the belt, each printed at one temperature via
custom per-layer M104. Each provino is an inverted-L overhang that stresses
print quality, so the operator reads the best temperature off overhang
quality rather than a continuous ramp.

It is offered as a "Test model" choice in the temperature calibration dialog
(mirroring the Cornering test's selector), so users keep Joe's counter-rotated
sectioned tower as "Standard" and can pick this one as "Overhang":
- Calib_Params::test_model (existing field) carries the choice.
- Temp_Calibration_Dlg gets a Standard/Overhang radio.
- Plater::calib_temp belt branch: test_model 0 -> _calib_temp_belt_sectioned
  (unchanged Standard path), 1 -> the discrete-provini Overhang path.

Assets: belt_temp_provino_unit.stl + belt_temp_tower_<start>_<end>.stl (6
ranges) + gen_belt_temp_tower.py (manifold engraving). Based on
belt/generic-calibrations. The Overhang path is HW-validated on the IdeaFormer
IR3 V2 (discrete M104 + engraved numbers); not re-validated since the rebase.
2026-06-12 05:13:07 -05:00
Joseph Robertson
0da24cd38b Belt/Standard calibrations (#54)
Enables supported printing of standard Orcaslicer calibration profiles.

* Build 2 Checkpoint

* fix support generation wedge, ghost layers

* flip cornering tests 180 deg to waste less supports

* fix row spacing on the flow ratio calibrations

* more testing, this didn't fix anything

* switched rotation tools, same issue

* fixed Z-offset issues

* add rest of PA features, may look a bit weird on a belt

* make temp towers work

* re-enable spiral on calibrations that want it

* Final cleanup pre-PR and community testing
2026-06-12 03:14:12 -05:00
Rodrigo Faselli
d7b75540d0 Merge branch 'main' into belt/baseChanges 2026-06-11 11:59:53 -03:00
Tommaso Bianchi
b7bda9912b belt: fix IR3 V2 end G-code reversing the belt into the part (#56)
The IdeaFormer IR3 V2 End G-code ran `G28 ; home all`, which homes the
Z (belt) and Y (gantry) axes. On a belt printer Z is the conveyor, so
homing it runs the belt all the way back to origin, dragging the finished
part back under the gantry that G28 has just lowered — the head knocks the
print (reported by an IR3 V2 user; the `G1 Y50` lift came after the G28,
too late).

Replace the end sequence with a belt-safe one: switch to relative mode
(G91), lift the gantry for clearance, advance the belt forward one full
machine-depth (Z676, the 676 mm product depth) to eject the part and cycle
the belt surface clean, then home X only — never the Z/belt axis.
2026-06-11 09:30:35 -05:00
Tommaso Bianchi
4f3a608009 belt: don't flag the lead-in as an empty-layer error on belt printers (#47)
collect_layers_to_print() warns (CRITICAL) when an extrusion layer sits above
the previous one with an empty gap below — the fixed-bed assumption that
material with nothing under it is floating and unprintable. On a belt printer a
*leading* empty range (the gap starts at Z=0, no prior extrusion layer) is not
floating: it is the conveyor lead-in, and the part rests on the advancing belt
as the first material is laid down well above Z=0. A part not designed for a
belt (e.g. a flat test model tilted into the belt frame) then trips this as a
false "Object can't be printed for empty layer between 0 and N" error.

Suppress only the leading case (belt_printer && last_extrusion_layer == null);
genuine internal gaps are still flagged, since on a belt those can be an
over-angle overhang printing into air. Non-belt output is unchanged.
2026-06-10 23:54:02 -05:00
Tommaso Bianchi
f682ab5cd3 belt: replace height-check skip with a belt-correct vertical-clearance check
The original PR skipped the max-print-height check entirely on belt printers
because the sliced (virtual) Z is belt travel, not build height. As the reviewer
noted, that removed the only working height guard. Restore a correct guard:

- Print::validate: on belt printers, compare the upright object height
  (max over instances of the scene-space bbox) against printable_height directly.
  printable_height is the usable VERTICAL clearance above the belt: the gantry
  travels up the tilted plane (reach = height/cos(tilt)) and its axis range is
  sized for that (IR3 V2: ~354 mm gantry travel = 250 mm vertical at 45deg, and
  printable_height = 250). Hardware-confirmed 250 mm vertical clearance, so no
  cos(tilt) factor is applied.
- BuildVolume::set_belt_printer: drop the diagonal Z scaling; the build-volume Z
  already equals printable_height, keeping the live 'outside build volume'
  highlight in agreement with validate().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 21:41:18 +02:00
harrierpigeon
2bcb775b90 update IdeaFormer profiles to new generic belt printer config 2026-06-10 05:10:20 -05:00
Joseph Robertson
e29a82c672 add attribution and design notes 2026-06-10 05:10:20 -05:00
Joseph Robertson
5b243eec92 Relocate Pre-Slice remap logic 2026-06-10 05:10:20 -05:00
Joseph Robertson
fee6be98b2 unify frame tilt work 2026-06-10 05:10:20 -05:00
Joseph Robertson
9405ac5976 remove mesh origin snapping 2026-06-10 05:10:20 -05:00
Tommaso Bianchi
6ed2437848 Add IdeaFormer IR3 V2 belt printer profile - credit: tommasobbianchi (#43)
* Add IdeaFormer IR3 V2 belt printer profile

Self-contained vendor profile for the IdeaFormer IR3 V2 (45 deg belt printer):
machine (0.4 nozzle) + 0.20mm process + Generic PLA/PETG filaments, with the
belt machine-frame transforms set explicitly on the machine preset
(belt_printer, belt_slice_rotation x/45/global, build_plate_tilt_x=45,
gcode_remap_x/y/z, gcode_shear_z=pos_tan, gcode_scale_y=inv_cos).

The vendor bundles its own machine/process commons (fdm_belt_common,
fdm_klipper_common, fdm_machine_common, fdm_process_common) on purpose:
OrcaSlicer resolves system-preset inheritance per-vendor, so a profile that
inherits the Custom vendor's commons cross-vendor fails to resolve its parent
and the whole IdeaFormer vendor silently fails to load. Bundling the commons
(and listing them in IdeaFormer.json in dependency order) keeps the vendor
self-contained, matching how every other vendor folder is structured.

Machine limits, bed temperature (75 C for belt PLA) and start/end G-code are
taken from a working IdeaFormer IR3 V2.



* feat(belt/profile): eSUN PLA @IdeaFormer IR3 V2 — HW-calibrated belt filament

Add an eSUN PLA belt profile for the IR3 V2, inheriting Generic PLA @IdeaFormer
IR3 V2 (self-contained: parent is in the same IdeaFormer vendor, registered
after it in filament_list). HW-calibrated on the IR3 V2:
- nozzle_temperature 200/200 (temp-tower calibration)
- pressure_advance 0.12 (PA calibration)
- filament_max_volumetric_speed 10 mm³/s (max-vol-speed calibration: wall
  failed at 126 mm/s → 126 × 0.0798 mm³/mm ≈ 10 mm³/s)
2026-06-10 04:13:56 -05:00
Joseph Robertson
da3fee2dfa Merge branch 'main' into belt/baseChanges 2026-06-05 11:55:44 -05:00
Joseph Robertson
c0d6ae8540 Merge branch 'main' into belt/baseChanges 2026-06-05 03:12:27 -05:00
Joseph Robertson
573e1c6544 Belt/fix profiles and minor oopsies (#42)
* fix duplicate printer, bump version

* clean up extra tab in space

* fix generic defaults
2026-06-05 03:11:38 -05:00
Rodrigo Faselli
20be78a96e Merge branch 'main' into belt/baseChanges 2026-06-04 17:32:35 -03:00
Joseph Robertson
02d45c3258 Finish Fixes from Copilot Review (#39)
* fix: restore BuildVolume bounds when toggling belt mode

set_belt_printer() mutated m_bboxf when enabling but never restored
the original extents on disable or when switching infinite_y true->false,
leaving stale max.y/max.z values that broke collision and object_state
checks. Recompute m_bboxf from m_bed_shape + m_max_print_height at the
top of each call, then apply belt-specific adjustments on top.

Addresses Copilot review comment on PR #12998 (BuildVolume.cpp:196).

* chore: drop [BELT-DEBUG] to_machine_coords log to trace

Was emitting at warning level once per 0.2mm Z bucket during every belt
print export, polluting default user logs. Trace level matches the rest
of the belt diagnostics and is silent in production.

Addresses Copilot review comment on PR #12998 (BeltGCodeWriter.cpp:86).

* chore: drop [BELTRACE] make_perimeters/support logs to trace

Eight warning-level traces around make_perimeters and
generate_support_material were emitting on every call/exit during normal
slicing, cluttering default logs. They're concurrency-debug breadcrumbs
not user-facing diagnostics, so drop them to trace.

Addresses Copilot review comment on PR #12998 (PrintObject.cpp:438).

* perf: gate BeltSliceStrategy diagnostic bbox tracking behind compile flag

apply_to_trafo() walked every model vertex twice (once for min_z, once
for per-volume mesh/slicer bboxes) and emitted seven trace logs per
call. The bboxes and logs are diagnostic only; min_z is the load-bearing
output. Wrap the bbox accumulation, logging, and supporting headers in
SLIC3R_BELT_DIAGNOSTIC_LOG so production builds do the bare min_z scan.

Addresses Copilot review comment on PR #12998 (BeltSliceStrategy.cpp:95).

* fix: apply part_cooling_fan_min_pwm to first-layer plane fan crossings

apply_first_layer_plane_fan_eval emitted band-crossing M106 commands
through GCodeWriter::set_fan() without the per-printer PWM floor that
every other set_fan call in CoolingBuffer applies. On printers with a
non-zero part_cooling_fan_min_pwm, fans could fail to spin up at low
requested speeds near the belt surface.

Addresses Copilot review comment on PR #12998 (CoolingBuffer.cpp:1227).
2026-06-04 14:40:45 -05:00
harrierpigeon
f9888c7d7a Merge remote-tracking branch 'upstream/main' into belt/baseChanges 2026-05-31 05:17:32 -05:00
Joseph Robertson
0bda684dd7 delete mesh transforms (#37)
* delete mesh shear, scale and refactor logger

* clean up config options

* reorder UI elements
2026-05-31 05:08:42 -05:00
Joseph Robertson
8a578cdf00 Merge branch 'main' into belt/baseChanges 2026-05-30 21:39:03 -05:00
Rodrigo Faselli
6b256db012 Merge branch 'main' into belt/baseChanges 2026-05-28 07:44:43 -03:00
Joseph Robertson
2dc4900292 Copilot review fixes & upstream code interaction fix (#34)
* first pass at review issue 8
* delete detritus
* fix build compile error due to upstream changes
2026-05-27 21:53:04 -05:00
Joseph Robertson
0f75d6bc4e Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-27 19:25:02 -05:00
Joseph Robertson
e913621369 Merge branch 'main' into belt/baseChanges 2026-05-27 11:50:16 -05:00
Joseph Robertson
48b6db93b8 Belt/slice rotate (#33)
* initial commit
* fix upper bounds for assemblies
* significantly less Z shift issues, still not quite tamped down yet though
* add instrumentation to logs
* finally found the issue
* update printer defaults
2026-05-27 11:45:38 -05:00
Joseph Robertson
72cafcbe06 Merge branch 'main' into belt/baseChanges 2026-05-22 15:23:07 -05:00
Joseph Robertson
a9bae54f20 Rotate instead of shear for slicing stage (#30)
* initial commit

* fix upper bounds for assemblies

* significantly less Z shift issues, still not quite tamped down yet though

* add instrumentation to logs

* finally found the issue

* update printer defaults
2026-05-22 15:21:33 -05:00
Joseph Robertson
218881c6f6 fix assembly bounding box truncation problems noticed by hotcubcar (#28) 2026-05-20 02:46:41 -05:00
Joseph Robertson
cd5fb68d38 Merge branch 'main' into belt/baseChanges 2026-05-19 23:00:14 -05:00
Joseph Robertson
f87a46ec6e fix X mirroring (#26)
Thanks to @hotcubcar for catching this!
2026-05-19 22:54:50 -05:00
Rodrigo Faselli
8dc91d8b1d Merge branch 'main' into belt/baseChanges 2026-05-19 08:06:57 -03:00
Joseph Robertson
da8b11b8ab HOTFIX: update generic belt printer profile (#23)
oops
2026-05-19 01:06:39 -05:00
Joseph Robertson
c79970bedb Clean Up Settings Interface, Update Generic Profile (#22)
* clean up UI elements

* further cleaning

* final cleanup for first round of settings UI streamlining

* update generic belt printer settings

* fix generic again
2026-05-19 00:56:08 -05:00
harrierpigeon
7252f6acb7 Merge upstream/main into belt/rebase/may-18
Reconciles the belt-printer branch with upstream PRs through #13723. Six
files had conflicts; three additional files needed manual follow-up fixes
where the auto-merge produced code that referenced upstream-renamed fields
or changed function signatures.

Notable reconciliations:
- TreeSupport.cpp: kept belt-floor early-exit branches around HEAD's
  drop-down logic, folded upstream's `(distance_to_top > 0 ? 1 : 0)`
  formula into the non-belt-floor path (upstream PR #11812). Dropped dead
  `roof_enabled`/`force_tip_to_roof` locals.
- TreeSupport3D.cpp: combined upstream's safety-offset + remove_small
  changes with HEAD's belt-floor clip in the per-slice trim loop. Dropped
  HEAD's `else` block (superseded by upstream's rewritten bottom-contact
  propagation) and re-added the belt-floor clip into the new propagation
  loop. Gated the propagation on belt printers to prevent OOM when
  belt-floor clipping produces empty initial slices.
- TriangleSelector.{cpp,hpp}: merged both new `select_patch` parameters
  (HEAD's `up_direction` and upstream's `select_partially`); body uses
  `dot(up_direction)` for the overhang angle check and forwards
  `select_partially` to `select_triangle`.
- SupportMaterial.cpp: `slicing_params.soluble_interface` →
  `zero_gap_interface_bottom` in HEAD's `detect_belt_floor_bottom_contacts`,
  matching upstream's same-purpose rename at line 2495.
- Custom.json, GCodeWriter.cpp: simple additive merges (kept entries /
  includes from both sides).

Verified by building OrcaSlicer (RelWithDebInfo) after a full deps
rebuild (Eigen v5.0.1, libigl v2.6.0 are now managed deps) and slicing
a scaled Benchy on the NORMALIZER belt-printer profile without OOM.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 21:53:24 -05:00
Joseph Robertson
6a2d690f45 Decouple Slicing From Machine Frame Logic (#21)
* minor logic swap

* first attempt, has a race condition

* fixed the offset issue

* found a solution, I think things work now (at least once I quash this race condition)

* still chasing down race conditions

* add manual shear / scale order strategy swap

* tweak manual shear, fix ui uninitialization crash

* fix z height / g-code desync issue

* fix shear then scale cutoff planes

* getting closer

* fix support termination planes

* fix incorrect offsets in shear-then-scale mode

* test - fix overextrusion due to model/layer scale
2026-05-18 19:01:43 -05:00
RF47
8fa6a4602b fix profile indentation 2026-05-09 19:51:18 -03:00
harrierpigeon
0f29437135 Merge remote-tracking branch 'upstream/main' into belt/baseChanges
Conflicts resolved in src/libslic3r/GCode.cpp and src/slic3r/GUI/GUI_Factories.cpp.

GCode.cpp: combined upstream's air-filtration per-extruder gating
(activate_air_filtration_during_print / _on_completion), the new
extrusion-role-change gcode lambda, ZAA's path.z_contoured arc-fit
disable, raft-aware slow_down_layers branch, and Vec3d/Line3 ZAA
plumbing with the local belt-printer changes (path_on_first_layer,
effective_layer_index_for_point, should_disable_arc_fitting). All
auto-merged m_writer.X() calls converted to m_writer->X() to match
the local unique_ptr<GCodeWriter> refactor.

GUI_Factories.cpp: inserted brim_flow_ratio in the Support category
list and renumbered around the local build_plate_tilt_x/y entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 16:23:41 -05:00
SoftFever
75cc0de071 Merge branch 'main' into belt/baseChanges 2026-04-17 15:44:03 +08:00
Joseph Robertson
bc6d0ef0fb Add first layer detection and fan control - prototype 2026-04-13 22:29:23 -05:00
Joseph Robertson
c17ae25bbc Merge branch 'main' into belt/baseChanges 2026-04-13 21:34:34 -05:00
harrierpigeon
e981a517cd Merge branch 'belt/global-mesh-transform' into temp-pr19-merge 2026-04-10 11:49:37 -05:00
harrierpigeon
0703728e56 add global mesh transform option 2026-04-10 11:39:08 -05:00
SoftFever
1e9ee0c120 add a generic belt printer 2026-04-09 23:07:08 -05:00
harrierpigeon
e9a579b604 switch default shear axis, swap to tan(a) instead of cot(a) 2026-04-09 23:07:07 -05:00
harrierpigeon
783acd932a revert CLAUDE.md 2026-04-09 23:07:07 -05:00
harrierpigeon
c8a1bf3a99 Part 3.2: decouple axis remapping, enable viewing settings in Developer mode or when Belt mode is active 2026-04-09 23:07:07 -05:00
harrierpigeon
2facaac9e8 Part 3.1: refactor BeltTransform pipeline
add BeltGCodeWriter

add BeltGCode

consolidate changes into shared classes for BeltGcode
2026-04-09 23:07:07 -05:00
harrierpigeon
9bbac19de4 Part 2.7: Add G-code back-transform and tree support belt floor clipping
- Add BeltBackTransform class that inverts the shear/scale matrix and
  applies it in GCodeWriter::to_machine_coords() so G-code outputs in
  the machine's physical coordinate space, gated by new
  belt_gcode_back_transform config option
- Extend belt floor clipping to all three tree support pipelines
  (Prusa-style, Orca organic, TreeModelVolumes) with per-layer polygon
  clipping, anti-overhang integration, and belt raft extension layers
- Fix tree drop_nodes() belt termination, organic support global Z
  offset, collision calculation index bug, and first-layer brim/empty
  layer checks for belt printers

two-shot - first build built but didn't plumb to UI.  Woah.

add pre-slice axis remap, because Y needs to be Z

going to change tactic and move based on bbox min

switch to per axis snapping

per axis swap snap now per object

build plate tilt wasn't invalidating slicer settings

support upper bound now correct, need to get lower bound corrected

axis swapped support termination corrected

Z Shear works with and without pre-slice remap now
2026-04-09 23:07:07 -05:00
harrierpigeon
ea5c6776b3 Part 2.6: Add belt floor support clipping for all support types
- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch and sync belt_floor_z_shift with global_z_offset; fix
  invalidation so posSupportMaterial no longer resets slicing params
- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) with collision surface integration in
  TreeSupportData, belt extension layers, and first-layer brim
  suppression
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers, per-layer polygons in TreeModelVolumes, and
  post-generation layer trimming; fix pre-existing processing_last_mesh
  bug in calculateCollision()

Fix belt floor support clipping: z-shift, invalidation, and global offset

- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch (raw_bounding_box min.z vs trafo_centered m_belt_min_z) and
  sync belt_floor_z_shift with global_z_offset in global shear mode
- Fix invalidation so posSupportMaterial no longer resets slicing params,
  preventing the exact posSlice z-shift from being overwritten by the
  bounding-box approximation on support-only setting changes
- Remove double-counting of global z_offset on support layers — support
  already inherits the offset from object layers during generation

This Work Was Co-Authored-By Claude Opus 4.6 (1M context) <noreply@anthropic.com>

UI: gray out inactive belt sub-options, rename to mesh transforms, move to Advanced

Fix mesh clipping through build plate after belt shear/scale transform

Generalize G-code viewer designed-view toggle for full belt transform

Clip support layers to transformed belt floor plane

Supports below the tilted build plate (Z = shear_factor * from_axis - min_z)
are now clipped via half-plane intersection after generation. Belt floor
parameters stored in SlicingParameters and populated in both update_slicing_parameters()
and the static slicing_parameters() overload.

Make belt G-code viewer toggle more prominent, add B keyboard shortcut

- Add separator + teal "Belt Printer" header in legend panel
- Append [B] hint to checkbox label
- Add B key shortcut in GLCanvas3D to toggle designed/machine view
- Read belt_printer_angle from loaded G-code headers to enable belt view

Add per-axis global transform option for belt printer shear

New belt_shear_{x,y,z}_global bool configs. When enabled, shear incorporates
instance shift so objects at different bed positions get position-aware
transform (Z += factor * instance_shift_on_from_axis).

Fix global shear: use layer Z offset instead of mesh transform, add config invalidation

- Global shear offset applied as post-slicing layer print_z adjustment
  instead of mesh transform (which was absorbed by min_z normalization
  or shifted mesh out of slice range)
- Register all belt transform options in Print::invalidate_state_by_config_options
  to trigger posSlice re-slicing (the fallback only invalidated Print steps,
  not PrintObject steps — belt changes had no effect without manual re-slice)
- Belt gcode remap options added to steps_gcode (gcode-export only)
- Skip empty-first-layer check for belt objects with global Z offset

WIP: split instances for global shear, relative Z offsets, debug logging

- PrintApply: when belt global mode active, prevent instance grouping by
  adding unique Z perturbation to trafo — each copy becomes its own
  PrintObject with independent layers
- PrintObjectSlice: compute global Z offset relative to minimum Y shift
  across all PrintObjects (lowest-Y object stays at Z=0)
- Debug logging (warning level) for belt global shift values and offsets

Known issues:
- Cached posSlice results cause stale offsets when mixing copies with
  individually-added objects — need to compute min baseline outside slice()
- Supports still generate to Z=0 instead of object's global Z offset

Fix global shear for copied objects: disable shared-object layer optimization

When belt global Z shear is active, each object needs unique layer Z
values based on its bed position. The shared-object optimization was
causing copies to reuse the source object's layers (and its Z offset)
instead of computing their own position-based offset.

started work on getting supports to work properly

one step forward, one step back

this version didn't quite work.  Getting somewhere though

about to add UI controllable tests

added configuration options for supports

tweak CLAUDE.md to be more aggressive for my machine.  This commit should probably be pulled out before contributing upstream

still chasing down some bugs

moving objects between slices no longer results in improper Z-height because of caching

added more data to the debug logs

Z offset is getting more global again

still not quite there, I think there's a fundamental logic flaw?

hunting for bugs

finally have a functional fix

Add belt floor clipping to tree supports (organic and non-organic)

- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) in draw_circles() and terminate nodes at the
  belt surface instead of the horizontal build plate
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers for sub-floor branch generation, per-layer belt
  floor polygons in TreeModelVolumes, and post-generation layer trimming
- Fix pre-existing processing_last_mesh bug in TreeModelVolumes that
  prevented m_anti_overhang (support blockers) from ever being applied;
  skip empty first layer check for belt printers

Commits:

current approach: make a face surface to build supports to

closer!

supports now terminate on shear plane, now need to get shear plane to correct Z height

nearly there

chasing down logic issues still

committing for checkpoint, this still does not work

still got logic problems...

cull support clipping

stashing changes for now.  Going to focus on getting the global shear OFF support generation dialed first.

beginning per object shear calcs

Local shear transform is on correct Z offset now

local shear finally works now and needs more testing

global shear works now, needs thorough testing

debugging non-45 degree angles

debugging part 2

supports at all angles work now

remove debug logging

Add belt floor collision to non-organic tree support pipeline

- Integrate belt floor as a collision surface in TreeSupportData so
  branches route around the belt naturally, replacing the explicit
  termination checks in drop_nodes()
- Add belt extension layers below the object after draw_circles() to
  allow support geometry to extend to the diagonal belt surface instead
  of terminating at a horizontal first layer
- Fix coordinate overflow in belt floor polygons (scale_(1e4) exceeds
  int32), skip first-layer brim expansion for belt printers, and
  extend empty first layer check bypass to all belt modes

add debug logging, Z translate for tree supports

still not seeing any cutoff surface yet

adding debug options

attempt #2 at trees

if hit Z buildplate stop but don't set to_buildplate true

getting closer

tree support almost there, just need to get rid of the circles at the beginning

getting closer

belt / shear plane clip works, need to figure out the buidlplate plane issues

more logic, added debugging logs

supports now extend somewhat below Z=0 in global shear mode

fix bad alloc, add 10mm below build plate

fully works now

shear transform + prusa tree support generation works now.

pull out debug logging
2026-04-09 23:07:07 -05:00
harrierpigeon
98f4d34dcb Part 2.5: Add global shear transform, support clipping, and belt UI improvements
- Implement per-object global shear transform in PrintObject with
  layer Z-offset calculation, config invalidation, and fix for
  shared-object layer optimization breaking copied objects
- Clip support layers to the transformed belt floor plane and begin
  work on tree support adaptation for sheared coordinate space
- Improve belt UI: gray out inactive sub-options, add B keyboard
  shortcut for G-code viewer design-view toggle, fix mesh clipping
  through build plate after shear/scale transform

y' = y + z·cot(α),
  while x' = x and z' = z

getting closer to customizable variant

getting closer

X/Y/Z shear initial

clean up UI

add 1/sin(a) transform, idea taken from blackbelt cura plugin

Things work now (turns out I've been using the wrong set of  transforms)
2026-04-09 23:07:07 -05:00
harrierpigeon
501aff7e53 Part 2: Replace belt rotation w/ per-axis shear transforms and G-code axis remap
- Replace monolithic belt rotation transform with independent per-axis
    shear controls (mode/angle/source-axis for X, Y, Z) and G-code axis
    remapping, giving full flexibility to match any belt printer's
    coordinate system
  - Remove all rotation mode logic and intermediate type+axes dropdowns,
    simplifying the pipeline to pure shear matrices while preserving the
    default behavior (Y += Z*cot(45deg) with identity remap)
  - Clean up GCodeWriter, GCodeProcessor, and GCodeViewer for the new
    shear-only model; expose 12 new settings in printer UI via
    Tab.cpp/Preset.cpp

Implement belt printer tilted slicing

Implement the core belt slicing pipeline that makes the slicer
tilt-aware:

Step 1: GCodeWriter::to_machine_coords() - R(+alpha, X) rotation
  from slicing frame to machine frame
Step 2: PrintObject - belt-rotated object height calculation
  (y*sin(a) + z*cos(a)) for correct layer count
Step 3: PrintObjectSlice - apply R(-alpha, X) rotation trafo so
  horizontal slice planes correspond to belt-parallel planes,
  with Z-shift computed from model volumes
Step 4: GCodeProcessor - machine-frame preview (no transform needed)
Step 5: 3DBed - rotate bed visualization about X by belt angle

Fix: belt surface IS the build plate, no mesh rotation

Currently still slicing perpendicular to the belt normal.  Need to figure out why.

Fix G-code Z sign: use R(-alpha, X) so Z+ is away from belt

The previous R(+alpha, X) transform produced negative Z values
(-y*sin(a) term dominated). Changed to R(-alpha, X) which gives
machine_z = y*sin(a) + z*cos(a), always positive for points
above the belt surface. Z increases with each layer as expected.

reverting and changing slice methodology

Add pink slicing direction arrow from origin

Shows the effective slicing direction (gantry normal) as a pink
arrow from the origin. Shorter and wider than the gravity arrow.
Direction: R(+alpha, X) * Z = (0, -sin(a), cos(a)), which is
the layer stacking direction in the original mesh frame.

Fix slicing arrow visibility and add raw G-code toggle

- Disable depth test for pink slicing arrow so it renders on top of
  the tilted bed geometry (was being occluded)
- Remove unnecessary 5mm Z-offset from arrow position
- Add m_belt_show_raw toggle to GCodeViewer
- Add "Show raw G-code (slicing frame)" checkbox in legend when
  belt mode is active

Implement to_machine_coords inverse rotation for belt printer G-code

The slicing pipeline rotates the mesh by R(-alpha, X) and shifts Z to
start at 0. The G-code output now undoes this transform via
to_machine_coords: R(+alpha, X) * T(0,0,+z_shift), recovering the
original machine-frame coordinates where Y is horizontal and Z is
vertical.

Changes:
- GCodeWriter: implement to_machine_coords with inverse rotation + Z-shift
- GCodeWriter: add belt_z_shift member and setter/getter
- GCode.cpp: compute Z-shift from print objects (same logic as
  PrintObjectSlice) and pass to writer; write z_shift to G-code header
- GCodeProcessor: parse belt_z_shift from G-code header
- GCodeViewer: store belt_z_shift from processor result

Wire raw G-code toggle to apply slicing-frame view transform

When "Show raw G-code (slicing frame)" is checked in the preview
legend, the view matrix is modified to apply R(-alpha, X) * T(0,0,-z_shift)
to the toolpath rendering. This shows the G-code as it was during
slicing: rotated part with horizontal layers.

Default (unchecked): machine-frame view — upright part with tilted layers.

Remove belt printer placeholder comment from GCodeProcessor

The preview now correctly displays machine-frame G-code with the
optional raw view toggle. No transform is needed in the processor.
2026-04-09 23:07:06 -05:00
harrierpigeon
c808653565 Add belt printer transform pipeline: slicing rotation, G-code coords, preview
- Implement core belt slicing pipeline: R(-alpha, X) mesh rotation in PrintObjectSlice with corrected object height calculation for proper layer count
Add to_machine_coords() in GCodeWriter to convert slicing-frame coordinates back to machine-frame, propagated through GCode,
GCodeProcessor, and GCodeViewer
Add belt-mode UI: tilted bed visualization, slicing-direction arrow, and raw G-code toggle to switch between machine-frame and slicing-frame views

This is a combination of 6 commits.

checkpoint 1: initial MVP.  Slicing functions, but rotates instead of skews are happening and a lot of other stuff too

getting somewhere, getting to the point where I need to figure out how to verify this stuff

this appears to be a dead end.

getting somewhere I think maybe

I'm pretty sure we've completely lost the plot at this point and need to restart this process...

remove slice logic in preparation for new, more invasive plan
2026-04-09 23:07:06 -05:00
harrierpigeon
a7441c7f48 stage in changes from off-plate-gravity and remove stuff I didn't need 2026-04-09 23:07:06 -05:00
SoftFever
3bc13e5cfd add a generic belt printer 2026-04-07 10:37:34 +08:00
SoftFever
141749a6f2 Merge branch 'main' into belt/baseChanges 2026-04-06 22:52:31 +08:00
harrierpigeon
4634a5dfd7 switch default shear axis, swap to tan(a) instead of cot(a) 2026-03-30 13:25:40 -05:00
harrierpigeon
372139c770 revert CLAUDE.md 2026-03-30 13:25:40 -05:00
harrierpigeon
44eebdb8ad Part 3.2: decouple axis remapping, enable viewing settings in Developer mode or when Belt mode is active 2026-03-30 13:25:40 -05:00
harrierpigeon
c7aa4ca3ef Part 3.1: refactor BeltTransform pipeline
add BeltGCodeWriter

add BeltGCode

consolidate changes into shared classes for BeltGcode
2026-03-30 13:25:40 -05:00
harrierpigeon
b297f68921 Part 2.7: Add G-code back-transform and tree support belt floor clipping
- Add BeltBackTransform class that inverts the shear/scale matrix and
  applies it in GCodeWriter::to_machine_coords() so G-code outputs in
  the machine's physical coordinate space, gated by new
  belt_gcode_back_transform config option
- Extend belt floor clipping to all three tree support pipelines
  (Prusa-style, Orca organic, TreeModelVolumes) with per-layer polygon
  clipping, anti-overhang integration, and belt raft extension layers
- Fix tree drop_nodes() belt termination, organic support global Z
  offset, collision calculation index bug, and first-layer brim/empty
  layer checks for belt printers

two-shot - first build built but didn't plumb to UI.  Woah.

add pre-slice axis remap, because Y needs to be Z

going to change tactic and move based on bbox min

switch to per axis snapping

per axis swap snap now per object

build plate tilt wasn't invalidating slicer settings

support upper bound now correct, need to get lower bound corrected

axis swapped support termination corrected

Z Shear works with and without pre-slice remap now
2026-03-30 13:25:40 -05:00
harrierpigeon
7ff6bc42b1 Part 2.6: Add belt floor support clipping for all support types
- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch and sync belt_floor_z_shift with global_z_offset; fix
  invalidation so posSupportMaterial no longer resets slicing params
- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) with collision surface integration in
  TreeSupportData, belt extension layers, and first-layer brim
  suppression
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers, per-layer polygons in TreeModelVolumes, and
  post-generation layer trimming; fix pre-existing processing_last_mesh
  bug in calculateCollision()

Fix belt floor support clipping: z-shift, invalidation, and global offset

- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch (raw_bounding_box min.z vs trafo_centered m_belt_min_z) and
  sync belt_floor_z_shift with global_z_offset in global shear mode
- Fix invalidation so posSupportMaterial no longer resets slicing params,
  preventing the exact posSlice z-shift from being overwritten by the
  bounding-box approximation on support-only setting changes
- Remove double-counting of global z_offset on support layers — support
  already inherits the offset from object layers during generation

This Work Was Co-Authored-By Claude Opus 4.6 (1M context) <noreply@anthropic.com>

UI: gray out inactive belt sub-options, rename to mesh transforms, move to Advanced

Fix mesh clipping through build plate after belt shear/scale transform

Generalize G-code viewer designed-view toggle for full belt transform

Clip support layers to transformed belt floor plane

Supports below the tilted build plate (Z = shear_factor * from_axis - min_z)
are now clipped via half-plane intersection after generation. Belt floor
parameters stored in SlicingParameters and populated in both update_slicing_parameters()
and the static slicing_parameters() overload.

Make belt G-code viewer toggle more prominent, add B keyboard shortcut

- Add separator + teal "Belt Printer" header in legend panel
- Append [B] hint to checkbox label
- Add B key shortcut in GLCanvas3D to toggle designed/machine view
- Read belt_printer_angle from loaded G-code headers to enable belt view

Add per-axis global transform option for belt printer shear

New belt_shear_{x,y,z}_global bool configs. When enabled, shear incorporates
instance shift so objects at different bed positions get position-aware
transform (Z += factor * instance_shift_on_from_axis).

Fix global shear: use layer Z offset instead of mesh transform, add config invalidation

- Global shear offset applied as post-slicing layer print_z adjustment
  instead of mesh transform (which was absorbed by min_z normalization
  or shifted mesh out of slice range)
- Register all belt transform options in Print::invalidate_state_by_config_options
  to trigger posSlice re-slicing (the fallback only invalidated Print steps,
  not PrintObject steps — belt changes had no effect without manual re-slice)
- Belt gcode remap options added to steps_gcode (gcode-export only)
- Skip empty-first-layer check for belt objects with global Z offset

WIP: split instances for global shear, relative Z offsets, debug logging

- PrintApply: when belt global mode active, prevent instance grouping by
  adding unique Z perturbation to trafo — each copy becomes its own
  PrintObject with independent layers
- PrintObjectSlice: compute global Z offset relative to minimum Y shift
  across all PrintObjects (lowest-Y object stays at Z=0)
- Debug logging (warning level) for belt global shift values and offsets

Known issues:
- Cached posSlice results cause stale offsets when mixing copies with
  individually-added objects — need to compute min baseline outside slice()
- Supports still generate to Z=0 instead of object's global Z offset

Fix global shear for copied objects: disable shared-object layer optimization

When belt global Z shear is active, each object needs unique layer Z
values based on its bed position. The shared-object optimization was
causing copies to reuse the source object's layers (and its Z offset)
instead of computing their own position-based offset.

started work on getting supports to work properly

one step forward, one step back

this version didn't quite work.  Getting somewhere though

about to add UI controllable tests

added configuration options for supports

tweak CLAUDE.md to be more aggressive for my machine.  This commit should probably be pulled out before contributing upstream

still chasing down some bugs

moving objects between slices no longer results in improper Z-height because of caching

added more data to the debug logs

Z offset is getting more global again

still not quite there, I think there's a fundamental logic flaw?

hunting for bugs

finally have a functional fix

Add belt floor clipping to tree supports (organic and non-organic)

- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) in draw_circles() and terminate nodes at the
  belt surface instead of the horizontal build plate
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers for sub-floor branch generation, per-layer belt
  floor polygons in TreeModelVolumes, and post-generation layer trimming
- Fix pre-existing processing_last_mesh bug in TreeModelVolumes that
  prevented m_anti_overhang (support blockers) from ever being applied;
  skip empty first layer check for belt printers

Commits:

current approach: make a face surface to build supports to

closer!

supports now terminate on shear plane, now need to get shear plane to correct Z height

nearly there

chasing down logic issues still

committing for checkpoint, this still does not work

still got logic problems...

cull support clipping

stashing changes for now.  Going to focus on getting the global shear OFF support generation dialed first.

beginning per object shear calcs

Local shear transform is on correct Z offset now

local shear finally works now and needs more testing

global shear works now, needs thorough testing

debugging non-45 degree angles

debugging part 2

supports at all angles work now

remove debug logging

Add belt floor collision to non-organic tree support pipeline

- Integrate belt floor as a collision surface in TreeSupportData so
  branches route around the belt naturally, replacing the explicit
  termination checks in drop_nodes()
- Add belt extension layers below the object after draw_circles() to
  allow support geometry to extend to the diagonal belt surface instead
  of terminating at a horizontal first layer
- Fix coordinate overflow in belt floor polygons (scale_(1e4) exceeds
  int32), skip first-layer brim expansion for belt printers, and
  extend empty first layer check bypass to all belt modes

add debug logging, Z translate for tree supports

still not seeing any cutoff surface yet

adding debug options

attempt #2 at trees

if hit Z buildplate stop but don't set to_buildplate true

getting closer

tree support almost there, just need to get rid of the circles at the beginning

getting closer

belt / shear plane clip works, need to figure out the buidlplate plane issues

more logic, added debugging logs

supports now extend somewhat below Z=0 in global shear mode

fix bad alloc, add 10mm below build plate

fully works now

shear transform + prusa tree support generation works now.

pull out debug logging
2026-03-30 13:25:40 -05:00
harrierpigeon
719af2d81d Part 2.5: Add global shear transform, support clipping, and belt UI improvements
- Implement per-object global shear transform in PrintObject with
  layer Z-offset calculation, config invalidation, and fix for
  shared-object layer optimization breaking copied objects
- Clip support layers to the transformed belt floor plane and begin
  work on tree support adaptation for sheared coordinate space
- Improve belt UI: gray out inactive sub-options, add B keyboard
  shortcut for G-code viewer design-view toggle, fix mesh clipping
  through build plate after shear/scale transform

y' = y + z·cot(α),
  while x' = x and z' = z

getting closer to customizable variant

getting closer

X/Y/Z shear initial

clean up UI

add 1/sin(a) transform, idea taken from blackbelt cura plugin

Things work now (turns out I've been using the wrong set of  transforms)
2026-03-30 13:25:40 -05:00
harrierpigeon
cb13a22e57 Part 2: Replace belt rotation w/ per-axis shear transforms and G-code axis remap
- Replace monolithic belt rotation transform with independent per-axis
    shear controls (mode/angle/source-axis for X, Y, Z) and G-code axis
    remapping, giving full flexibility to match any belt printer's
    coordinate system
  - Remove all rotation mode logic and intermediate type+axes dropdowns,
    simplifying the pipeline to pure shear matrices while preserving the
    default behavior (Y += Z*cot(45deg) with identity remap)
  - Clean up GCodeWriter, GCodeProcessor, and GCodeViewer for the new
    shear-only model; expose 12 new settings in printer UI via
    Tab.cpp/Preset.cpp

Implement belt printer tilted slicing

Implement the core belt slicing pipeline that makes the slicer
tilt-aware:

Step 1: GCodeWriter::to_machine_coords() - R(+alpha, X) rotation
  from slicing frame to machine frame
Step 2: PrintObject - belt-rotated object height calculation
  (y*sin(a) + z*cos(a)) for correct layer count
Step 3: PrintObjectSlice - apply R(-alpha, X) rotation trafo so
  horizontal slice planes correspond to belt-parallel planes,
  with Z-shift computed from model volumes
Step 4: GCodeProcessor - machine-frame preview (no transform needed)
Step 5: 3DBed - rotate bed visualization about X by belt angle

Fix: belt surface IS the build plate, no mesh rotation

Currently still slicing perpendicular to the belt normal.  Need to figure out why.

Fix G-code Z sign: use R(-alpha, X) so Z+ is away from belt

The previous R(+alpha, X) transform produced negative Z values
(-y*sin(a) term dominated). Changed to R(-alpha, X) which gives
machine_z = y*sin(a) + z*cos(a), always positive for points
above the belt surface. Z increases with each layer as expected.

reverting and changing slice methodology

Add pink slicing direction arrow from origin

Shows the effective slicing direction (gantry normal) as a pink
arrow from the origin. Shorter and wider than the gravity arrow.
Direction: R(+alpha, X) * Z = (0, -sin(a), cos(a)), which is
the layer stacking direction in the original mesh frame.

Fix slicing arrow visibility and add raw G-code toggle

- Disable depth test for pink slicing arrow so it renders on top of
  the tilted bed geometry (was being occluded)
- Remove unnecessary 5mm Z-offset from arrow position
- Add m_belt_show_raw toggle to GCodeViewer
- Add "Show raw G-code (slicing frame)" checkbox in legend when
  belt mode is active

Implement to_machine_coords inverse rotation for belt printer G-code

The slicing pipeline rotates the mesh by R(-alpha, X) and shifts Z to
start at 0. The G-code output now undoes this transform via
to_machine_coords: R(+alpha, X) * T(0,0,+z_shift), recovering the
original machine-frame coordinates where Y is horizontal and Z is
vertical.

Changes:
- GCodeWriter: implement to_machine_coords with inverse rotation + Z-shift
- GCodeWriter: add belt_z_shift member and setter/getter
- GCode.cpp: compute Z-shift from print objects (same logic as
  PrintObjectSlice) and pass to writer; write z_shift to G-code header
- GCodeProcessor: parse belt_z_shift from G-code header
- GCodeViewer: store belt_z_shift from processor result

Wire raw G-code toggle to apply slicing-frame view transform

When "Show raw G-code (slicing frame)" is checked in the preview
legend, the view matrix is modified to apply R(-alpha, X) * T(0,0,-z_shift)
to the toolpath rendering. This shows the G-code as it was during
slicing: rotated part with horizontal layers.

Default (unchecked): machine-frame view — upright part with tilted layers.

Remove belt printer placeholder comment from GCodeProcessor

The preview now correctly displays machine-frame G-code with the
optional raw view toggle. No transform is needed in the processor.
2026-03-30 13:25:40 -05:00
harrierpigeon
ed6ea086a2 Add belt printer transform pipeline: slicing rotation, G-code coords, preview
- Implement core belt slicing pipeline: R(-alpha, X) mesh rotation in PrintObjectSlice with corrected object height calculation for proper layer count
Add to_machine_coords() in GCodeWriter to convert slicing-frame coordinates back to machine-frame, propagated through GCode,
GCodeProcessor, and GCodeViewer
Add belt-mode UI: tilted bed visualization, slicing-direction arrow, and raw G-code toggle to switch between machine-frame and slicing-frame views

This is a combination of 6 commits.

checkpoint 1: initial MVP.  Slicing functions, but rotates instead of skews are happening and a lot of other stuff too

getting somewhere, getting to the point where I need to figure out how to verify this stuff

this appears to be a dead end.

getting somewhere I think maybe

I'm pretty sure we've completely lost the plot at this point and need to restart this process...

remove slice logic in preparation for new, more invasive plan
2026-03-30 13:25:40 -05:00
harrierpigeon
08aa277974 stage in changes from off-plate-gravity and remove stuff I didn't need 2026-03-30 13:25:40 -05:00
208 changed files with 17536 additions and 3267 deletions

View File

@@ -119,6 +119,10 @@ Download the **Windows Installer exe** for your preferred version from the [rele
- This file may already be available on your computer if you've installed visual studio. Check the following location: `%VCINSTALLDIR%Redist\MSVC\v142`
</details>
### Microsoft Store
Install from the [Microsoft Store](https://apps.microsoft.com/detail/9mv6gl23xm59) when you prefer a Store-signed package (helps on Windows 11 Smart App Control).
### Windows Package Manager
```shell

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -3608,6 +3608,9 @@ msgstr ""
msgid "Arranging"
msgstr ""
msgid "Arranging "
msgstr ""
msgid "Arranging canceled."
msgstr ""
@@ -8661,6 +8664,17 @@ msgstr ""
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr ""
msgid "Dimmed layer brightness"
msgstr ""
msgid "%"
msgstr ""
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
msgid "Login region"
msgstr ""
@@ -12357,12 +12371,26 @@ msgstr ""
msgid "Intra-layer order"
msgstr ""
msgid "Print order within a single layer."
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
msgid "As object list"
msgstr ""
msgid "Best of all (shortest path)"
msgstr ""
msgid "Snake"
msgstr ""
msgid "Slow printing down for better layer cooling"
msgstr ""
@@ -17218,6 +17246,15 @@ msgid ""
"Please select one that should be used."
msgstr ""
msgid "Auto-scale for nozzle"
msgstr ""
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
msgid "PA Calibration"
msgstr ""
@@ -17340,6 +17377,12 @@ msgstr ""
msgid "End speed: "
msgstr ""
msgid "Auto-adjust to max volumetric speed"
msgstr ""
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr ""
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -17347,6 +17390,39 @@ msgid ""
"end > start + step"
msgstr ""
#, possible-c-format, possible-boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
#, possible-c-format, possible-boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
#, possible-c-format, possible-boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
msgid "Continue anyway?"
msgstr ""
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr ""
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr ""
msgid "Start retraction length: "
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2025-03-15 10:55+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -3931,6 +3931,10 @@ msgstr "Organitzant..."
msgid "Arranging"
msgstr "Organitzant"
# AI Translated
msgid "Arranging "
msgstr "Organitzant "
msgid "Arranging canceled."
msgstr "S'ha cancel·lat l'ordenació."
@@ -9350,6 +9354,21 @@ msgstr "Enfosquir les capes inferiors"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "En desplaçar el control lliscant de capes a la previsualització laminada, mostra enfosquides les capes per sota de l'actual, de manera que només la capa que s'està visualitzant es vegi amb la lluminositat completa."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Brillantor de les capes enfosquides"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Amb quina brillantor es mostren les capes enfosquides quan \"Enfosquir les capes inferiors\" està activat.\n"
"99% amb prou feines s'enfosqueix, 0% les mostra negres. Limitat al 99% perquè el 100% seria el mateix que desactivar l'opció."
msgid "Login region"
msgstr "Regió d'inici de sessió"
@@ -13494,12 +13513,37 @@ msgstr "Objecte"
msgid "Intra-layer order"
msgstr "Ordre intracapa"
msgid "Print order within a single layer."
msgstr "Ordre d'impressió dins d'una sola capa"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Ordre en què es visiten les instàncies dels objectes dins d'una mateixa capa, que determina quant recorregut es dedica a moure's entre elles.\n"
"\n"
"Per defecte: encadenament pel veí més proper, refinat amb 2-opt i eliminació de creuaments. Una bona opció general.\n"
"Com a llista d'objectes: les instàncies s'imprimeixen en el mateix ordre que la llista d'objectes, sense cap optimització del recorregut. Feu-lo servir quan necessiteu un ordre previsible i controlat manualment.\n"
"La millor de totes (camí més curt): s'avaluen totes les estratègies i s'utilitza la més curta. L'ordre de les instàncies dels objectes es decideix una sola vegada per a tota la impressió, mentre que l'ordre de les illes individuals es decideix per capa, de manera que capes diferents poden acabar utilitzant estratègies diferents. El laminat és una mica més lent.\n"
"Serpentí: recorregut en serpentina, fila per fila, refinat amb 2-opt. Adequat per a graelles regulars de moltes peces petites.\n"
"\n"
"Amb diversos filaments o eines a la mateixa capa, minimitzar els canvis d'eina té prioritat: els objectes s'agrupen primer per filament i aquest paràmetre només ordena les instàncies dins de cada grup de filament, de manera que la seqüència global pot no semblar el camí més curt per la safata."
msgid "As object list"
msgstr "Com a llista d'objectes"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "La millor de totes (camí més curt)"
# AI Translated
msgid "Snake"
msgstr "Serpentí"
msgid "Slow printing down for better layer cooling"
msgstr "Reduir la velocitat d'impressió per millorar la refrigeració de les capes"
@@ -18927,6 +18971,20 @@ msgstr ""
"Hi ha diverses adreces IP que responen al nom d'amfitrió( host ) %1%.\n"
"Seleccioneu-ne la que s'hagi d'utilitzar."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Escala automàtica segons el broquet"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Aquest model està dissenyat per a un broquet de 0,4 mm amb una alçada de capa de 0,2 mm. \n"
"Quan l'opció d'escalat està activada (recomanat), es redimensiona dinàmicament per adaptar-se al diàmetre del broquet actual i a una alçada de capa adequada, cosa que fa que la prova sigui precisa i fàcil de llegir.\n"
"Desactiveu l'escalat només si voleu imprimir el model de referència exactament tal com és."
msgid "PA Calibration"
msgstr "Calibratge PA( Pressure Advance )"
@@ -19063,6 +19121,14 @@ msgstr "Velocitat d'inici: "
msgid "End speed: "
msgstr "Velocitat final: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Ajust automàtic a la velocitat volumètrica màxima"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Si la velocitat final superés la velocitat volumètrica màxima del filament, redueix automàticament l'alçada de capa (mantenint valors estàndard i respectant els límits de la màquina) per assolir-la. Si ni tan sols l'alçada de capa mínima és suficient, redueix la velocitat final."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19074,6 +19140,57 @@ msgstr ""
"pas >= 0\n"
"final >inici + pas )"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"La velocitat final (%.0f mm/s) supera la velocitat volumètrica màxima del filament (%.1f mm³/s), cosa que limita el perímetre exterior a uns %.0f mm/s amb aquesta amplada de línia i alçada de capa.\n"
" Les velocitats superiors es retallaran, de manera que els blocs superiors de la torre no s'imprimiran a la velocitat sol·licitada.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"La velocitat final (%.0f mm/s) supera la velocitat volumètrica màxima del filament (%.1f mm³/s) amb l'alçada de capa per defecte (%.2f mm).\n"
"\n"
"L'alçada de capa s'ha reduït a %.2f mm (un valor utilitzat pels perfils d'aquesta impressora) perquè la torre pugui assolir la velocitat sol·licitada."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Fins i tot amb l'alçada de capa més petita utilitzada pels perfils d'aquesta impressora (%.2f mm), la velocitat final (%.0f mm/s) supera la velocitat volumètrica màxima del filament (%.1f mm³/s).\n"
"\n"
"L'alçada de capa s'establirà a %.2f mm i la velocitat final es reduirà a %.0f mm/s.\n"
"\n"
"Voleu continuar?"
# AI Translated
msgid "Continue anyway?"
msgstr "Voleu continuar igualment?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Voleu activar \"Ajust automàtic\" per corregir-ho automàticament o continuar igualment?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Voleu activar \"Escala automàtica segons el broquet\" i \"Ajust automàtic\" per corregir-ho automàticament o continuar igualment?"
msgid "Start retraction length: "
msgstr "Longitud de la retracció d'inici: "
@@ -21770,6 +21887,9 @@ msgstr ""
"Evitar la deformació( warping )\n"
"Sabíeu que quan imprimiu materials propensos a deformar-se, com ara l'ABS, augmentar adequadament la temperatura del llit pot reduir la probabilitat de deformació?"
#~ msgid "Print order within a single layer."
#~ msgstr "Ordre d'impressió dins d'una sola capa"
#~ msgid "Bottom"
#~ msgstr "Inferior"
@@ -21856,9 +21976,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Continue to sync filaments"
#~ msgstr "Continua sincronitzant filaments"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Jakub Hencl\n"
"Language-Team: \n"
@@ -3888,6 +3888,10 @@ msgstr "Uspořádání..."
msgid "Arranging"
msgstr "Uspořádání"
# AI Translated
msgid "Arranging "
msgstr "Rozkládání "
msgid "Arranging canceled."
msgstr "Uspořádání zrušeno."
@@ -9305,6 +9309,21 @@ msgstr "Ztmavit nižší vrstvy"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Při posouvání posuvníku vrstev v náhledu po slicování vykresluje vrstvy pod aktuální ztmavené, takže v plném jasu je zobrazena pouze prohlížená vrstva."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Jas ztmavených vrstev"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Jak jasně se vykreslují ztmavené vrstvy, když je zapnuta volba „Ztmavit nižší vrstvy“.\n"
"99 % znamená sotva znatelné ztmavení, 0 % je vykreslí černě. Maximum je 99 %, protože 100 % by odpovídalo vypnutí této volby."
msgid "Login region"
msgstr "Oblast přihlášení"
@@ -13475,12 +13494,37 @@ msgstr "Podle objektu"
msgid "Intra-layer order"
msgstr "Pořadí v rámci vrstvy"
msgid "Print order within a single layer."
msgstr "Pořadí tisku v rámci jedné vrstvy."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Pořadí, v jakém se v rámci jedné vrstvy navštěvují instance objektů; určuje, kolik přejezdů se stráví přesuny mezi nimi.\n"
"\n"
"Výchozí: řetězení metodou nejbližšího souseda, doladěné algoritmem 2-opt a odstraněním křížení. Dobrá volba pro obecné použití.\n"
"Jako seznam objektů: instance se tisknou ve stejném pořadí jako v seznamu objektů, bez jakékoli optimalizace dráhy. Použijte, když potřebujete předvídatelné, ručně řízené pořadí.\n"
"Nejlepší ze všech (nejkratší dráha): vyhodnotí se všechny strategie a použije se ta nejkratší. Pořadí instancí objektů se určí jednou pro celý tisk, zatímco pořadí jednotlivých ostrůvků se určuje pro každou vrstvu zvlášť, takže různé vrstvy mohou nakonec používat různé strategie. Slicování je mírně pomalejší.\n"
"Hadovitě: klikaté procházení řádek po řádku, doladěné algoritmem 2-opt. Vhodné pro pravidelné mřížky mnoha malých dílů.\n"
"\n"
"Pokud je v téže vrstvě více filamentů nebo nástrojů, má přednost minimalizace výměn nástroje: objekty se nejprve seskupí podle filamentu a toto nastavení pak řadí pouze instance uvnitř každé skupiny, takže celková posloupnost nemusí vypadat jako nejkratší dráha po desce."
msgid "As object list"
msgstr "Jako seznam objektů"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Nejlepší ze všech (nejkratší dráha)"
# AI Translated
msgid "Snake"
msgstr "Hadovitě"
msgid "Slow printing down for better layer cooling"
msgstr "Zpomalit tisk pro lepší chlazení vrstvy"
@@ -18850,6 +18894,20 @@ msgstr ""
"Ke jménu hostitele %1% je přiřazeno několik IP adres.\n"
"Vyberte prosím jednu, která má být použita."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Automatické měřítko podle trysky"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Tento model je navržen pro trysku 0,4 mm a výšku vrstvy 0,2 mm. \n"
"Je-li volba změny měřítka zapnuta (doporučeno), model se dynamicky přizpůsobí průměru vaší současné trysky a odpovídající výšce vrstvy, takže je test přesný a dobře čitelný.\n"
"Měřítko vypněte pouze tehdy, chcete-li vytisknout referenční model přesně tak, jak je."
msgid "PA Calibration"
msgstr "PA kalibrace"
@@ -18988,6 +19046,14 @@ msgstr "Počáteční rychlost: "
msgid "End speed: "
msgstr "Konec rychlosti: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Automaticky přizpůsobit maximální objemové rychlosti"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Pokud by koncová rychlost překročila maximální objemovou rychlost filamentu, automaticky snížit výšku vrstvy (se zachováním standardních hodnot a v rámci limitů stroje), aby jí bylo možné dosáhnout. Pokud nestačí ani minimální výška vrstvy, sníží se místo toho koncová rychlost."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18999,6 +19065,57 @@ msgstr ""
"krok >= 0\n"
"konec > start + krok"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Koncová rychlost (%.0f mm/s) překračuje maximální objemovou rychlost filamentu (%.1f mm³/s), která při této šířce čáry a výšce vrstvy omezuje vnější stěnu na přibližně %.0f mm/s.\n"
" Vyšší rychlosti budou oříznuty, takže horní bloky věže se nevytisknou požadovanou rychlostí.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Koncová rychlost (%.0f mm/s) překračuje maximální objemovou rychlost filamentu (%.1f mm³/s) při výchozí výšce vrstvy (%.2f mm).\n"
"\n"
"Výška vrstvy byla snížena na %.2f mm (hodnota používaná profily této tiskárny), aby věž mohla dosáhnout požadované rychlosti."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"I při nejmenší výšce vrstvy používané profily této tiskárny (%.2f mm) koncová rychlost (%.0f mm/s) překračuje maximální objemovou rychlost filamentu (%.1f mm³/s).\n"
"\n"
"Výška vrstvy bude nastavena na %.2f mm a koncová rychlost snížena na %.0f mm/s.\n"
"\n"
"Pokračovat?"
# AI Translated
msgid "Continue anyway?"
msgstr "Přesto pokračovat?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Zapnout „Automaticky přizpůsobit“ pro automatickou nápravu, nebo přesto pokračovat?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Zapnout „Automatické měřítko podle trysky“ a „Automaticky přizpůsobit“ pro automatickou nápravu, nebo přesto pokračovat?"
msgid "Start retraction length: "
msgstr "Počáteční délka retrakce: "
@@ -21756,6 +21873,9 @@ msgstr ""
"Zamezte kroucení\n"
"Víte, že při tisku materiálů náchylných ke kroucení, jako je ABS, může vhodné zvýšení teploty vyhřívané desky snížit pravděpodobnost kroucení?"
#~ msgid "Print order within a single layer."
#~ msgstr "Pořadí tisku v rámci jedné vrstvy."
#~ msgid "Bottom"
#~ msgstr "Dole"
@@ -21824,9 +21944,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Align infill direction to model"
#~ msgstr "Zarovnat směr výplně podle modelu"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Heiko Liebscher <hliebschergmail.com>\n"
"Language-Team: \n"
@@ -3804,6 +3804,10 @@ msgstr "Anordnen..."
msgid "Arranging"
msgstr "Anordnen"
# AI Translated
msgid "Arranging "
msgstr "Anordnen "
msgid "Arranging canceled."
msgstr "Anordnen abgebrochen."
@@ -9152,6 +9156,21 @@ msgstr "Untere Schichten abdunkeln"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Beim Bewegen des Schichtreglers in der geslicten Vorschau werden die Schichten unterhalb der aktuellen abgedunkelt dargestellt, sodass nur die betrachtete Schicht in voller Helligkeit angezeigt wird."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Helligkeit abgedunkelter Schichten"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Wie hell die abgedunkelten Schichten dargestellt werden, wenn \"Untere Schichten abdunkeln\" aktiviert ist.\n"
"99% ist kaum abgedunkelt, 0% stellt sie schwarz dar. Auf 99% begrenzt, da 100% dem Deaktivieren der Option entsprechen würde."
msgid "Login region"
msgstr "Anmeldungsregion"
@@ -13180,12 +13199,37 @@ msgstr "Nach Objekt"
msgid "Intra-layer order"
msgstr "Intra-Schicht-Reihenfolge"
msgid "Print order within a single layer."
msgstr "Druckreihenfolge innerhalb einer einzelnen Schicht"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Reihenfolge, in der die Objektinstanzen innerhalb einer einzelnen Schicht angefahren werden. Sie bestimmt, wie viel Eilgang für die Bewegung zwischen ihnen aufgewendet wird.\n"
"\n"
"Standard: Verkettung nach dem nächsten Nachbarn, verfeinert mit 2-opt und Entfernen von Überkreuzungen. Eine gute allgemeine Wahl.\n"
"Als Objektliste: Die Instanzen werden in derselben Reihenfolge wie in der Objektliste gedruckt, ohne jede Pfadoptimierung. Verwenden Sie diese Option, wenn Sie eine vorhersehbare, manuell gesteuerte Reihenfolge benötigen.\n"
"Bestes Ergebnis (kürzester Weg): Alle Strategien werden ausgewertet und die kürzeste wird verwendet. Die Reihenfolge der Objektinstanzen wird einmal für den gesamten Druck festgelegt, während die Reihenfolge der einzelnen Inseln pro Schicht bestimmt wird, sodass verschiedene Schichten unterschiedliche Strategien verwenden können. Etwas langsameres Slicing.\n"
"Schlangenlinie: Zeilenweiser Mäanderverlauf, verfeinert mit 2-opt. Gut geeignet für regelmäßige Raster aus vielen kleinen Teilen.\n"
"\n"
"Bei mehreren Filamenten oder Werkzeugen in derselben Schicht hat das Minimieren der Werkzeugwechsel Vorrang: Objekte werden zuerst nach Filament gruppiert und diese Einstellung ordnet nur die Instanzen innerhalb jeder Filamentgruppe. Die Gesamtabfolge sieht daher möglicherweise nicht wie der kürzeste Weg über die Platte aus."
msgid "As object list"
msgstr "Als Objektliste"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Bestes Ergebnis (kürzester Weg)"
# AI Translated
msgid "Snake"
msgstr "Schlangenlinie"
msgid "Slow printing down for better layer cooling"
msgstr "Verlangsamen Sie den Druck für eine bessere Schichtkühlung"
@@ -18487,6 +18531,20 @@ msgstr ""
"Es gibt mehrere IP-Adressen, die zu Hostname %1% auflösen.\n"
"Bitte wählen Sie eine aus, die verwendet werden soll."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Automatisch an Düse skalieren"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Dieses Modell ist für eine 0,4 mm Düse mit einer Schichthöhe von 0,2 mm ausgelegt. \n"
"Wenn die Skalierungsoption aktiviert ist (empfohlen), wird das Modell dynamisch an Ihren aktuellen Düsendurchmesser und eine passende Schichthöhe angepasst, sodass der Test sowohl genau als auch gut ablesbar ist.\n"
"Deaktivieren Sie die Skalierung nur, wenn Sie das Referenzmodell exakt so drucken möchten, wie es ist."
msgid "PA Calibration"
msgstr "PA Kalibrierung"
@@ -18623,6 +18681,14 @@ msgstr "Startgeschwindigkeit"
msgid "End speed: "
msgstr "Endgeschwindigkeit"
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Automatisch an maximale Volumengeschwindigkeit anpassen"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Wenn die Endgeschwindigkeit die maximale Volumengeschwindigkeit des Filaments überschreiten würde, wird die Schichthöhe automatisch verringert (unter Beibehaltung üblicher Werte und innerhalb der Grenzen der Maschine), um sie zu erreichen. Reicht selbst die minimale Schichthöhe nicht aus, wird stattdessen die Endgeschwindigkeit gesenkt."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18634,6 +18700,57 @@ msgstr ""
"Schritt >= 0\n"
"Ende > Start + Schritt"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Die Endgeschwindigkeit (%.0f mm/s) überschreitet die maximale Volumengeschwindigkeit des Filaments (%.1f mm³/s), wodurch die Außenwand bei dieser Linienbreite und Schichthöhe auf etwa %.0f mm/s begrenzt wird.\n"
" Höhere Geschwindigkeiten werden begrenzt, sodass die oberen Blöcke des Turms nicht mit der gewünschten Geschwindigkeit gedruckt werden.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Die Endgeschwindigkeit (%.0f mm/s) überschreitet die maximale Volumengeschwindigkeit des Filaments (%.1f mm³/s) bei der Standard-Schichthöhe (%.2f mm).\n"
"\n"
"Die Schichthöhe wurde auf %.2f mm verringert (ein Wert, der in den Profilen dieses Druckers verwendet wird), damit der Turm die gewünschte Geschwindigkeit erreichen kann."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Selbst bei der kleinsten Schichthöhe, die in den Profilen dieses Druckers verwendet wird (%.2f mm), überschreitet die Endgeschwindigkeit (%.0f mm/s) die maximale Volumengeschwindigkeit des Filaments (%.1f mm³/s).\n"
"\n"
"Die Schichthöhe wird auf %.2f mm gesetzt und die Endgeschwindigkeit auf %.0f mm/s verringert.\n"
"\n"
"Fortfahren?"
# AI Translated
msgid "Continue anyway?"
msgstr "Trotzdem fortfahren?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "\"Automatisch anpassen\" aktivieren, um dies automatisch zu beheben, oder trotzdem fortfahren?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "\"Automatisch an Düse skalieren\" und \"Automatisch anpassen\" aktivieren, um dies automatisch zu beheben, oder trotzdem fortfahren?"
msgid "Start retraction length: "
msgstr "Start Rückzugslänge"
@@ -21169,6 +21286,9 @@ msgstr ""
"Verwerfungen vermeiden\n"
"Wussten Sie, dass beim Drucken von Materialien, die zu Verwerfungen neigen, wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die Wahrscheinlichkeit von Verwerfungen verringert werden kann?"
#~ msgid "Print order within a single layer."
#~ msgstr "Druckreihenfolge innerhalb einer einzelnen Schicht"
#~ msgid "Bottom"
#~ msgstr "Unten"
@@ -21261,9 +21381,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "Zeigt geworfene Schatten auf der Platte in der realistischen Ansicht an."

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-06-17 15:44-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: \n"
@@ -3604,6 +3604,9 @@ msgstr ""
msgid "Arranging"
msgstr ""
msgid "Arranging "
msgstr ""
msgid "Arranging canceled."
msgstr ""
@@ -8657,6 +8660,17 @@ msgstr ""
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr ""
msgid "Dimmed layer brightness"
msgstr ""
msgid "%"
msgstr ""
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
msgid "Login region"
msgstr ""
@@ -12353,12 +12367,26 @@ msgstr ""
msgid "Intra-layer order"
msgstr ""
msgid "Print order within a single layer."
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
msgid "As object list"
msgstr ""
msgid "Best of all (shortest path)"
msgstr ""
msgid "Snake"
msgstr ""
msgid "Slow printing down for better layer cooling"
msgstr ""
@@ -17214,6 +17242,15 @@ msgid ""
"Please select one that should be used."
msgstr ""
msgid "Auto-scale for nozzle"
msgstr ""
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
msgid "PA Calibration"
msgstr ""
@@ -17336,6 +17373,12 @@ msgstr ""
msgid "End speed: "
msgstr ""
msgid "Auto-adjust to max volumetric speed"
msgstr ""
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr ""
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -17343,6 +17386,39 @@ msgid ""
"end > start + step"
msgstr ""
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
msgid "Continue anyway?"
msgstr ""
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr ""
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr ""
msgid "Start retraction length: "
msgstr ""

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Ian A. Bassi <>\n"
"Language-Team: \n"
@@ -3686,6 +3686,10 @@ msgstr "Organizando..."
msgid "Arranging"
msgstr "Organizando"
# AI Translated
msgid "Arranging "
msgstr "Organizando "
msgid "Arranging canceled."
msgstr "Organización cancelada."
@@ -8931,6 +8935,21 @@ msgstr "Atenuar las capas inferiores"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Al desplazar el control deslizante de capas en la vista previa laminada, oscurece las capas inferiores a la actual para que solo la capa visualizada se muestre a pleno brillo."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Brillo de las capas atenuadas"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Con qué brillo se muestran las capas atenuadas cuando \"Atenuar las capas inferiores\" está activado.\n"
"99% apenas se oscurece y 0% las muestra en negro. Está limitado al 99% porque el 100% equivaldría a desactivar la opción."
msgid "Login region"
msgstr "Región de inicio de sesión"
@@ -12881,12 +12900,37 @@ msgstr "Por objeto"
msgid "Intra-layer order"
msgstr "Orden dentro de la capa"
msgid "Print order within a single layer."
msgstr "Orden de impresión dentro de cada capa."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Orden en el que se recorren las instancias de objeto dentro de una misma capa, lo que determina cuánto desplazamiento se emplea para moverse entre ellas.\n"
"\n"
"Por defecto: encadenado por vecino más cercano, refinado con 2-opt y eliminación de cruces. Una buena opción general.\n"
"Como lista de objetos: las instancias se imprimen en el mismo orden que la lista de objetos, sin ninguna optimización de trayectoria. Úselo cuando necesite un orden predecible y controlado manualmente.\n"
"La mejor de todas (trayectoria más corta): se evalúan todas las estrategias y se utiliza la más corta. El orden de las instancias de objeto se decide una sola vez para toda la impresión, mientras que el orden de las islas individuales se decide capa por capa, por lo que distintas capas pueden acabar usando estrategias diferentes. El laminado es algo más lento.\n"
"Serpentina: recorrido serpenteante fila por fila, refinado con 2-opt. Muy adecuado para rejillas regulares de muchas piezas pequeñas.\n"
"\n"
"Con varios filamentos o herramientas en la misma capa, minimizar los cambios de herramienta tiene prioridad: los objetos se agrupan primero por filamento y este ajuste solo ordena las instancias dentro de cada grupo de filamento, por lo que la secuencia global puede no parecer la trayectoria más corta a lo largo de la cama."
msgid "As object list"
msgstr "Como lista de objetos"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "La mejor de todas (trayectoria más corta)"
# AI Translated
msgid "Snake"
msgstr "Serpentina"
msgid "Slow printing down for better layer cooling"
msgstr "Reducir la velocidad de impresión para mejorar la refrigeración de las capas"
@@ -18122,6 +18166,20 @@ msgstr ""
"Hay varias direcciones IP resueltas del nombre del host %1%.\n"
"Por favor, seleccione la que debe usarse."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Escalar automáticamente para la boquilla"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Este modelo está diseñado para una boquilla de 0,4 mm con una altura de la capa de 0,2 mm. \n"
"Cuando la opción de escalado está activada (recomendado), el modelo se redimensiona dinámicamente para adaptarse al diámetro de boquilla actual y a una altura de capa adecuada, lo que hace que la prueba sea precisa y fácil de leer.\n"
"Desactive el escalado solo si desea imprimir el modelo de referencia exactamente tal cual."
msgid "PA Calibration"
msgstr "Calibración PA"
@@ -18258,6 +18316,14 @@ msgstr "Velocidad inicial: "
msgid "End speed: "
msgstr "Velocidad final: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Ajustar automáticamente a la velocidad volumétrica máxima"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Si la velocidad final superara la velocidad volumétrica máxima del filamento, se reduce automáticamente la altura de la capa (manteniendo valores estándar y dentro de los límites de la máquina) para alcanzarla. Si ni siquiera la altura de capa mínima es suficiente, se reduce la velocidad final."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18269,6 +18335,57 @@ msgstr ""
"incremento >=0\n"
"final > inicio + paso"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"La velocidad final (%.0f mm/s) supera la velocidad volumétrica máxima del filamento (%.1f mm³/s), lo que limita el perímetro externo a unos %.0f mm/s con este ancho de línea y esta altura de capa.\n"
" Las velocidades superiores se recortarán, por lo que los bloques superiores de la torre no se imprimirán a la velocidad solicitada.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"La velocidad final (%.0f mm/s) supera la velocidad volumétrica máxima del filamento (%.1f mm³/s) con la altura de capa predeterminada (%.2f mm).\n"
"\n"
"La altura de la capa se ha reducido a %.2f mm (un valor usado por los perfiles de esta impresora) para que la torre pueda alcanzar la velocidad solicitada."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Incluso con la altura de capa más pequeña usada por los perfiles de esta impresora (%.2f mm), la velocidad final (%.0f mm/s) supera la velocidad volumétrica máxima del filamento (%.1f mm³/s).\n"
"\n"
"La altura de la capa se establecerá en %.2f mm y la velocidad final se reducirá a %.0f mm/s.\n"
"\n"
"¿Continuar?"
# AI Translated
msgid "Continue anyway?"
msgstr "¿Continuar de todos modos?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "¿Activar \"Ajuste automático\" para corregir esto automáticamente o continuar de todos modos?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "¿Activar \"Escalar automáticamente para la boquilla\" y \"Ajuste automático\" para corregir esto automáticamente o continuar de todos modos?"
msgid "Start retraction length: "
msgstr "Longitud de retracción inicial: "
@@ -20744,6 +20861,9 @@ msgstr ""
"Evita la deformación\n"
"¿Sabías que al imprimir materiales propensos a la deformación como el ABS, aumentar adecuadamente la temperatura de la cama térmica puede reducir la probabilidad de deformaciones?"
#~ msgid "Print order within a single layer."
#~ msgstr "Orden de impresión dentro de cada capa."
#~ msgid "Bottom"
#~ msgstr "Inferior"
@@ -20837,9 +20957,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Anisotropic surfaces"
#~ msgstr "Superficies anisótropas"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-07-20 13:33+0200\n"
"Last-Translator: Manu Goiogana <mgoiogana@gmail.com>\n"
"Language-Team: \n"
@@ -3724,6 +3724,10 @@ msgstr "Antolatzen..."
msgid "Arranging"
msgstr "Antolaketa"
# AI Translated
msgid "Arranging "
msgstr "Antolatzen "
msgid "Arranging canceled."
msgstr "Antolaketa bertan behera utzi da."
@@ -8999,6 +9003,21 @@ msgstr "Ilundu beheko geruzak"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Xerratutako aurrebistan geruza-graduatzailea mugitzean, unekoaren azpiko geruzak ilunduta erakusten ditu, ikusten ari den geruza soilik distira osoz ager dadin."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Ilundutako geruzen distira"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"\"Ilundu beheko geruzak\" gaituta dagoenean ilundutako geruzak zein distiratsu marrazten diren.\n"
"%99 balioak ozta-ozta iluntzen ditu, %0 balioak beltz bihurtzen ditu. Gehienez %99 onartzen da, %100 balioak aukera desgaitzearen gauza bera egingo bailuke."
msgid "Login region"
msgstr "Saio-hasierako eskualdea"
@@ -12992,12 +13011,37 @@ msgstr "Objektuka"
msgid "Intra-layer order"
msgstr "Geruza barruko ordena"
msgid "Print order within a single layer."
msgstr "Geruza bakarreko inprimatze-ordena."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Geruza bakar baten barruan objektu-instantziak zein ordenatan bisitatzen diren; horrek zehazten du zenbat desplazamendu behar den haien artean mugitzeko.\n"
"\n"
"Lehenetsia: auzokide hurbilenaren araberako kateaketa, 2-opt bidez eta gurutzaketak kenduz findua. Aukera orokor ona.\n"
"Objektu-zerrenda bezala: instantziak objektu-zerrendaren ordena berean inprimatzen dira, ibilbidea batere optimizatu gabe. Erabili ordena aurreikusgarri eta eskuz kontrolatu bat behar duzunean.\n"
"Guztien onena (ibilbide laburrena): estrategia guztiak ebaluatzen dira eta laburrena erabiltzen da. Objektu-instantzien ordena behin erabakitzen da inprimaketa osorako, eta uharte bakoitzaren ordena geruzaz geruza erabakitzen da; beraz, geruza desberdinek estrategia desberdinak erabil ditzakete. Xerratzea apur bat motelagoa da.\n"
"Sigi-saga: errenkadaz errenkadako sigi-saga ibilbidea, 2-opt bidez findua. Oso egokia pieza txiki askoren sareta erregularretarako.\n"
"\n"
"Geruza berean filamentu edo tresna bat baino gehiago daudenean, tresna-aldaketak gutxitzeak du lehentasuna: objektuak filamentuaren arabera multzokatzen dira lehenik, eta ezarpen honek filamentu-multzo bakoitzaren barruko instantziak baino ez ditu ordenatzen; beraz, baliteke sekuentzia orokorrak plaka osoko ibilbide laburrenaren itxurarik ez izatea."
msgid "As object list"
msgstr "Objektu-zerrenda bezala"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Guztien onena (ibilbide laburrena)"
# AI Translated
msgid "Snake"
msgstr "Sigi-saga"
msgid "Slow printing down for better layer cooling"
msgstr "Moteldu inprimaketa geruza hobeto hozteko"
@@ -18269,6 +18313,20 @@ msgstr ""
"Hainbat IP helbide ebazten dira %1% ostalari-izenerako.\n"
"Hautatu erabili beharrekoa."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Eskalatze automatikoa pitarako"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Modelo hau 0,4 mm-ko pita eta 0,2 mm-ko geruza-altuera kontuan hartuta diseinatu da. \n"
"Eskalatze-aukera gaituta dagoenean (gomendatua), tamaina dinamikoki egokitzen zaie zure uneko pita-diametroari eta geruza-altuera egoki bati, testa zehatza eta irakurterraza izan dadin.\n"
"Itzali eskalatzea erreferentzia-modeloa dagoen-dagoenean inprimatu nahi baduzu bakarrik."
msgid "PA Calibration"
msgstr "PA kalibrazioa"
@@ -18406,6 +18464,14 @@ msgstr "Hasierako abiadura: "
msgid "End speed: "
msgstr "Amaierako abiadura: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Doikuntza automatikoa abiadura bolumetriko maximora"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Amaierako abiadurak filamentuaren abiadura bolumetriko maximoa gaindituko balu, geruza-altuera automatikoki jaisten da (balio estandarrak mantenduz eta makinaren mugen barruan) hura lortzeko. Gutxieneko geruza-altuerarekin ere nahikoa ez bada, amaierako abiadura jaisten da haren ordez."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18417,6 +18483,57 @@ msgstr ""
"urratsa >= 0\n"
"amaiera > hasiera + urratsa"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Amaierako abiadurak (%.0f mm/s) filamentuaren abiadura bolumetriko maximoa (%.1f mm³/s) gainditzen du, eta horrek kanpoko horma gutxi gorabehera %.0f mm/s-ra mugatzen du lerro-zabalera eta geruza-altuera honekin.\n"
" Horren gaineko abiadurak mugatu egingo dira, beraz dorrearen goiko blokeak ez dira eskatutako abiaduran inprimatuko.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Amaierako abiadurak (%.0f mm/s) filamentuaren abiadura bolumetriko maximoa (%.1f mm³/s) gainditzen du geruza-altuera lehenetsian (%.2f mm).\n"
"\n"
"Geruza-altuera %.2f mm-ra jaitsi da (inprimagailu honen aurrezarpenek erabiltzen duten balio bat), dorreak eskatutako abiadura lor dezan."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Inprimagailu honen aurrezarpenek erabiltzen duten geruza-altuera txikienarekin ere (%.2f mm), amaierako abiadurak (%.0f mm/s) filamentuaren abiadura bolumetriko maximoa (%.1f mm³/s) gainditzen du.\n"
"\n"
"Geruza-altuera %.2f mm-ra ezarriko da eta amaierako abiadura %.0f mm/s-ra jaitsiko da.\n"
"\n"
"Jarraitu?"
# AI Translated
msgid "Continue anyway?"
msgstr "Hala ere jarraitu?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Gaitu \"Doikuntza automatikoa\" hau automatikoki konpontzeko, edo hala ere jarraitu?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Gaitu \"Eskalatze automatikoa pitarako\" eta \"Doikuntza automatikoa\" hau automatikoki konpontzeko, edo hala ere jarraitu?"
msgid "Start retraction length: "
msgstr "Hasierako atzera-egite luzera: "
@@ -20899,6 +21016,9 @@ msgstr ""
"Saihestu okertzea\n"
"Ba al zenekien ABS bezalako okertzeko joera duten materialak inprimatzean ohe beroaren tenperatura egoki igotzeak okertzeko probabilitatea murriztu dezakeela?"
#~ msgid "Print order within a single layer."
#~ msgstr "Geruza bakarreko inprimatze-ordena."
#~ msgid "Bottom"
#~ msgstr "Behekoa"
@@ -21028,9 +21148,6 @@ msgstr ""
#~ msgid "°"
#~ msgstr "°"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "uniform scale"
#~ msgstr "eskala uniformea"

View File

@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: Guislain Cyril, Thomas Lété\n"
@@ -3760,6 +3760,10 @@ msgstr "Agencement…"
msgid "Arranging"
msgstr "Agencement"
# AI Translated
msgid "Arranging "
msgstr "Agencement "
msgid "Arranging canceled."
msgstr "Agencement annulé."
@@ -9068,6 +9072,21 @@ msgstr "Assombrir les couches inférieures"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Lors du défilement du curseur de couche dans l'aperçu découpé, affiche les couches situées sous la couche actuelle assombries, de sorte que seule la couche visualisée soit affichée en pleine luminosité."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Luminosité des couches assombries"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Luminosité de rendu des couches assombries lorsque « Assombrir les couches inférieures » est activé.\n"
"99% correspond à un assombrissement à peine perceptible, 0% les affiche en noir. Limité à 99% car 100% reviendrait à désactiver loption."
msgid "Login region"
msgstr "Région d'origine"
@@ -13087,12 +13106,37 @@ msgstr "Par objet"
msgid "Intra-layer order"
msgstr "Ordre intra-couche"
msgid "Print order within a single layer."
msgstr "Ordre dimpression au sein dune même couche"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Ordre dans lequel les instances dobjets sont parcourues au sein dune même couche, ce qui détermine la quantité de déplacements effectués entre elles.\n"
"\n"
"Par défaut : chaînage par plus proche voisin, affiné par 2-opt et suppression des croisements. Un bon choix général.\n"
"En tant que liste dobjets : les instances sont imprimées dans le même ordre que la liste dobjets, sans aucune optimisation de trajet. À utiliser lorsque vous avez besoin dun ordre prévisible et contrôlé manuellement.\n"
"Meilleur de tous (trajet le plus court) : toutes les stratégies sont évaluées et la plus courte est retenue. Lordre des instances dobjets est déterminé une seule fois pour toute limpression, tandis que lordre des îlots individuels est déterminé couche par couche ; différentes couches peuvent donc utiliser des stratégies différentes. Découpage légèrement plus lent.\n"
"Serpentin : parcours en serpentin, rangée par rangée, affiné par 2-opt. Bien adapté aux grilles régulières de nombreuses petites pièces.\n"
"\n"
"Avec plusieurs filaments ou outils dans la même couche, la réduction des changements doutil est prioritaire : les objets sont dabord regroupés par filament et ce réglage nordonne que les instances au sein de chaque groupe de filament ; la séquence globale peut donc ne pas ressembler au trajet le plus court sur la plaque."
msgid "As object list"
msgstr "En tant que liste dobjets"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Meilleur de tous (trajet le plus court)"
# AI Translated
msgid "Snake"
msgstr "Serpentin"
msgid "Slow printing down for better layer cooling"
msgstr "Impression lente pour un meilleur refroidissement des couches"
@@ -18381,6 +18425,20 @@ msgstr ""
"Il existe plusieurs adresses IP résolues par le nom dhôte %1%.\n"
"Veuillez en sélectionner une qui doit être utilisée."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Mise à léchelle automatique selon la buse"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Ce modèle est conçu pour une buse de 0,4 mm avec une hauteur de couche de 0,2 mm. \n"
"Lorsque loption de mise à léchelle est activée (recommandé), il est redimensionné dynamiquement pour correspondre au diamètre de buse actuel et à une hauteur de couche appropriée, ce qui rend le test à la fois précis et facile à lire.\n"
"Ne désactivez la mise à léchelle que si vous souhaitez imprimer le modèle de référence exactement tel quel."
msgid "PA Calibration"
msgstr "Calibration Pressure Advance"
@@ -18517,6 +18575,14 @@ msgstr "Vitesse de début: "
msgid "End speed: "
msgstr "Vitesse de fin: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Ajustement automatique à la vitesse volumétrique maximale"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Si la vitesse finale devait dépasser la vitesse volumétrique maximale du filament, la hauteur de couche est automatiquement réduite (en conservant des valeurs standard et en restant dans les limites de la machine) pour latteindre. Si même la hauteur de couche minimale ne suffit pas, cest la vitesse finale qui est réduite."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18528,6 +18594,57 @@ msgstr ""
"intervalles >= 0\n"
"Fin > Début + Intervalle"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"La vitesse finale (%.0f mm/s) dépasse la vitesse volumétrique maximale du filament (%.1f mm³/s), ce qui limite la paroi extérieure à environ %.0f mm/s pour cette largeur de ligne et cette hauteur de couche.\n"
" Les vitesses supérieures seront bridées : les blocs supérieurs de la tour ne seront donc pas imprimés à la vitesse demandée.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"La vitesse finale (%.0f mm/s) dépasse la vitesse volumétrique maximale du filament (%.1f mm³/s) avec la hauteur de couche par défaut (%.2f mm).\n"
"\n"
"La hauteur de couche a été réduite à %.2f mm (une valeur utilisée par les profils de cette imprimante) afin que la tour puisse atteindre la vitesse demandée."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Même avec la plus petite hauteur de couche utilisée par les profils de cette imprimante (%.2f mm), la vitesse finale (%.0f mm/s) dépasse la vitesse volumétrique maximale du filament (%.1f mm³/s).\n"
"\n"
"La hauteur de couche sera réglée sur %.2f mm et la vitesse finale abaissée à %.0f mm/s.\n"
"\n"
"Continuer ?"
# AI Translated
msgid "Continue anyway?"
msgstr "Continuer quand même ?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Activer « Ajustement automatique » pour corriger cela automatiquement, ou continuer quand même ?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Activer « Mise à léchelle automatique selon la buse » et « Ajustement automatique » pour corriger cela automatiquement, ou continuer quand même ?"
msgid "Start retraction length: "
msgstr "Longueur de rétraction de début: "
@@ -21059,6 +21176,9 @@ msgstr ""
"Éviter la déformation\n"
"Saviez-vous que lors de limpression de matériaux susceptibles de se déformer, tels que lABS, une augmentation appropriée de la température du plateau chauffant peut réduire la probabilité de déformation?"
#~ msgid "Print order within a single layer."
#~ msgstr "Ordre dimpression au sein dune même couche"
#~ msgid "Bottom"
#~ msgstr "Dessous"
@@ -21149,9 +21269,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "Affiche les ombres portées sur la plaque dans la vue réaliste."

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -3850,6 +3850,10 @@ msgstr "Disposizione..."
msgid "Arranging"
msgstr "Disposizione"
# AI Translated
msgid "Arranging "
msgstr "Disposizione "
msgid "Arranging canceled."
msgstr "Disposizione annullata."
@@ -9229,6 +9233,21 @@ msgstr "Attenua gli strati inferiori"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Quando si scorre il cursore degli strati nell'anteprima elaborata, gli strati al di sotto di quello corrente vengono visualizzati scuriti, in modo che solo lo strato in visualizzazione sia mostrato alla massima luminosità."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Luminosità degli strati attenuati"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Quanto luminosi appaiono gli strati attenuati quando \"Attenua gli strati inferiori\" è attivo.\n"
"99% è appena scurito, 0% li rende neri. Limitato al 99% perché 100% equivarrebbe a disattivare l'opzione."
msgid "Login region"
msgstr "Regione di accesso"
@@ -13326,12 +13345,37 @@ msgstr "Per oggetto"
msgid "Intra-layer order"
msgstr "Ordine intra-strato"
msgid "Print order within a single layer."
msgstr "Ordine di stampa all'interno di un singolo strato."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Ordine in cui le istanze degli oggetti vengono percorse all'interno di un singolo strato; determina quanti spostamenti servono per passare dall'una all'altra.\n"
"\n"
"Predefinito: concatenamento con il vicino più prossimo, affinato con 2-opt e rimozione degli incroci. Una buona scelta generale.\n"
"Come elenco di oggetti: le istanze vengono stampate nello stesso ordine dell'elenco degli oggetti, senza alcuna ottimizzazione del percorso. Da usare quando serve un ordine prevedibile e controllato manualmente.\n"
"Il migliore di tutti (percorso più breve): tutte le strategie vengono valutate e viene usata la più breve. L'ordine delle istanze degli oggetti viene deciso una sola volta per l'intera stampa, mentre l'ordine delle singole isole viene deciso strato per strato, quindi strati diversi possono usare strategie diverse. Slicing leggermente più lento.\n"
"Serpentina: percorso a serpentina, riga per riga, affinato con 2-opt. Adatto a griglie regolari di molti pezzi piccoli.\n"
"\n"
"Con più filamenti o strumenti nello stesso strato, ridurre i cambi strumento ha la priorità: gli oggetti vengono prima raggruppati per filamento e questa impostazione ordina solo le istanze all'interno di ciascun gruppo di filamento, quindi la sequenza complessiva potrebbe non sembrare il percorso più breve sul piatto."
msgid "As object list"
msgstr "Come elenco di oggetti"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Il migliore di tutti (percorso più breve)"
# AI Translated
msgid "Snake"
msgstr "Serpentina"
msgid "Slow printing down for better layer cooling"
msgstr "Rallenta stampa per miglior raffreddamento degli strati"
@@ -18679,6 +18723,20 @@ msgstr ""
"Esistono diversi indirizzi IP che risolvono il nome host %1%.\n"
"Selezionare quello da utilizzare."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Scala automaticamente in base all'ugello"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Questo modello è progettato per un ugello da 0,4 mm con un'altezza strato di 0,2 mm. \n"
"Quando l'opzione di ridimensionamento è attiva (consigliata), il modello viene ridimensionato dinamicamente in base al diametro dell'ugello attuale e a un'altezza strato adeguata, rendendo il test preciso e facile da leggere.\n"
"Disattiva il ridimensionamento solo se desideri stampare il modello di riferimento esattamente com'è."
msgid "PA Calibration"
msgstr "Calibrazione AP"
@@ -18815,6 +18873,14 @@ msgstr "Velocità iniziale: "
msgid "End speed: "
msgstr "Velocità finale: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Adatta automaticamente alla velocità volumetrica massima"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Se la velocità finale superasse la velocità volumetrica massima del filamento, l'altezza strato viene ridotta automaticamente (mantenendo valori standard e restando entro i limiti della macchina) per raggiungerla. Se anche l'altezza strato minima non è sufficiente, viene ridotta invece la velocità finale."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18826,6 +18892,57 @@ msgstr ""
"incremento >= 0\n"
"fine > inizio + incremento"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"La velocità finale (%.0f mm/s) supera la velocità volumetrica massima del filamento (%.1f mm³/s), il che limita la parete esterna a circa %.0f mm/s con questa larghezza linea e questa altezza strato.\n"
" Le velocità superiori verranno limitate, quindi i blocchi superiori della torre non verranno stampati alla velocità richiesta.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"La velocità finale (%.0f mm/s) supera la velocità volumetrica massima del filamento (%.1f mm³/s) con l'altezza strato predefinita (%.2f mm).\n"
"\n"
"L'altezza strato è stata ridotta a %.2f mm (un valore usato dai profili di questa stampante) affinché la torre possa raggiungere la velocità richiesta."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Anche con l'altezza strato più piccola usata dai profili di questa stampante (%.2f mm), la velocità finale (%.0f mm/s) supera la velocità volumetrica massima del filamento (%.1f mm³/s).\n"
"\n"
"L'altezza strato verrà impostata su %.2f mm e la velocità finale ridotta a %.0f mm/s.\n"
"\n"
"Continuare?"
# AI Translated
msgid "Continue anyway?"
msgstr "Continuare comunque?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Attivare \"Adatta automaticamente\" per correggere automaticamente il problema oppure continuare comunque?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Attivare \"Scala automaticamente in base all'ugello\" e \"Adatta automaticamente\" per correggere automaticamente il problema oppure continuare comunque?"
msgid "Start retraction length: "
msgstr "Lunghezza di retrazione iniziale: "
@@ -21514,6 +21631,9 @@ msgstr ""
"Evita le deformazioni\n"
"Sapevi che quando si stampano materiali soggetti a deformazioni come l'ABS, aumentare in modo appropriato la temperatura del piano riscaldato può ridurre la probabilità di deformazione?"
#~ msgid "Print order within a single layer."
#~ msgstr "Ordine di stampa all'interno di un singolo strato."
#~ msgid "Bottom"
#~ msgstr "Inferiore"
@@ -21600,9 +21720,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Continue to sync filaments"
#~ msgstr "Continua la sincronizzazione dei filamenti"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -3860,6 +3860,10 @@ msgstr "レイアウト中"
msgid "Arranging"
msgstr "レイアウト中"
# AI Translated
msgid "Arranging "
msgstr "レイアウト中 "
msgid "Arranging canceled."
msgstr "レイアウトを取り消しました"
@@ -9249,6 +9253,21 @@ msgstr "下の積層を暗くする"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "スライスプレビューで積層スライダーを操作する際、現在の層より下の積層を暗く描画し、表示中の積層のみを明るく表示します。"
# AI Translated
msgid "Dimmed layer brightness"
msgstr "暗くした積層の明るさ"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"「下の積層を暗くする」を有効にしたときに、暗くした積層をどの程度の明るさで表示するかを指定します。\n"
"99%ではほとんど暗くならず、0%では真っ黒になります。100%はオプションを無効にした場合と同じになるため、上限は99%です。"
msgid "Login region"
msgstr "地域"
@@ -13416,12 +13435,37 @@ msgstr "オブジェクト順"
msgid "Intra-layer order"
msgstr "レイヤー内の順序"
msgid "Print order within a single layer."
msgstr "単一レイヤー内の印刷順序。"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"1つの積層内でオブジェクトインスタンスを巡回する順序です。インスタンス間の移動距離に影響します。\n"
"\n"
"デフォルト最近傍法でつなぎ、2-optと交差の除去で改善します。一般的な用途に適した選択です。\n"
"オブジェクトリスト順:パスの最適化を行わず、オブジェクトリストと同じ順序でインスタンスを造形します。手動で管理できる予測しやすい順序が必要な場合に使用します。\n"
"すべてを比較最短経路すべての方式を評価し、最も短いものを使用します。オブジェクトインスタンスの順序は造形全体で1回だけ決定され、個々のアイランドの順序は積層ごとに決定されるため、積層によって異なる方式が使われる場合があります。スライスがやや遅くなります。\n"
"蛇行行ごとに折り返しながら蛇行して巡回し、2-optで改善します。小さなパーツが規則的に並んだ配置に適しています。\n"
"\n"
"同じ積層内で複数のフィラメントやツールを使用する場合は、ツール交換の削減が優先されます。オブジェクトはまずフィラメントごとにグループ化され、この設定は各フィラメントグループ内のインスタンスの順序のみを決めるため、全体の順序はプレート全体での最短経路には見えないことがあります。"
msgid "As object list"
msgstr "オブジェクトリスト順"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "すべてを比較(最短経路)"
# AI Translated
msgid "Snake"
msgstr "蛇行"
msgid "Slow printing down for better layer cooling"
msgstr "冷却の為減速"
@@ -19167,6 +19211,20 @@ msgstr ""
"ホスト名%1%には、いくつかのIPアドレスがあります。\n"
"使用するIPアドレスを1つ選んでください。"
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "ノズルに合わせて自動スケール"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"このモデルは、0.4 mmズルと0.2 mmの積層ピッチを基準に設計されています。 \n"
"スケールオプションを有効にすると(推奨)、現在のノズル径と適切な積層ピッチに合わせてサイズが動的に調整され、テストの精度と読み取りやすさが向上します。\n"
"参照モデルをそのままの状態で造形したい場合のみ、スケールを無効にしてください。"
msgid "PA Calibration"
msgstr "PAキャリブレーション"
@@ -19306,6 +19364,14 @@ msgstr "開始速度: "
msgid "End speed: "
msgstr "終了速度: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "最大体積速度に合わせて自動調整"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "終了速度がフィラメントの最大体積速度を超える場合、その速度に到達できるよう積層ピッチを自動的に下げます(標準的な値を使用し、プリンタの制限内に収めます)。最小の積層ピッチでも足りない場合は、代わりに終了速度を下げます。"
# AI Translated
msgid ""
"Please input valid values:\n"
@@ -19318,6 +19384,57 @@ msgstr ""
"ステップ >= 0\n"
"終了 > 開始 + ステップ"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"終了速度(%.0f mm/sがフィラメントの最大体積速度%.1f mm³/sを超えています。この押出線幅と積層ピッチでは、外壁は約 %.0f mm/s に制限されます。\n"
" これを超える速度は制限されるため、タワーの上部ブロックは指定した速度で造形されません。\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"終了速度(%.0f mm/sがフィラメントの最大体積速度%.1f mm³/sを超えていますデフォルトの積層ピッチ %.2f mm の場合)。\n"
"\n"
"タワーが指定した速度に到達できるよう、積層ピッチを %.2f mmこのプリンタのプロファイルで使用されている値に下げました。"
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"このプリンタのプロファイルで使用されている最小の積層ピッチ(%.2f mmでも、終了速度%.0f mm/sがフィラメントの最大体積速度%.1f mm³/sを超えています。\n"
"\n"
"積層ピッチを %.2f mm に設定し、終了速度を %.0f mm/s に下げます。\n"
"\n"
"続行しますか?"
# AI Translated
msgid "Continue anyway?"
msgstr "このまま続行しますか?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "「自動調整」を有効にすると自動的に修正されます。このまま続行しますか?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "「ノズルに合わせて自動スケール」と「自動調整」を有効にすると自動的に修正されます。このまま続行しますか?"
msgid "Start retraction length: "
msgstr "開始リトラクション長さ: "
@@ -22077,6 +22194,9 @@ msgstr ""
"反りを避ける\n"
"ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げることで、反りが発生する確率を下げることができることをご存知ですか"
#~ msgid "Print order within a single layer."
#~ msgstr "単一レイヤー内の印刷順序。"
#~ msgid "Bottom"
#~ msgstr "底面"
@@ -22157,9 +22277,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Continue to sync filaments"
#~ msgstr "フィラメントの同期を続行"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2025-06-02 17:12+0900\n"
"Last-Translator: crwusiz <crwusiz@gmail.com>\n"
"Language-Team: \n"
@@ -3864,6 +3864,10 @@ msgstr "정렬 중..."
msgid "Arranging"
msgstr "정렬 중"
# AI Translated
msgid "Arranging "
msgstr "정렬 중 "
msgid "Arranging canceled."
msgstr "정렬 취소됨."
@@ -9324,6 +9328,21 @@ msgstr "아래 레이어 어둡게 표시"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "슬라이스된 미리보기에서 레이어 슬라이더를 움직일 때 현재 레이어보다 아래에 있는 레이어를 어둡게 렌더링하여, 보고 있는 레이어만 완전한 밝기로 표시합니다."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "어둡게 표시된 레이어의 밝기"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"\"아래 레이어 어둡게 표시\"를 활성화했을 때 어둡게 표시되는 레이어의 밝기입니다.\n"
"99%는 거의 어두워지지 않고, 0%는 완전히 검게 표시됩니다. 100%는 이 옵션을 비활성화한 것과 같으므로 최대 99%로 제한됩니다."
msgid "Login region"
msgstr "로그인 지역"
@@ -13539,12 +13558,37 @@ msgstr "객체별"
msgid "Intra-layer order"
msgstr "레이어 내 순서"
msgid "Print order within a single layer."
msgstr "단일 레이어 내의 출력 순서"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"단일 레이어 내에서 객체 인스턴스를 방문하는 순서로, 인스턴스 사이를 오가는 이동량을 결정합니다.\n"
"\n"
"기본값: 최근접 이웃 방식으로 경로를 연결하고 2-opt와 교차 제거로 개선합니다. 일반적으로 무난한 선택입니다.\n"
"객체 목록으로: 경로 최적화 없이 객체 목록과 동일한 순서로 인스턴스를 출력합니다. 예측 가능하고 수동으로 제어되는 순서가 필요할 때 사용하십시오.\n"
"전체 비교(최단 경로): 모든 전략을 평가하여 가장 짧은 것을 사용합니다. 객체 인스턴스 순서는 출력 전체에 대해 한 번만 결정되고 개별 아일랜드의 순서는 레이어마다 결정되므로, 레이어에 따라 서로 다른 전략이 사용될 수 있습니다. 슬라이싱이 약간 느려집니다.\n"
"사행형: 행 단위로 앞뒤를 오가며 사행하듯 순회하고 2-opt로 개선합니다. 작은 부품이 규칙적인 격자로 배치된 경우에 적합합니다.\n"
"\n"
"같은 레이어에서 여러 필라멘트나 툴을 사용하는 경우에는 툴 교체 최소화가 우선합니다. 객체를 먼저 필라멘트별로 그룹화하며 이 설정은 각 필라멘트 그룹 내의 인스턴스 순서만 결정하므로, 전체 순서가 플레이트 전체의 최단 경로처럼 보이지 않을 수 있습니다."
msgid "As object list"
msgstr "객체 목록으로"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "전체 비교(최단 경로)"
# AI Translated
msgid "Snake"
msgstr "사행형"
msgid "Slow printing down for better layer cooling"
msgstr "레이어 냉각 향상을 위한 감속"
@@ -14248,7 +14292,7 @@ msgstr "플러시 체적 속도"
# AI Translated
msgid "Volumetric speed when flushing filament. 0 indicates the max volumetric speed."
msgstr "필라멘트를 플러시할 때의 체적 속도입니다. 0은 최대 체적 속도를 의미합니다."
msgstr "필라멘트를 플러시할 때의 압출 속도입니다. 0은 최대 압출 속도를 의미합니다."
msgid "This setting is the volume of filament that can be melted and extruded per second. Printing speed is limited by max volumetric speed, in case of too high and unreasonable speed setting. This value cannot be zero."
msgstr "이 설정은 초당 얼마나 많은 양의 필라멘트를 녹이고 압출할 수 있는지를 나타냅니다. 너무 높고 부적절한 속도 설정의 경우 출력 속도는 최대 압출 속도에 의해 제한됩니다. 0이 될 수 없습니다"
@@ -18715,7 +18759,7 @@ msgstr ""
"이제 다양한 필라멘트에 대한 자동 교정 기능이 추가되었습니다. 완전히 자동으로 수행되며 결과는 나중에 사용할 수 있도록 프린터에 저장됩니다. 다음과 같은 제한된 경우에만 교정을 수행하면 됩니다:\n"
"1. 다른 브랜드/모델의 새 필라멘트를 사용하거나 필라멘트가 눅눅해진 경우\n"
"2. 노즐이 마모되었거나 새 노즐로 교체한 경우\n"
"3. 필라멘트 설정에서 최대 체적 속도나 출력 온도를 변경한 경우."
"3. 필라멘트 설정에서 최대 압출 속도나 출력 온도를 변경한 경우."
msgid "About this calibration"
msgstr "교정 정보"
@@ -19033,6 +19077,20 @@ msgstr ""
"호스트 이름 %1%으로 확인되는 IP 주소가 여러 개 있습니다.\n"
"사용 할 IP를 선택해 주세요."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "노즐에 맞춰 자동 크기 조정"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"이 모델은 0.4 mm 노즐과 0.2 mm 레이어 높이를 기준으로 설계되었습니다. \n"
"크기 조정 옵션을 활성화하면(권장) 현재 노즐 직경과 적절한 레이어 높이에 맞춰 크기가 동적으로 조정되어 테스트가 정확하고 읽기 쉬워집니다.\n"
"참조 모델을 있는 그대로 출력하려는 경우에만 크기 조정을 끄십시오."
msgid "PA Calibration"
msgstr "PA 교정"
@@ -19171,6 +19229,14 @@ msgstr "시작 속도: "
msgid "End speed: "
msgstr "종료 속도: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "최대 압출 속도에 맞춰 자동 조정"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "종료 속도가 필라멘트의 최대 압출 속도를 초과하는 경우, 해당 속도에 도달할 수 있도록 레이어 높이를 자동으로 낮춥니다(표준 값을 유지하고 장비의 한계 내에서 조정). 최소 레이어 높이로도 부족하면 대신 종료 속도를 낮춥니다."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19182,6 +19248,57 @@ msgstr ""
"단계 >= 0\n"
"끝 > 시작 + 단계)"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"종료 속도(%.0f mm/s)가 필라멘트의 최대 압출 속도(%.1f mm³/s)를 초과합니다. 현재 선 너비와 레이어 높이에서는 외벽이 약 %.0f mm/s로 제한됩니다.\n"
" 이보다 빠른 속도는 제한되므로 타워의 상단 블록은 요청한 속도로 출력되지 않습니다.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"종료 속도(%.0f mm/s)가 필라멘트의 최대 압출 속도(%.1f mm³/s)를 초과합니다(기본 레이어 높이 %.2f mm 기준).\n"
"\n"
"타워가 요청한 속도에 도달할 수 있도록 레이어 높이를 %.2f mm(이 프린터의 프로파일에서 사용하는 값)로 낮췄습니다."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"이 프린터의 프로파일에서 사용하는 가장 작은 레이어 높이(%.2f mm)에서도 종료 속도(%.0f mm/s)가 필라멘트의 최대 압출 속도(%.1f mm³/s)를 초과합니다.\n"
"\n"
"레이어 높이를 %.2f mm로 설정하고 종료 속도를 %.0f mm/s로 낮춥니다.\n"
"\n"
"계속하시겠습니까?"
# AI Translated
msgid "Continue anyway?"
msgstr "그래도 계속하시겠습니까?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "\"자동 조정\"을 활성화하면 자동으로 해결됩니다. 그래도 계속하시겠습니까?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "\"노즐에 맞춰 자동 크기 조정\"과 \"자동 조정\"을 활성화하면 자동으로 해결됩니다. 그래도 계속하시겠습니까?"
msgid "Start retraction length: "
msgstr "후퇴 시작 길이: "
@@ -21289,7 +21406,7 @@ msgstr "채워넣기 전혀 없음"
# AI Translated
msgid "Volumetric speed"
msgstr "체적 속도"
msgstr "압출 속도"
msgid "Step file import parameters"
msgstr "스텝 파일 가져오기 매개변수"
@@ -21940,6 +22057,9 @@ msgstr ""
"뒤틀림 방지\n"
"ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?"
#~ msgid "Print order within a single layer."
#~ msgstr "단일 레이어 내의 출력 순서"
#~ msgid "Bottom"
#~ msgstr "아래"
@@ -22008,9 +22128,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Continue to sync filaments"
#~ msgstr "필라멘트 동기화 계속하기"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-07-02 14:13+0300\n"
"Last-Translator: Gintaras Kučinskas <sharanchius@gmail.com>\n"
"Language-Team: \n"
@@ -3840,6 +3840,10 @@ msgstr "Išdėstoma..."
msgid "Arranging"
msgstr "Išdėstymas"
# AI Translated
msgid "Arranging "
msgstr "Išdėstoma "
msgid "Arranging canceled."
msgstr "Išdėstymas atšauktas."
@@ -9186,6 +9190,21 @@ msgstr "Pritemdyti apatinius sluoksnius"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Slenkant sluoksnių slankiklį pjaustytoje peržiūroje, atvaizduoti žemiau esančius sluoksnius pritemdytus, kad visu ryškumu būtų rodomas tik peržiūrimas sluoksnis."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Pritemdytų sluoksnių ryškumas"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Kaip ryškiai atvaizduojami pritemdyti sluoksniai, kai įjungta parinktis „Pritemdyti apatinius sluoksnius“.\n"
"99 % pritemdymas vos pastebimas, 0 % sluoksniai atvaizduojami juodai. Riba yra 99 %, nes 100 % prilygtų parinkties išjungimui."
msgid "Login region"
msgstr "Prisijungimo regionas"
@@ -13222,12 +13241,37 @@ msgstr "Objektas po objekto"
msgid "Intra-layer order"
msgstr "Eiliškumas sluoksnio viduje"
msgid "Print order within a single layer."
msgstr "Elementų spausdinimo eiliškumas vieno sluoksnio ribose."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Tvarka, kuria objektų kopijos aplankomos viename sluoksnyje; ji lemia, kiek tuščiosios eigos sugaištama pereinant tarp jų.\n"
"\n"
"Numatytasis: grandinės sudarymas artimiausio kaimyno metodu, patobulintas 2-opt algoritmu ir sankirtų šalinimu. Geras bendras pasirinkimas.\n"
"Kaip objektų sąrašas: kopijos spausdinamos tokia pačia tvarka kaip objektų sąraše, be jokio kelio optimizavimo. Naudokite, kai reikia nuspėjamos, rankiniu būdu valdomos tvarkos.\n"
"Geriausias iš visų (trumpiausias kelias): įvertinamos visos strategijos ir naudojama trumpiausia. Objektų kopijų tvarka nustatoma vieną kartą visam spausdinimui, o atskirų salelių tvarka kiekvienam sluoksniui atskirai, todėl skirtinguose sluoksniuose gali būti naudojamos skirtingos strategijos. Sluoksniuojama šiek tiek lėčiau.\n"
"Gyvatėle: vingiuotas ėjimas eilutė po eilutės, patobulintas 2-opt algoritmu. Gerai tinka taisyklingiems daugelio mažų detalių tinkleliams.\n"
"\n"
"Kai tame pačiame sluoksnyje naudojamos kelios gijos ar keli įrankiai, pirmenybė teikiama įrankio keitimų mažinimui: objektai pirmiausia grupuojami pagal giją, o ši nuostata rikiuoja tik kopijas kiekvienoje grupėje, todėl bendra seka gali neatrodyti kaip trumpiausias kelias per plokštę."
msgid "As object list"
msgstr "Kaip objektų sąrašas"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Geriausias iš visų (trumpiausias kelias)"
# AI Translated
msgid "Snake"
msgstr "Gyvatėle"
msgid "Slow printing down for better layer cooling"
msgstr "Sulėtinti spausdinimą geresniam sluoksnių aušinimui"
@@ -18537,6 +18581,20 @@ msgstr ""
"Yra keli IP adresai, susieti su mazgo pavadinimu %1%.\n"
"Pasirinkite tą, kurį norite naudoti."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Automatinis mastelis pagal purkštuką"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Šis modelis suprojektuotas 0,4 mm purkštukui ir 0,2 mm sluoksnio aukščiui. \n"
"Kai mastelio keitimo parinktis įjungta (rekomenduojama), modelio dydis dinamiškai pritaikomas prie jūsų dabartinio purkštuko skersmens ir tinkamo sluoksnio aukščio, todėl testas yra ir tikslus, ir lengvai įskaitomas.\n"
"Mastelio keitimą išjunkite tik tuo atveju, jei norite spausdinti etaloninį modelį tiksliai tokį, koks jis yra."
msgid "PA Calibration"
msgstr "PA kalibravimas (Pressure Advance)"
@@ -18673,6 +18731,14 @@ msgstr "Pradinis greitis: "
msgid "End speed: "
msgstr "Galinis greitis: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Automatiškai pritaikyti prie maksimalaus tūrinio greičio"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Jei galutinis greitis viršytų maksimalų gijos tūrinį greitį, automatiškai sumažinti sluoksnio aukštį (išlaikant standartines reikšmes ir neperžengiant įrenginio apribojimų), kad jį pasiektų. Jei net mažiausio sluoksnio aukščio nepakanka, vietoj to sumažinamas galutinis greitis."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18684,6 +18750,57 @@ msgstr ""
"žingsnis >= 0\n"
"galinis > pradinis + žingsnis"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Galutinis greitis (%.0f mm/s) viršija maksimalų gijos tūrinį greitį (%.1f mm³/s), kuris esant tokiam linijos pločiui ir sluoksnio aukščiui riboja išorinę sienelę iki maždaug %.0f mm/s.\n"
" Didesni greičiai bus apriboti, todėl viršutiniai bokšto blokai nebus spausdinami pageidaujamu greičiu.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Galutinis greitis (%.0f mm/s) viršija maksimalų gijos tūrinį greitį (%.1f mm³/s) esant numatytajam sluoksnio aukščiui (%.2f mm).\n"
"\n"
"Sluoksnio aukštis sumažintas iki %.2f mm (reikšmė, naudojama šio spausdintuvo profiliuose), kad bokštas galėtų pasiekti pageidaujamą greitį."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Net ir esant mažiausiam sluoksnio aukščiui, naudojamam šio spausdintuvo profiliuose (%.2f mm), galutinis greitis (%.0f mm/s) viršija maksimalų gijos tūrinį greitį (%.1f mm³/s).\n"
"\n"
"Sluoksnio aukštis bus nustatytas į %.2f mm, o galutinis greitis sumažintas iki %.0f mm/s.\n"
"\n"
"Tęsti?"
# AI Translated
msgid "Continue anyway?"
msgstr "Vis tiek tęsti?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Įjungti „Automatiškai pritaikyti“, kad tai būtų ištaisyta automatiškai, ar vis tiek tęsti?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Įjungti „Automatinis mastelis pagal purkštuką“ ir „Automatiškai pritaikyti“, kad tai būtų ištaisyta automatiškai, ar vis tiek tęsti?"
msgid "Start retraction length: "
msgstr "Pradinis įtraukimo ilgis: "
@@ -21219,6 +21336,9 @@ msgstr ""
"Venkite deformacijų (warping)\n"
"Ar žinojote, kad spausdinant medžiagas, kurios yra linkusios trauktis ir riestis (pvz., ABS), tinkamas kaitinamojo pagrindo temperatūros padidinimas gali sumažinti deformacijų (warping) tikimybę?"
#~ msgid "Print order within a single layer."
#~ msgstr "Elementų spausdinimo eiliškumas vieno sluoksnio ribose."
#~ msgid "Bottom"
#~ msgstr "Apačia"
@@ -21306,9 +21426,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "Realistiniame vaizde atvaizduoja krentančius šešėlius ant spausdinimo pagrindo."

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -4172,6 +4172,10 @@ msgstr "Rangschikken..."
msgid "Arranging"
msgstr "Rangschikken"
# AI Translated
msgid "Arranging "
msgstr "Rangschikken "
msgid "Arranging canceled."
msgstr "Rangschikken geannuleerd."
@@ -10076,6 +10080,21 @@ msgstr "Onderliggende lagen dimmen"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Bij het verschuiven van de laagschuifregelaar in de slicevoorvertoning worden de lagen onder de huidige laag verduisterd weergegeven, zodat alleen de bekeken laag op volle helderheid wordt getoond."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Helderheid van gedimde lagen"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Hoe helder de gedimde lagen worden weergegeven wanneer \"Onderliggende lagen dimmen\" is ingeschakeld.\n"
"99% is nauwelijks donkerder, 0% maakt ze zwart. Beperkt tot 99%, omdat 100% hetzelfde zou zijn als de optie uitschakelen."
msgid "Login region"
msgstr "Inlogregio"
@@ -14544,13 +14563,37 @@ msgid "Intra-layer order"
msgstr "Volgorde binnen een laag"
# AI Translated
msgid "Print order within a single layer."
msgstr "Printvolgorde binnen één laag."
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"De volgorde waarin objectinstanties binnen één laag worden bezocht, wat bepaalt hoeveel verplaatsing er nodig is om ertussen te bewegen.\n"
"\n"
"Standaard: aaneenschakeling via de dichtstbijzijnde buur, verfijnd met 2-opt en het verwijderen van kruisingen. Een goede algemene keuze.\n"
"Zoals de objectlijst: instanties worden afgedrukt in dezelfde volgorde als de objectlijst, zonder enige padoptimalisatie. Gebruik dit wanneer je een voorspelbare, handmatig bepaalde volgorde nodig hebt.\n"
"Beste van allemaal (kortste pad): elke strategie wordt beoordeeld en de kortste wordt gebruikt. De volgorde van de objectinstanties wordt eenmalig voor de hele print bepaald, terwijl de volgorde van de afzonderlijke eilanden per laag wordt bepaald, waardoor verschillende lagen uiteindelijk verschillende strategieën kunnen gebruiken. Het slicen duurt iets langer.\n"
"Slingerend: slingerend traject, rij voor rij, verfijnd met 2-opt. Zeer geschikt voor regelmatige rasters van veel kleine onderdelen.\n"
"\n"
"Bij meerdere filamenten of gereedschappen in dezelfde laag heeft het beperken van het aantal gereedschapswissels voorrang: objecten worden eerst per filament gegroepeerd en deze instelling bepaalt alleen de volgorde van de instanties binnen elke filamentgroep, waardoor de totale volgorde er niet uitziet als het kortste pad over het printbed."
# AI Translated
msgid "As object list"
msgstr "Zoals de objectlijst"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Beste van allemaal (kortste pad)"
# AI Translated
msgid "Snake"
msgstr "Slingerend"
msgid "Slow printing down for better layer cooling"
msgstr "Printsnelheid omlaag brengen zodat de laag beter kan koelen"
@@ -20593,6 +20636,20 @@ msgstr ""
"Er zijn meerdere IP-adressen die verwijzen naar hostname %1%.\n"
"Selecteer er een die gebruikt moet worden."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Automatisch schalen naar mondstuk"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Dit model is ontworpen voor een mondstuk van 0,4 mm met een laaghoogte van 0,2 mm. \n"
"Wanneer de schaaloptie is ingeschakeld (aanbevolen), wordt het model dynamisch aangepast aan je huidige mondstukdiameter en een passende laaghoogte, waardoor de test zowel nauwkeurig als goed afleesbaar is.\n"
"Schakel het schalen alleen uit als je het referentiemodel precies zo wilt printen als het is."
msgid "PA Calibration"
msgstr "PA-kalibratie"
@@ -20736,6 +20793,14 @@ msgstr "Startsnelheid:"
msgid "End speed: "
msgstr "Eindsnelheid:"
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Automatisch aanpassen aan max. volumetrische snelheid"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Als de eindsnelheid de maximale volumetrische snelheid van het filament zou overschrijden, wordt de laaghoogte automatisch verlaagd (met behoud van standaardwaarden en binnen de limieten van de machine) om die snelheid te halen. Als zelfs de minimale laaghoogte niet volstaat, wordt in plaats daarvan de eindsnelheid verlaagd."
# AI Translated
msgid ""
"Please input valid values:\n"
@@ -20748,6 +20813,57 @@ msgstr ""
"stap >= 0\n"
"einde > start + stap"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"De eindsnelheid (%.0f mm/s) overschrijdt de maximale volumetrische snelheid van het filament (%.1f mm³/s), waardoor de buitenste wand bij deze lijndikte en laaghoogte beperkt wordt tot ongeveer %.0f mm/s.\n"
" Hogere snelheden worden begrensd, waardoor de bovenste blokken van de toren niet op de gevraagde snelheid worden geprint.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"De eindsnelheid (%.0f mm/s) overschrijdt de maximale volumetrische snelheid van het filament (%.1f mm³/s) bij de standaard laaghoogte (%.2f mm).\n"
"\n"
"De laaghoogte is verlaagd naar %.2f mm (een waarde die door de profielen van deze printer wordt gebruikt), zodat de toren de gevraagde snelheid kan halen."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Zelfs bij de kleinste laaghoogte die door de profielen van deze printer wordt gebruikt (%.2f mm) overschrijdt de eindsnelheid (%.0f mm/s) de maximale volumetrische snelheid van het filament (%.1f mm³/s).\n"
"\n"
"De laaghoogte wordt ingesteld op %.2f mm en de eindsnelheid verlaagd naar %.0f mm/s.\n"
"\n"
"Doorgaan?"
# AI Translated
msgid "Continue anyway?"
msgstr "Toch doorgaan?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "\"Automatisch aanpassen\" inschakelen om dit automatisch op te lossen, of toch doorgaan?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "\"Automatisch schalen naar mondstuk\" en \"Automatisch aanpassen\" inschakelen om dit automatisch op te lossen, of toch doorgaan?"
msgid "Start retraction length: "
msgstr "Begin terugtreklengte:"
@@ -23665,6 +23781,10 @@ msgstr ""
"Kromtrekken voorkomen\n"
"Wist je dat bij het printen van materialen die gevoelig zijn voor kromtrekken, zoals ABS, een juiste verhoging van de temperatuur van het warmtebed de kans op kromtrekken kan verkleinen?"
# AI Translated
#~ msgid "Print order within a single layer."
#~ msgstr "Printvolgorde binnen één laag."
#~ msgid "Bottom"
#~ msgstr "Onderkant"
@@ -23707,9 +23827,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgctxt "Sync_Nozzle_AMS"
#~ msgid "Cancel"
#~ msgstr "Annuleren"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OrcaSlicer 2.3.0-rc\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Krzysztof Morga <<tlumaczeniebs@gmail.com>>\n"
"Language-Team: \n"
@@ -3926,6 +3926,10 @@ msgstr "Układanie..."
msgid "Arranging"
msgstr "Układanie"
# AI Translated
msgid "Arranging "
msgstr "Rozmieszczanie "
msgid "Arranging canceled."
msgstr "Układanie anulowane."
@@ -9479,6 +9483,21 @@ msgstr "Przyciemnij niższe warstwy"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Podczas przewijania suwaka warstw w podglądzie po cięciu renderuj warstwy poniżej bieżącej w przyciemnieniu, tak aby tylko oglądana warstwa była w pełnej jasności."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Jasność przyciemnionych warstw"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Jak jasno renderowane są przyciemnione warstwy, gdy włączona jest opcja „Przyciemnij niższe warstwy”.\n"
"99% oznacza ledwo zauważalne przyciemnienie, 0% renderuje je na czarno. Wartość jest ograniczona do 99%, ponieważ 100% oznaczałoby to samo co wyłączenie opcji."
msgid "Login region"
msgstr "Region logowania"
@@ -13709,12 +13728,37 @@ msgstr "Wg obiektu"
msgid "Intra-layer order"
msgstr "Kolejność warstw"
msgid "Print order within a single layer."
msgstr "Kolejność druku obiektów w obrębie jednej warstwy. Domyślnie lub według listy obiektów"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Kolejność, w jakiej instancje obiektów są odwiedzane w obrębie jednej warstwy; decyduje o tym, ile przemieszczeń zajmuje przechodzenie między nimi.\n"
"\n"
"Domyślny: łączenie metodą najbliższego sąsiada, dopracowane algorytmem 2-opt i usuwaniem przecięć. Dobry wybór ogólny.\n"
"Wg listy obiektów: instancje są drukowane w tej samej kolejności co na liście obiektów, bez optymalizacji ścieżki. Użyj, gdy potrzebujesz przewidywalnej, ręcznie ustalonej kolejności.\n"
"Najlepsza ze wszystkich (najkrótsza ścieżka): oceniane są wszystkie strategie i wybierana jest najkrótsza. Kolejność instancji obiektów ustalana jest raz dla całego wydruku, natomiast kolejność poszczególnych wysp jest ustalana dla każdej warstwy, więc różne warstwy mogą ostatecznie korzystać z różnych strategii. Cięcie trwa nieco dłużej.\n"
"Wężykiem: serpentynowe przechodzenie rząd po rzędzie, dopracowane algorytmem 2-opt. Dobrze sprawdza się przy regularnych siatkach wielu małych elementów.\n"
"\n"
"Gdy w tej samej warstwie używanych jest wiele filamentów lub narzędzi, priorytetem jest minimalizacja zmian narzędzia: obiekty są najpierw grupowane według filamentu, a to ustawienie porządkuje jedynie instancje w obrębie każdej grupy, więc ogólna sekwencja może nie wyglądać jak najkrótsza ścieżka po płycie."
msgid "As object list"
msgstr "Wg listy obiektów"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Najlepsza ze wszystkich (najkrótsza ścieżka)"
# AI Translated
msgid "Snake"
msgstr "Wężykiem"
msgid "Slow printing down for better layer cooling"
msgstr "Zwolnienie druku dla lepszego chłodzenia warstw"
@@ -19211,6 +19255,20 @@ msgstr ""
"Jest kilka adresów IP przypisanych do nazwy hosta %1%.\n"
"Proszę wybrać jeden, który ma być używany."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Automatyczne skalowanie do dyszy"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Ten model zaprojektowano dla dyszy 0,4 mm i wysokości warstwy 0,2 mm. \n"
"Gdy opcja skalowania jest włączona (zalecane), model dynamicznie dopasowuje rozmiar do średnicy Twojej obecnej dyszy i odpowiedniej wysokości warstwy, dzięki czemu test jest dokładny i łatwy do odczytania.\n"
"Wyłącz skalowanie tylko wtedy, gdy chcesz wydrukować model referencyjny dokładnie w oryginalnej postaci."
msgid "PA Calibration"
msgstr "Kalibracja PA"
@@ -19349,6 +19407,14 @@ msgstr "Rozpocznij z prędkością: "
msgid "End speed: "
msgstr "Zakończ z prędkością: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Automatyczne dopasowanie do maksymalnej prędkości przepływu"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Jeśli prędkość końcowa przekroczyłaby maksymalną prędkość przepływu filamentu, automatycznie obniż wysokość warstwy (zachowując standardowe wartości i pozostając w limitach maszyny), aby ją osiągnąć. Jeśli nawet minimalna wysokość warstwy nie wystarczy, obniżona zostanie prędkość końcowa."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19360,6 +19426,57 @@ msgstr ""
"krok >= 0\n"
"koniec > start + krok)"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Prędkość końcowa (%.0f mm/s) przekracza maksymalną prędkość przepływu filamentu (%.1f mm³/s), która przy tej szerokości linii i wysokości warstwy ogranicza zewnętrzną ścianę do około %.0f mm/s.\n"
" Wyższe prędkości zostaną ograniczone, więc górne bloki wieży nie zostaną wydrukowane z żądaną prędkością.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Prędkość końcowa (%.0f mm/s) przekracza maksymalną prędkość przepływu filamentu (%.1f mm³/s) przy domyślnej wysokości warstwy (%.2f mm).\n"
"\n"
"Wysokość warstwy została zmniejszona do %.2f mm (wartość stosowana w profilach tej drukarki), aby wieża mogła osiągnąć żądaną prędkość."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Nawet przy najmniejszej wysokości warstwy stosowanej w profilach tej drukarki (%.2f mm) prędkość końcowa (%.0f mm/s) przekracza maksymalną prędkość przepływu filamentu (%.1f mm³/s).\n"
"\n"
"Wysokość warstwy zostanie ustawiona na %.2f mm, a prędkość końcowa obniżona do %.0f mm/s.\n"
"\n"
"Kontynuować?"
# AI Translated
msgid "Continue anyway?"
msgstr "Kontynuować mimo to?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Włączyć „Automatyczne dopasowanie”, aby naprawić to automatycznie, czy kontynuować mimo to?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Włączyć „Automatyczne skalowanie do dyszy” i „Automatyczne dopasowanie”, aby naprawić to automatycznie, czy kontynuować mimo to?"
msgid "Start retraction length: "
msgstr "Długość retrakcji na początku: "
@@ -22117,6 +22234,9 @@ msgstr ""
"Unikaj odkształceń\n"
"Czy wiesz, że podczas drukowania filamentami podatnymi na odkształcenia, takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może zmniejszyć prawdopodobieństwo odkształceń?"
#~ msgid "Print order within a single layer."
#~ msgstr "Kolejność druku obiektów w obrębie jednej warstwy. Domyślnie lub według listy obiektów"
#~ msgid "Bottom"
#~ msgstr "Dół"
@@ -22191,9 +22311,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Continue to sync filaments"
#~ msgstr "Kontynuuj aby zsynchronizować filamenty"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-07-26 11:14-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: Portuguese, Brazilian\n"
@@ -3700,6 +3700,10 @@ msgstr "Organizando…"
msgid "Arranging"
msgstr "Organizando"
# AI Translated
msgid "Arranging "
msgstr "Organizando "
msgid "Arranging canceled."
msgstr "Organização cancelada."
@@ -8975,6 +8979,22 @@ msgstr "Escurecer camadas inferiores"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Ao mover o controle deslizante de camadas na pré-visualização fatiada, renderiza as camadas abaixo da atual escurecidas, de modo que apenas a camada visualizada seja exibida com brilho total."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Brilho das camadas escurecidas"
# AI Translated
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Com que brilho as camadas escurecidas são exibidas quando \"Escurecer camadas inferiores\" está ativado.\n"
"99% quase não escurece, 0% as deixa pretas. Limitado a 99% porque 100% seria o mesmo que desativar a opção."
msgid "Login region"
msgstr "Região de login"
@@ -12983,12 +13003,37 @@ msgstr "Por objeto"
msgid "Intra-layer order"
msgstr "Ordem intra-camada"
msgid "Print order within a single layer."
msgstr "Ordem de impressão dentro de uma única camada."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Ordem em que as instâncias dos objetos são visitadas dentro de uma mesma camada, o que determina quanto deslocamento é gasto no trajeto entre elas.\n"
"\n"
"Padrão: encadeamento por vizinho mais próximo, refinado com 2-opt e remoção de cruzamentos. Uma boa escolha geral.\n"
"Como lista de objetos: as instâncias são impressas na mesma ordem da lista de objetos, sem nenhuma otimização de trajeto. Use quando precisar de uma ordem previsível e controlada manualmente.\n"
"Melhor de todas (caminho mais curto): todas as estratégias são avaliadas e a mais curta é usada. A ordem das instâncias dos objetos é definida uma única vez para toda a impressão, enquanto a ordem das ilhas individuais é definida por camada, de modo que camadas diferentes podem acabar usando estratégias diferentes. O fatiamento fica um pouco mais lento.\n"
"Serpentina: percurso em serpentina, linha por linha, refinado com 2-opt. Adequado a grades regulares de muitas peças pequenas.\n"
"\n"
"Com vários filamentos ou ferramentas na mesma camada, minimizar as trocas de ferramenta tem prioridade: os objetos são agrupados primeiro por filamento e esta configuração ordena apenas as instâncias dentro de cada grupo de filamento, portanto a sequência geral pode não parecer o caminho mais curto pela placa."
msgid "As object list"
msgstr "Como lista de objetos"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Melhor de todas (caminho mais curto)"
# AI Translated
msgid "Snake"
msgstr "Serpentina"
msgid "Slow printing down for better layer cooling"
msgstr "Diminuir a velocidade de impressão para melhor resfriamento de camada"
@@ -18278,6 +18323,20 @@ msgstr ""
"Há vários endereços IP resolvendo para o nome do host %1%.\n"
"Por favor, selecione um que deve ser usado."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Escala automática para o bico"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Este modelo foi projetado para um bico de 0,4 mm com altura de camada de 0,2 mm. \n"
"Quando a opção de escala está ativada (recomendado), ele é redimensionado dinamicamente para corresponder ao diâmetro do bico atual e a uma altura de camada apropriada, tornando o teste preciso e fácil de ler.\n"
"Desative a escala apenas se quiser imprimir o modelo de referência exatamente como está."
msgid "PA Calibration"
msgstr "Calibração de PA"
@@ -18414,6 +18473,14 @@ msgstr "Velocidade Inicial: "
msgid "End speed: "
msgstr "Velocidade Final: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Ajuste automático à velocidade volumétrica máxima"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Se a velocidade final ultrapassar a velocidade volumétrica máxima do filamento, reduz automaticamente a altura de camada (mantendo valores padrão e respeitando os limites da máquina) para alcançá-la. Se nem mesmo a altura de camada mínima for suficiente, reduz a velocidade final."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18425,6 +18492,57 @@ msgstr ""
"passo >= 0\n"
"fim > início + passo"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"A velocidade final (%.0f mm/s) ultrapassa a velocidade volumétrica máxima do filamento (%.1f mm³/s), o que limita a parede externa a cerca de %.0f mm/s com esta largura de linha e altura de camada.\n"
" Velocidades acima disso serão limitadas, portanto os blocos superiores da torre não serão impressos na velocidade solicitada.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"A velocidade final (%.0f mm/s) ultrapassa a velocidade volumétrica máxima do filamento (%.1f mm³/s) na altura de camada padrão (%.2f mm).\n"
"\n"
"A altura de camada foi reduzida para %.2f mm (um valor usado pelos perfis desta impressora) para que a torre possa atingir a velocidade solicitada."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Mesmo na menor altura de camada usada pelos perfis desta impressora (%.2f mm), a velocidade final (%.0f mm/s) ultrapassa a velocidade volumétrica máxima do filamento (%.1f mm³/s).\n"
"\n"
"A altura de camada será definida como %.2f mm e a velocidade final reduzida para %.0f mm/s.\n"
"\n"
"Continuar?"
# AI Translated
msgid "Continue anyway?"
msgstr "Continuar mesmo assim?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Ativar \"Ajuste automático\" para corrigir isso automaticamente ou continuar mesmo assim?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Ativar \"Escala automática para o bico\" e \"Ajuste automático\" para corrigir isso automaticamente ou continuar mesmo assim?"
msgid "Start retraction length: "
msgstr "Distância de Retração Inicial: "
@@ -20948,6 +21066,9 @@ msgstr ""
"Evitar empenamento\n"
"Você sabia que ao imprimir materiais propensos ao empenamento como ABS, aumentar adequadamente a temperatura da mesa aquecida pode reduzir a probabilidade de empenamento?"
#~ msgid "Print order within a single layer."
#~ msgstr "Ordem de impressão dentro de uma única camada."
#~ msgid "Bottom"
#~ msgstr "Inferior"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OrcaSlicer V2.5.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-02-25 13:38+0300\n"
"Last-Translator: Felix14_v2\n"
"Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg <andylg@yandex.ru>\n"
@@ -3888,6 +3888,10 @@ msgstr "Расстановка..."
msgid "Arranging"
msgstr "Расстановка"
# AI Translated
msgid "Arranging "
msgstr "Расстановка "
msgid "Arranging canceled."
msgstr "Расстановка отменена."
@@ -9387,6 +9391,21 @@ msgstr "Затемнять нижние слои"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "При перемещении ползунка слоёв в предпросмотре нарезки слои ниже текущего отображаются затемнёнными, так что на полной яркости показан только просматриваемый слой."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Яркость затемнённых слоёв"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Насколько ярко отображаются затемнённые слои, когда включена опция «Затемнять нижние слои».\n"
"99% — затемнение почти незаметно, 0% — слои становятся чёрными. Максимум ограничен 99%, так как 100% равносильно отключению опции."
msgid "Login region"
msgstr "Регион входа"
@@ -13531,12 +13550,37 @@ msgstr "По очереди"
msgid "Intra-layer order"
msgstr "Очерёдность моделей"
msgid "Print order within a single layer."
msgstr "Последовательность печати моделей в пределах одного слоя."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Порядок обхода экземпляров моделей в пределах одного слоя; определяет, сколько перемещений тратится на переходы между ними.\n"
"\n"
"По умолчанию: построение цепочки методом ближайшего соседа с последующим улучшением алгоритмом 2-opt и устранением пересечений. Хороший универсальный вариант.\n"
"По списку: экземпляры печатаются в том же порядке, что и в списке моделей, без какой-либо оптимизации пути. Используйте, когда нужен предсказуемый, задаваемый вручную порядок.\n"
"Лучший из всех (кратчайший путь): оцениваются все стратегии и применяется та, что даёт кратчайший путь. Порядок экземпляров моделей определяется один раз для всей печати, а порядок отдельных островков — для каждого слоя, поэтому на разных слоях могут использоваться разные стратегии. Нарезка идёт немного медленнее.\n"
"Змейкой: змеевидный обход ряд за рядом с улучшением алгоритмом 2-opt. Хорошо подходит для регулярных сеток из множества мелких деталей.\n"
"\n"
"Если в одном слое используется несколько материалов или инструментов, приоритет отдаётся минимизации смен инструмента: модели сначала группируются по материалу, и эта настройка упорядочивает только экземпляры внутри каждой группы, поэтому общая последовательность может не выглядеть как кратчайший путь по столу."
msgid "As object list"
msgstr "По списку"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Лучший из всех (кратчайший путь)"
# AI Translated
msgid "Snake"
msgstr "Змейкой"
msgid "Slow printing down for better layer cooling"
msgstr "Замедлять печать для охлаждения слоёв"
@@ -19413,6 +19457,20 @@ msgstr ""
"По имени хоста %1% обнаружено несколько IP-адресов.\n"
"Выберите адрес для использования."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Автомасштабирование под сопло"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Эта модель рассчитана на сопло 0,4 мм и высоту слоя 0,2 мм. \n"
"Если включено масштабирование (рекомендуется), размер модели динамически подстраивается под диаметр вашего текущего сопла и подходящую высоту слоя, благодаря чему тест получается и точным, и легко читаемым.\n"
"Отключайте масштабирование, только если хотите напечатать эталонную модель ровно в исходном виде."
# В заголовке окна куча места
msgid "PA Calibration"
msgstr "Калибровка Pressure Advance"
@@ -19549,6 +19607,14 @@ msgstr "Начальная скорость: "
msgid "End speed: "
msgstr "Конечная скорость: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Автоподстройка под предел объёмного расхода"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Если конечная скорость превысит предел объёмного расхода материала, автоматически уменьшать высоту слоя (сохраняя стандартные значения и оставаясь в пределах ограничений принтера), чтобы её достичь. Если даже минимальной высоты слоя недостаточно, вместо этого снижается конечная скорость."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19560,6 +19626,57 @@ msgstr ""
"Шаг ≥ 0\n"
"Конечное > начальное + шаг"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Конечная скорость (%.0f мм/с) превышает предел объёмного расхода материала (%.1f мм³/с), который при такой ширине линии и высоте слоя ограничивает скорость внешних периметров примерно до %.0f мм/с.\n"
" Более высокие скорости будут ограничены, поэтому верхние блоки башни не напечатаются с заданной скоростью.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Конечная скорость (%.0f мм/с) превышает предел объёмного расхода материала (%.1f мм³/с) при высоте слоя по умолчанию (%.2f мм).\n"
"\n"
"Высота слоя уменьшена до %.2f мм (значение, используемое профилями этого принтера), чтобы башня могла достичь заданной скорости."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Даже при наименьшей высоте слоя, используемой профилями этого принтера (%.2f мм), конечная скорость (%.0f мм/с) превышает предел объёмного расхода материала (%.1f мм³/с).\n"
"\n"
"Высота слоя будет установлена в %.2f мм, а конечная скорость снижена до %.0f мм/с.\n"
"\n"
"Продолжить?"
# AI Translated
msgid "Continue anyway?"
msgstr "Всё равно продолжить?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Включить «Автоподстройку» для автоматического исправления или всё равно продолжить?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Включить «Автомасштабирование под сопло» и «Автоподстройку» для автоматического исправления или всё равно продолжить?"
msgid "Start retraction length: "
msgstr "Начальная длина отката: "
@@ -22153,6 +22270,9 @@ msgstr ""
"Предотвращение коробления материала\n"
"Знаете ли вы, что при печати материалами, склонными к короблению, таких как ABS, повышение температуры подогреваемого стола может снизить эту вероятность?"
#~ msgid "Print order within a single layer."
#~ msgstr "Последовательность печати моделей в пределах одного слоя."
#~ msgid "Bottom"
#~ msgstr "Снизу"
@@ -22226,9 +22346,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "Отрисовывать тени в режиме продвинутой графики."

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -4245,6 +4245,10 @@ msgstr "Placerar..."
msgid "Arranging"
msgstr "Placerar"
# AI Translated
msgid "Arranging "
msgstr "Placerar "
msgid "Arranging canceled."
msgstr "Placering avbruten."
@@ -10187,6 +10191,21 @@ msgstr "Dämpa underliggande lager"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "När du drar i lagerreglaget i den beredda förhandsgranskningen renderas lagren under det aktuella mörkare, så att endast det lager du tittar på visas med full ljusstyrka."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Ljusstyrka för dämpade lager"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Hur ljust de dämpade lagren återges när \"Dämpa underliggande lager\" är aktiverat.\n"
"99% är knappt mörkare, 0% gör dem helt svarta. Begränsat till 99% eftersom 100% skulle vara detsamma som att stänga av alternativet."
msgid "Login region"
msgstr "Logga in region"
@@ -14716,13 +14735,37 @@ msgid "Intra-layer order"
msgstr "Ordning inom lager"
# AI Translated
msgid "Print order within a single layer."
msgstr "Utskriftsordning inom ett enskilt lager."
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Ordningen som objektinstanserna besöks i inom ett och samma lager, vilket avgör hur mycket förflyttning som går åt mellan dem.\n"
"\n"
"Standard: kedjning efter närmaste granne, förfinad med 2-opt och borttagning av korsningar. Ett bra generellt val.\n"
"Som objektlistan: instanserna skrivs ut i samma ordning som i objektlistan, utan någon vägoptimering. Använd det när du behöver en förutsägbar ordning som du styr manuellt.\n"
"Bäst av alla (kortaste vägen): varje strategi utvärderas och den kortaste används. Ordningen för objektinstanserna bestäms en gång för hela utskriften, medan ordningen för enskilda öar bestäms per lager, så olika lager kan sluta med att använda olika strategier. Beredningen blir något långsammare.\n"
"Slingrande: slingrande färdväg rad för rad, förfinad med 2-opt. Passar bra för regelbundna rutnät med många små detaljer.\n"
"\n"
"Med flera filament eller verktyg i samma lager prioriteras att minimera antalet verktygsbyten: objekten grupperas först efter filament och den här inställningen ordnar bara instanserna inom varje filamentgrupp, så den totala sekvensen kanske inte ser ut som den kortaste vägen över plattan."
# AI Translated
msgid "As object list"
msgstr "Som objektlistan"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Bäst av alla (kortaste vägen)"
# AI Translated
msgid "Snake"
msgstr "Slingrande"
msgid "Slow printing down for better layer cooling"
msgstr "Sakta ner utskrift för bättre kylning av lager"
@@ -20823,6 +20866,20 @@ msgstr ""
"Det finns flera IP-adresser som pekar på värdnamnet %1%.\n"
"Välj vilken som ska användas."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Autoskala efter nozzel"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Den här modellen är utformad för en nozzel på 0,4 mm med en lagerhöjd på 0,2 mm. \n"
"När skalningsalternativet är aktiverat (rekommenderas) ändras storleken dynamiskt så att den matchar din aktuella nozzeldiameter och en lämplig lagerhöjd, vilket gör testet både noggrant och lättläst.\n"
"Stäng bara av skalningen om du vill skriva ut referensmodellen exakt som den är."
msgid "PA Calibration"
msgstr "PA kalibrering"
@@ -20969,6 +21026,14 @@ msgstr "Start hastighet: "
msgid "End speed: "
msgstr "Sluthastighet: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Autojustera till max volymetrisk hastighet"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Om sluthastigheten skulle överskrida filamentets maximala volymetriska hastighet sänks lagerhöjden automatiskt (med bibehållna standardvärden och inom maskinens gränser) för att nå den. Om inte ens den minsta lagerhöjden räcker sänks sluthastigheten i stället."
# AI Translated
msgid ""
"Please input valid values:\n"
@@ -20981,6 +21046,57 @@ msgstr ""
"steg >= 0\n"
"slut > start + steg"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Sluthastigheten (%.0f mm/s) överskrider filamentets maximala volymetriska hastighet (%.1f mm³/s), vilket begränsar den yttre väggen till omkring %.0f mm/s vid den här linjebredden och lagerhöjden.\n"
" Högre hastigheter kapas, så tornets övre block skrivs inte ut med den begärda hastigheten.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Sluthastigheten (%.0f mm/s) överskrider filamentets maximala volymetriska hastighet (%.1f mm³/s) vid standardlagerhöjden (%.2f mm).\n"
"\n"
"Lagerhöjden har sänkts till %.2f mm (ett värde som används av den här skrivarens profiler) så att tornet kan nå den begärda hastigheten."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Även vid den minsta lagerhöjd som används av den här skrivarens profiler (%.2f mm) överskrider sluthastigheten (%.0f mm/s) filamentets maximala volymetriska hastighet (%.1f mm³/s).\n"
"\n"
"Lagerhöjden ställs in på %.2f mm och sluthastigheten sänks till %.0f mm/s.\n"
"\n"
"Vill du fortsätta?"
# AI Translated
msgid "Continue anyway?"
msgstr "Vill du fortsätta ändå?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Vill du aktivera \"Autojustera\" för att åtgärda detta automatiskt, eller fortsätta ändå?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Vill du aktivera \"Autoskala efter nozzel\" och \"Autojustera\" för att åtgärda detta automatiskt, eller fortsätta ändå?"
msgid "Start retraction length: "
msgstr "Starta retraktion längd: "
@@ -23955,6 +24071,10 @@ msgstr ""
"Undvik vridning\n"
"Visste du att när du skriver ut material som är benägna att vrida, såsom ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten för vridning?"
# AI Translated
#~ msgid "Print order within a single layer."
#~ msgstr "Utskriftsordning inom ett enskilt lager."
#~ msgid "Bottom"
#~ msgstr "Botten"
@@ -24000,9 +24120,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "° C"
#~ msgid "%"
#~ msgstr "%"
#~ msgctxt "Sync_Nozzle_AMS"
#~ msgid "Cancel"
#~ msgstr "Avbryt"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-06-19 13:40+0700\n"
"Last-Translator: Icezaza\n"
"Language-Team: Thai\n"
@@ -3834,6 +3834,10 @@ msgstr "กำลังจัด..."
msgid "Arranging"
msgstr "การจัด"
# AI Translated
msgid "Arranging "
msgstr "กำลังจัด "
msgid "Arranging canceled."
msgstr "ยกเลิกการจัดเตรียมแล้ว"
@@ -9156,6 +9160,21 @@ msgstr "หรี่เลเยอร์ด้านล่าง"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "เมื่อเลื่อนแถบเลเยอร์ในตัวอย่างที่สไลซ์แล้ว จะแสดงเลเยอร์ที่อยู่ต่ำกว่าเลเยอร์ปัจจุบันแบบมืดลง เพื่อให้เห็นเฉพาะเลเยอร์ที่กำลังดูอยู่ด้วยความสว่างเต็มที่"
# AI Translated
msgid "Dimmed layer brightness"
msgstr "ความสว่างของเลเยอร์ที่หรี่"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"ความสว่างในการแสดงผลของเลเยอร์ที่ถูกหรี่ เมื่อเปิดใช้งาน \"หรี่เลเยอร์ด้านล่าง\"\n"
"99% คือหรี่ลงเพียงเล็กน้อย ส่วน 0% จะแสดงเป็นสีดำ ค่าสูงสุดถูกจำกัดไว้ที่ 99% เพราะ 100% จะให้ผลเหมือนกับการปิดตัวเลือกนี้"
msgid "Login region"
msgstr "เข้าสู่ระบบภูมิภาค"
@@ -13190,12 +13209,37 @@ msgstr "ตามวัตถุ"
msgid "Intra-layer order"
msgstr "คำสั่งภายในชั้น"
msgid "Print order within a single layer."
msgstr "สั่งพิมพ์ภายในชั้นเดียว"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"ลำดับการเข้าถึงอินสแตนซ์ของวัตถุภายในเลเยอร์เดียวกัน ซึ่งกำหนดว่าต้องเดินหัวเปล่าระหว่างกันมากเพียงใด\n"
"\n"
"ค่าเริ่มต้น: การเชื่อมต่อแบบเพื่อนบ้านที่ใกล้ที่สุด ปรับปรุงด้วย 2-opt และการกำจัดเส้นทางที่ตัดกัน เป็นตัวเลือกทั่วไปที่ดี\n"
"เป็นรายการวัตถุ: พิมพ์อินสแตนซ์ตามลำดับเดียวกับรายการวัตถุ โดยไม่มีการปรับปรุงเส้นทางใด ๆ ใช้เมื่อคุณต้องการลำดับที่คาดเดาได้และควบคุมเองได้\n"
"ดีที่สุดจากทั้งหมด (เส้นทางสั้นที่สุด): จะประเมินทุกกลยุทธ์แล้วเลือกใช้กลยุทธ์ที่สั้นที่สุด ลำดับอินสแตนซ์ของวัตถุจะถูกกำหนดครั้งเดียวสำหรับทั้งงานพิมพ์ ส่วนลำดับของแต่ละเกาะจะถูกกำหนดแยกในแต่ละเลเยอร์ ดังนั้นเลเยอร์ต่าง ๆ อาจใช้กลยุทธ์ที่ต่างกัน สไลซ์ช้าลงเล็กน้อย\n"
"แบบงูเลื้อย: การไล่ทีละแถวแบบงูเลื้อย ปรับปรุงด้วย 2-opt เหมาะกับกริดที่เป็นระเบียบของชิ้นงานเล็ก ๆ จำนวนมาก\n"
"\n"
"เมื่อมีเส้นพลาสติกหรือหัวพิมพ์หลายชนิดในเลเยอร์เดียวกัน การลดจำนวนการเปลี่ยนหัวพิมพ์จะมีความสำคัญก่อน โดยวัตถุจะถูกจัดกลุ่มตามเส้นพลาสติกก่อน และการตั้งค่านี้จะจัดลำดับเฉพาะอินสแตนซ์ภายในแต่ละกลุ่มเส้นพลาสติกเท่านั้น ลำดับโดยรวมจึงอาจดูไม่เหมือนเส้นทางที่สั้นที่สุดบนฐานพิมพ์"
msgid "As object list"
msgstr "เป็นรายการวัตถุ"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "ดีที่สุดจากทั้งหมด (เส้นทางสั้นที่สุด)"
# AI Translated
msgid "Snake"
msgstr "แบบงูเลื้อย"
msgid "Slow printing down for better layer cooling"
msgstr "ชะลอการพิมพ์ลงเพื่อการระบายความร้อนที่ดีขึ้น"
@@ -18524,6 +18568,20 @@ msgstr ""
"มีที่อยู่ IP หลายแห่งที่ใช้ชื่อโฮสต์ %1%\n"
"โปรดเลือกอันที่ควรใช้"
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "ปรับขนาดอัตโนมัติตามหัวฉีด"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"โมเดลนี้ออกแบบมาสำหรับหัวฉีดขนาด 0.4 mm และความสูงเลเยอร์ 0.2 mm \n"
"เมื่อเปิดใช้งานตัวเลือกการปรับขนาด (แนะนำ) โมเดลจะปรับขนาดแบบไดนามิกให้ตรงกับเส้นผ่านศูนย์กลางหัวฉีดปัจจุบันและความสูงเลเยอร์ที่เหมาะสม ทำให้การทดสอบทั้งแม่นยำและอ่านค่าได้ง่าย\n"
"ปิดการปรับขนาดเฉพาะเมื่อคุณต้องการพิมพ์โมเดลอ้างอิงตามขนาดเดิมทุกประการ"
msgid "PA Calibration"
msgstr "ปรับเทียบ PA"
@@ -18660,6 +18718,14 @@ msgstr "ความเร็วเริ่มต้น:"
msgid "End speed: "
msgstr "ความเร็วสิ้นสุด:"
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "ปรับอัตโนมัติตามความเร็วปริมาตรสูงสุด"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "หากความเร็วปลายทางจะเกินความเร็วปริมาตรสูงสุดของเส้นพลาสติก ระบบจะลดความสูงเลเยอร์โดยอัตโนมัติ (โดยคงค่ามาตรฐานไว้และอยู่ภายในขีดจำกัดของเครื่อง) เพื่อให้ถึงค่าดังกล่าว หากแม้แต่ความสูงเลเยอร์ต่ำสุดยังไม่เพียงพอ ระบบจะลดความเร็วปลายทางแทน"
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18671,6 +18737,57 @@ msgstr ""
"ขั้นตอน >= 0\n"
"สิ้นสุด> เริ่มต้น + ขั้นตอน"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"ความเร็วปลายทาง (%.0f mm/s) เกินความเร็วปริมาตรสูงสุดของเส้นพลาสติก (%.1f mm³/s) ซึ่งจำกัดผนังด้านนอกไว้ที่ประมาณ %.0f mm/s ที่ความกว้างเส้นและความสูงเลเยอร์นี้\n"
" ความเร็วที่สูงกว่านี้จะถูกจำกัดไว้ ดังนั้นบล็อกด้านบนของทาวเวอร์จะไม่พิมพ์ด้วยความเร็วที่ร้องขอ\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"ความเร็วปลายทาง (%.0f mm/s) เกินความเร็วปริมาตรสูงสุดของเส้นพลาสติก (%.1f mm³/s) ที่ความสูงเลเยอร์เริ่มต้น (%.2f mm)\n"
"\n"
"ความสูงเลเยอร์ถูกลดลงเป็น %.2f mm (ค่าที่ใช้ในพรีเซ็ตของเครื่องพิมพ์นี้) เพื่อให้ทาวเวอร์ถึงความเร็วที่ร้องขอได้"
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"แม้แต่ที่ความสูงเลเยอร์ต่ำสุดที่ใช้ในพรีเซ็ตของเครื่องพิมพ์นี้ (%.2f mm) ความเร็วปลายทาง (%.0f mm/s) ก็ยังเกินความเร็วปริมาตรสูงสุดของเส้นพลาสติก (%.1f mm³/s)\n"
"\n"
"ความสูงเลเยอร์จะถูกตั้งเป็น %.2f mm และความเร็วปลายทางจะถูกลดลงเป็น %.0f mm/s\n"
"\n"
"ดำเนินการต่อหรือไม่?"
# AI Translated
msgid "Continue anyway?"
msgstr "ดำเนินการต่ออยู่ดีหรือไม่?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "เปิดใช้งาน \"ปรับอัตโนมัติ\" เพื่อแก้ไขปัญหานี้โดยอัตโนมัติ หรือดำเนินการต่ออยู่ดี?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "เปิดใช้งาน \"ปรับขนาดอัตโนมัติตามหัวฉีด\" และ \"ปรับอัตโนมัติ\" เพื่อแก้ไขปัญหานี้โดยอัตโนมัติ หรือดำเนินการต่ออยู่ดี?"
msgid "Start retraction length: "
msgstr "เริ่มต้นความยาวการดึงกลับ:"
@@ -21244,6 +21361,9 @@ msgstr ""
"หลีกเลี่ยงการบิดเบี้ยว\n"
"คุณรู้หรือไม่ว่าเมื่อพิมพ์วัสดุที่มีแนวโน้มที่จะเกิดการบิดเบี้ยว เช่น ABS การเพิ่มอุณหภูมิฐานพิมพ์อย่างเหมาะสมสามารถลดความน่าจะเป็นของการบิดเบี้ยวได้"
#~ msgid "Print order within a single layer."
#~ msgstr "สั่งพิมพ์ภายในชั้นเดียว"
#~ msgid "Bottom"
#~ msgstr "ล่าง"
@@ -21331,9 +21451,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "แสดงเงาแบบทอดบนเพลตในมุมมองแบบสมจริง"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-04-08 23:59+0300\n"
"Last-Translator: GlauTech\n"
"Language-Team: \n"
@@ -3913,6 +3913,10 @@ msgstr "Hizalanıyor..."
msgid "Arranging"
msgstr "Hizalanıyor"
# AI Translated
msgid "Arranging "
msgstr "Hizalanıyor "
msgid "Arranging canceled."
msgstr "Hizalama iptal edildi."
@@ -9321,6 +9325,21 @@ msgstr "Alt katmanları karart"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Dilimlenmiş önizlemede katman kaydırıcısı gezdirilirken, geçerli katmanın altındaki katmanları koyulaştırarak yalnızca görüntülenen katmanın tam parlaklıkta gösterilmesini sağlar."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Karartılmış katman parlaklığı"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"\"Alt katmanları karart\" etkinleştirildiğinde karartılmış katmanların ne kadar parlak görüntüleneceği.\n"
"%99 neredeyse hiç karartmaz, %0 ise tamamen siyah gösterir. Üst sınır %99 olarak belirlenmiştir, çünkü %100 seçeneği devre dışı bırakmakla aynı olurdu."
msgid "Login region"
msgstr "Giriş bölgesi"
@@ -13468,12 +13487,37 @@ msgstr "Nesneye göre"
msgid "Intra-layer order"
msgstr "Katman içi sıra"
msgid "Print order within a single layer."
msgstr "Tek bir katmanda yazdırma sırası."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Tek bir katman içinde nesne örneklerinin hangi sırayla ziyaret edileceği; bu da aralarında ne kadar seyahat harcanacağını belirler.\n"
"\n"
"Varsayılan: en yakın komşu zincirlemesi, 2-opt ve kesişim giderme ile iyileştirilir. İyi bir genel seçim.\n"
"Nesne listesi olarak: örnekler, herhangi bir yol optimizasyonu olmadan nesne listesindeki sırayla yazdırılır. Öngörülebilir, elle denetlenen bir sıraya ihtiyacınız olduğunda kullanın.\n"
"Hepsinin en iyisi (en kısa yol): her strateji değerlendirilir ve en kısa olanı kullanılır. Nesne örneklerinin sırası tüm baskı için bir kez belirlenir, tek tek adaların sırası ise her katman için ayrı belirlenir; bu nedenle farklı katmanlar farklı stratejiler kullanabilir. Dilimleme biraz daha yavaştır.\n"
"Yılankavi: satır satır ilerleyen yılankavi geçiş, 2-opt ile iyileştirilir. Çok sayıda küçük parçadan oluşan düzenli ızgaralar için çok uygundur.\n"
"\n"
"Aynı katmanda birden fazla filament veya araç varsa, araç değişimlerini en aza indirmek önceliklidir: nesneler önce filamente göre gruplanır ve bu ayar yalnızca her filament grubu içindeki örnekleri sıralar; bu nedenle genel sıra, tabla genelindeki en kısa yol gibi görünmeyebilir."
msgid "As object list"
msgstr "Nesne listesi olarak"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Hepsinin en iyisi (en kısa yol)"
# AI Translated
msgid "Snake"
msgstr "Yılankavi"
msgid "Slow printing down for better layer cooling"
msgstr "Daha iyi katman soğutması için baskıyı yavaşlat"
@@ -18899,6 +18943,20 @@ msgstr ""
"%1% ana bilgisayar adına çözümlenen birkaç IP adresi var.\n"
"Hangisinin kullanılacağını seçin."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Nozul için otomatik ölçekleme"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Bu model, 0,4 mm nozul ve 0,2 mm katman yüksekliği esas alınarak tasarlanmıştır. \n"
"Ölçekleme seçeneği etkinleştirildiğinde (önerilir), model mevcut nozul çapınıza ve uygun bir katman yüksekliğine uyacak şekilde dinamik olarak yeniden boyutlandırılır; böylece test hem doğru hem de kolay okunur olur.\n"
"Ölçeklemeyi yalnızca referans modeli olduğu gibi yazdırmak istiyorsanız kapatın."
msgid "PA Calibration"
msgstr "PA Kalibrasyonu"
@@ -19036,6 +19094,14 @@ msgstr "Başlangıç hızı: "
msgid "End speed: "
msgstr "Bitiş hızı: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Maksimum hacimsel hıza otomatik ayarlama"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Bitiş hızı filamentin maksimum hacimsel hızını aşacak olursa, bu hıza ulaşabilmek için katman yüksekliği otomatik olarak düşürülür (standart değerler korunarak ve makinenin sınırları içinde kalınarak). Minimum katman yüksekliği bile yeterli değilse, bunun yerine bitiş hızı düşürülür."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19047,6 +19113,57 @@ msgstr ""
"adım >= 0\n"
"bitiş > başlangıç + adım)"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Bitiş hızı (%.0f mm/s), filamentin maksimum hacimsel hızını (%.1f mm³/s) aşıyor; bu da dış duvarı bu çizgi genişliği ve katman yüksekliğinde yaklaşık %.0f mm/s ile sınırlıyor.\n"
" Bunun üzerindeki hızlar sınırlanacağından, kulenin üst blokları istenen hızda yazdırılmayacak.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Bitiş hızı (%.0f mm/s), filamentin maksimum hacimsel hızını (%.1f mm³/s) varsayılan katman yüksekliğinde (%.2f mm) aşıyor.\n"
"\n"
"Kulenin istenen hıza ulaşabilmesi için katman yüksekliği %.2f mm değerine düşürüldü (bu yazıcının ön ayarlarında kullanılan bir değer)."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Bu yazıcının ön ayarlarında kullanılan en küçük katman yüksekliğinde bile (%.2f mm), bitiş hızı (%.0f mm/s) filamentin maksimum hacimsel hızını (%.1f mm³/s) aşıyor.\n"
"\n"
"Katman yüksekliği %.2f mm olarak ayarlanacak ve bitiş hızı %.0f mm/s değerine düşürülecek.\n"
"\n"
"Devam edilsin mi?"
# AI Translated
msgid "Continue anyway?"
msgstr "Yine de devam edilsin mi?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Bunu otomatik olarak düzeltmek için \"Otomatik ayarlama\" seçeneğini etkinleştirin ya da yine de devam edilsin mi?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Bunu otomatik olarak düzeltmek için \"Nozul için otomatik ölçekleme\" ve \"Otomatik ayarlama\" seçeneklerini etkinleştirin ya da yine de devam edilsin mi?"
msgid "Start retraction length: "
msgstr "Geri çekme uzunluğu başlangıcı: "
@@ -21742,6 +21859,9 @@ msgstr ""
"Eğilmeyi önleyin\n"
"ABS gibi bükülmeye yatkın malzemelere baskı yaparken, ısıtma yatağı sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını azaltabileceğini biliyor muydunuz?"
#~ msgid "Print order within a single layer."
#~ msgstr "Tek bir katmanda yazdırma sırası."
#~ msgid "Bottom"
#~ msgstr "Alt"
@@ -21822,9 +21942,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Continue to sync filaments"
#~ msgstr "Filamentleri senkronize etmeye devam edin"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: orcaslicerua\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-07-17 16:25+0300\n"
"Last-Translator: Andrij Mizyk <andm1zyk@proton.me>\n"
"Language-Team: Ukrainian\n"
@@ -3796,6 +3796,10 @@ msgstr "Організація..."
msgid "Arranging"
msgstr "Організація"
# AI Translated
msgid "Arranging "
msgstr "Впорядкування "
msgid "Arranging canceled."
msgstr "Організацію скасовано."
@@ -9297,6 +9301,21 @@ msgstr "Затемнювати нижні шари"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Під час прокручування повзунка шарів у попередньому перегляді нарізки відображати шари нижче поточного затемненими, щоб лише переглядуваний шар показувався з повною яскравістю."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Яскравість затемнених шарів"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Наскільки яскраво відображаються затемнені шари, коли увімкнено параметр «Затемнювати нижні шари».\n"
"99% — затемнення майже непомітне, 0% — шари стають чорними. Максимум обмежено 99%, оскільки 100% дорівнювало б вимкненню параметра."
msgid "Login region"
msgstr "Регіон входу"
@@ -13531,12 +13550,37 @@ msgstr "По обʼєктах"
msgid "Intra-layer order"
msgstr "Внутрішній порядок шарів"
msgid "Print order within a single layer."
msgstr "Друк замовлення в один шар"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Порядок, у якому обходяться екземпляри обʼєктів у межах одного шару; він визначає, скільки переміщень витрачається на переходи між ними.\n"
"\n"
"Типово: побудова ланцюга методом найближчого сусіда з подальшим удосконаленням алгоритмом 2-opt та усуненням перетинів. Хороший універсальний вибір.\n"
"За порядком у списку: екземпляри друкуються в тому самому порядку, що й у списку обʼєктів, без жодної оптимізації шляху. Використовуйте, коли потрібен передбачуваний порядок, заданий вручну.\n"
"Найкращий з усіх (найкоротший шлях): оцінюються всі стратегії й застосовується та, що дає найкоротший шлях. Порядок екземплярів обʼєктів визначається один раз для всього друку, а порядок окремих острівців — для кожного шару окремо, тож різні шари можуть використовувати різні стратегії. Нарізка триває трохи довше.\n"
"Змійкою: змієподібний обхід ряд за рядом з удосконаленням алгоритмом 2-opt. Добре підходить для регулярних сіток із багатьох дрібних деталей.\n"
"\n"
"Якщо в одному шарі використовується кілька філаментів або інструментів, пріоритет має мінімізація змін інструмента: обʼєкти спочатку групуються за філаментом, і цей параметр упорядковує лише екземпляри в межах кожної групи, тож загальна послідовність може не виглядати як найкоротший шлях по пластині."
msgid "As object list"
msgstr "За порядком у списку"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Найкращий з усіх (найкоротший шлях)"
# AI Translated
msgid "Snake"
msgstr "Змійкою"
msgid "Slow printing down for better layer cooling"
msgstr "Сповільнювати друк для кращого охолодження шару"
@@ -19089,6 +19133,20 @@ msgstr ""
"Є кілька IP-адрес, які перетворюються на ім’я хоста %1%.\n"
"Будь ласка, виберіть той, який слід використовувати."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Автомасштабування під сопло"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Ця модель розрахована на сопло 0,4 мм і висоту шару 0,2 мм. \n"
"Коли увімкнено масштабування (рекомендовано), розмір моделі динамічно підлаштовується під діаметр вашого поточного сопла та відповідну висоту шару, завдяки чому тест є точним і легко читається.\n"
"Вимикайте масштабування, лише якщо хочете надрукувати еталонну модель точно в первісному вигляді."
msgid "PA Calibration"
msgstr "Калібрування ВТ (РА)"
@@ -19230,6 +19288,14 @@ msgstr "Початкова швидкість: "
msgid "End speed: "
msgstr "Кінцева швидкість: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Автопідлаштування під максимальну обʼємну швидкість"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Якщо кінцева швидкість перевищить максимальну обʼємну швидкість філаменту, автоматично зменшувати висоту шару (зберігаючи стандартні значення та не виходячи за обмеження машини), щоб її досягти. Якщо навіть мінімальної висоти шару не досить, натомість буде знижено кінцеву швидкість."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19241,6 +19307,57 @@ msgstr ""
"крок >= 0\n"
"кінець > початок + крок)"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Кінцева швидкість (%.0f мм/с) перевищує максимальну обʼємну швидкість філаменту (%.1f мм³/с), яка за такої ширини лінії та висоти шару обмежує зовнішню стінку приблизно до %.0f мм/с.\n"
" Вищі швидкості будуть обмежені, тож верхні блоки вежі не надрукуються із заданою швидкістю.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Кінцева швидкість (%.0f мм/с) перевищує максимальну обʼємну швидкість філаменту (%.1f мм³/с) за типової висоти шару (%.2f мм).\n"
"\n"
"Висоту шару зменшено до %.2f мм (значення, яке використовують профілі цього принтера), щоб вежа могла досягти заданої швидкості."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Навіть за найменшої висоти шару, яку використовують профілі цього принтера (%.2f мм), кінцева швидкість (%.0f мм/с) перевищує максимальну обʼємну швидкість філаменту (%.1f мм³/с).\n"
"\n"
"Висоту шару буде встановлено на %.2f мм, а кінцеву швидкість знижено до %.0f мм/с.\n"
"\n"
"Продовжити?"
# AI Translated
msgid "Continue anyway?"
msgstr "Усе одно продовжити?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Увімкнути «Автопідлаштування», щоб виправити це автоматично, чи все одно продовжити?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Увімкнути «Автомасштабування під сопло» та «Автопідлаштування», щоб виправити це автоматично, чи все одно продовжити?"
msgid "Start retraction length: "
msgstr "Початкова довжина ретракту: "
@@ -21862,6 +21979,9 @@ msgstr ""
"Уникнення деформації\n"
"Чи знаєте ви, що при друку матеріалами, схильними до деформації, такими як ABS, відповідне підвищення температури столу може зменшити ймовірність деформації?"
#~ msgid "Print order within a single layer."
#~ msgstr "Друк замовлення в один шар"
#~ msgid "Bottom"
#~ msgstr "Низ"
@@ -21940,9 +22060,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "℃"
#~ msgid "%"
#~ msgstr "%"
#~ msgctxt "Sync_Nozzle_AMS"
#~ msgid "Cancel"
#~ msgstr "Скасувати"

View File

@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2025-10-02 17:43+0700\n"
"Last-Translator: \n"
"Language-Team: hainguyen.ts13@gmail.com\n"
@@ -4031,6 +4031,10 @@ msgstr "Đang sắp xếp..."
msgid "Arranging"
msgstr "Đang sắp xếp"
# AI Translated
msgid "Arranging "
msgstr "Đang sắp xếp "
msgid "Arranging canceled."
msgstr "Hủy sắp xếp."
@@ -9779,6 +9783,21 @@ msgstr "Làm mờ các lớp bên dưới"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "Khi kéo thanh trượt lớp trong bản xem trước đã slice, kết xuất các lớp bên dưới lớp hiện tại ở dạng tối đi để chỉ lớp đang xem hiển thị với độ sáng đầy đủ."
# AI Translated
msgid "Dimmed layer brightness"
msgstr "Độ sáng của lớp bị làm mờ"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"Mức độ sáng khi hiển thị các lớp bị làm mờ nếu bật \"Làm mờ các lớp bên dưới\".\n"
"99% gần như không tối đi, 0% khiến chúng đen hoàn toàn. Giới hạn ở 99% vì 100% sẽ giống hệt như tắt tùy chọn này."
# AI Translated
msgid "Login region"
msgstr "Khu vực đăng nhập"
@@ -14093,12 +14112,37 @@ msgstr "Theo đối tượng"
msgid "Intra-layer order"
msgstr "Thứ tự trong lớp"
msgid "Print order within a single layer."
msgstr "Thứ tự in trong một lớp đơn."
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"Thứ tự các instance của đối tượng được đi qua trong cùng một lớp, quyết định lượng di chuyển tiêu tốn khi đi giữa chúng.\n"
"\n"
"Mặc định: nối chuỗi theo láng giềng gần nhất, tinh chỉnh bằng 2-opt và loại bỏ các đoạn cắt nhau. Lựa chọn chung tốt.\n"
"Như danh sách đối tượng: các instance được in theo đúng thứ tự trong danh sách đối tượng, không tối ưu hóa đường đi. Dùng khi bạn cần một thứ tự dễ đoán và tự kiểm soát.\n"
"Tốt nhất trong tất cả (đường đi ngắn nhất): mọi chiến lược đều được đánh giá và chiến lược ngắn nhất được sử dụng. Thứ tự các instance của đối tượng được quyết định một lần cho toàn bộ bản in, còn thứ tự của từng đảo được quyết định theo từng lớp, nên các lớp khác nhau có thể dùng chiến lược khác nhau. Slice hơi chậm hơn một chút.\n"
"Ngoằn ngoèo: duyệt lần lượt từng hàng theo kiểu ngoằn ngoèo, tinh chỉnh bằng 2-opt. Rất phù hợp với các lưới đều gồm nhiều chi tiết nhỏ.\n"
"\n"
"Khi có nhiều filament hoặc đầu công cụ trong cùng một lớp, việc giảm thiểu số lần đổi đầu công cụ được ưu tiên: các đối tượng được nhóm theo filament trước, và thiết lập này chỉ sắp xếp các instance trong từng nhóm filament, nên trình tự tổng thể có thể không giống đường đi ngắn nhất trên bàn in."
msgid "As object list"
msgstr "Như danh sách đối tượng"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "Tốt nhất trong tất cả (đường đi ngắn nhất)"
# AI Translated
msgid "Snake"
msgstr "Ngoằn ngoèo"
msgid "Slow printing down for better layer cooling"
msgstr "Giảm tốc độ in để làm mát lớp tốt hơn"
@@ -19626,6 +19670,20 @@ msgstr ""
"Có nhiều địa chỉ IP phân giải thành tên máy chủ %1%.\n"
"Vui lòng chọn một địa chỉ nên được sử dụng."
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "Tự động chia tỷ lệ theo đầu phun"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"Mô hình này được thiết kế cho đầu phun 0.4 mm với chiều cao lớp 0.2 mm. \n"
"Khi bật tùy chọn chia tỷ lệ (khuyến nghị), mô hình sẽ tự động thay đổi kích thước cho khớp với đường kính đầu phun hiện tại và một chiều cao lớp phù hợp, giúp bài kiểm tra vừa chính xác vừa dễ đọc.\n"
"Chỉ tắt chia tỷ lệ nếu bạn muốn in mô hình tham chiếu đúng nguyên trạng."
msgid "PA Calibration"
msgstr "Hiệu chỉnh PA"
@@ -19764,6 +19822,14 @@ msgstr "Tốc độ bắt đầu: "
msgid "End speed: "
msgstr "Tốc độ kết thúc: "
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "Tự động điều chỉnh theo tốc độ thể tích tối đa"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "Nếu tốc độ kết thúc vượt quá tốc độ thể tích tối đa của filament, tự động giảm chiều cao lớp (giữ các giá trị tiêu chuẩn và nằm trong giới hạn của máy) để đạt được tốc độ đó. Nếu ngay cả chiều cao lớp nhỏ nhất vẫn chưa đủ, thì giảm tốc độ kết thúc thay vào đó."
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -19775,6 +19841,57 @@ msgstr ""
"bước >= 0\n"
"kết thúc > bắt đầu + bước"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"Tốc độ kết thúc (%.0f mm/s) vượt quá tốc độ thể tích tối đa của filament (%.1f mm³/s), khiến thành ngoài bị giới hạn ở khoảng %.0f mm/s với độ rộng đường và chiều cao lớp hiện tại.\n"
" Các tốc độ cao hơn mức này sẽ bị cắt bớt, nên những khối phía trên của tháp sẽ không in ở tốc độ yêu cầu.\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"Tốc độ kết thúc (%.0f mm/s) vượt quá tốc độ thể tích tối đa của filament (%.1f mm³/s) ở chiều cao lớp mặc định (%.2f mm).\n"
"\n"
"Chiều cao lớp đã được giảm xuống %.2f mm (một giá trị được dùng trong các cài đặt sẵn của máy in này) để tháp có thể đạt tốc độ yêu cầu."
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"Ngay cả ở chiều cao lớp nhỏ nhất được dùng trong các cài đặt sẵn của máy in này (%.2f mm), tốc độ kết thúc (%.0f mm/s) vẫn vượt quá tốc độ thể tích tối đa của filament (%.1f mm³/s).\n"
"\n"
"Chiều cao lớp sẽ được đặt thành %.2f mm và tốc độ kết thúc giảm xuống %.0f mm/s.\n"
"\n"
"Tiếp tục?"
# AI Translated
msgid "Continue anyway?"
msgstr "Vẫn tiếp tục?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Bật \"Tự động điều chỉnh\" để khắc phục việc này tự động, hoặc vẫn tiếp tục?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "Bật \"Tự động chia tỷ lệ theo đầu phun\" và \"Tự động điều chỉnh\" để khắc phục việc này tự động, hoặc vẫn tiếp tục?"
msgid "Start retraction length: "
msgstr "Độ dài rút bắt đầu: "
@@ -22585,6 +22702,9 @@ msgstr ""
"Tránh cong vênh\n"
"Bạn có biết rằng khi in vật liệu dễ cong vênh như ABS, tăng nhiệt độ bàn nóng một cách thích hợp có thể giảm xác suất cong vênh không?"
#~ msgid "Print order within a single layer."
#~ msgstr "Thứ tự in trong một lớp đơn."
#~ msgid "Bottom"
#~ msgstr "Dưới"
@@ -22627,9 +22747,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgctxt "Sync_Nozzle_AMS"
#~ msgid "Cancel"
#~ msgstr "Hủy"

View File

@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Slic3rPE\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2026-06-11 12:37-0300\n"
"Last-Translator: Handle <mail@bysb.net>\n"
"Language-Team: \n"
@@ -3694,6 +3694,10 @@ msgstr "自动摆放中..."
msgid "Arranging"
msgstr "自动摆放"
# AI Translated
msgid "Arranging "
msgstr "自动摆放 "
msgid "Arranging canceled."
msgstr "已取消自动摆放。"
@@ -8978,6 +8982,21 @@ msgstr "调暗下方图层"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "在切片预览中拖动图层滑块时,将当前图层下方的图层渲染为变暗状态,以便只有正在查看的图层以完整亮度显示。"
# AI Translated
msgid "Dimmed layer brightness"
msgstr "调暗图层的亮度"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"启用“调暗下方图层”时,被调暗的图层以多高的亮度显示。\n"
"99% 表示几乎不变暗0% 表示显示为纯黑。上限为 99%,因为 100% 与关闭该选项的效果相同。"
msgid "Login region"
msgstr "登录区域"
@@ -12949,12 +12968,37 @@ msgstr "逐件"
msgid "Intra-layer order"
msgstr "层内打印顺序"
msgid "Print order within a single layer."
msgstr "同一层内的打印顺序"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"在同一层内访问各对象实例的顺序,它决定了在实例之间移动所花费的空驶量。\n"
"\n"
"默认:以最近邻方式串联,并通过 2-opt 和交叉消除进行优化。通常是较好的选择。\n"
"按对象列表中的顺序:不做任何路径优化,按对象列表中的顺序打印各实例。需要可预测、手动控制的顺序时使用。\n"
"全部比较(最短路径):评估所有策略并采用最短的一种。对象实例的顺序在整个打印任务中只确定一次,而各个岛的排序则逐层确定,因此不同层可能采用不同的策略。切片速度略慢。\n"
"蛇形:逐行往复的蛇形遍历,并通过 2-opt 进行优化。非常适合由大量小零件组成的规则阵列。\n"
"\n"
"当同一层中使用多种耗材丝或工具时,优先减少换料次数:对象会先按耗材丝分组,本设置仅决定每个耗材丝分组内实例的顺序,因此整体顺序看起来可能不是整个热床上的最短路径。"
msgid "As object list"
msgstr "按对象列表中的顺序"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "全部比较(最短路径)"
# AI Translated
msgid "Snake"
msgstr "蛇形"
msgid "Slow printing down for better layer cooling"
msgstr "降低打印速度 以得到更好的冷却"
@@ -18278,6 +18322,20 @@ msgstr ""
"主机名 %1% 指向了多个IP地址\n"
"请在其中选择一个正在使用的地址。"
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "根据喷嘴自动缩放"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"该模型是按 0.4 mm 喷嘴和 0.2 mm 层高设计的。 \n"
"启用缩放选项后(推荐),模型会根据当前喷嘴直径和合适的层高动态调整尺寸,使测试既准确又易于读取。\n"
"只有当您希望完全按原样打印参考模型时,才关闭缩放。"
msgid "PA Calibration"
msgstr "压力提前/PA校准"
@@ -18412,6 +18470,14 @@ msgstr "起始速度"
msgid "End speed: "
msgstr "结束速度"
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "自动调整以适应最大体积流量"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "如果结束速度会超过耗材丝的最大体积流量,则自动降低层高(保持标准数值并处于机器限制范围内)以达到该速度。如果连最小层高也不够,则改为降低结束速度。"
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18423,6 +18489,57 @@ msgstr ""
"步进长度 >= 0\n"
"结束 > 开始 + 步进长度)"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"结束速度(%.0f mm/s超过了耗材丝的最大体积流量%.1f mm³/s在当前线宽和层高下外墙被限制在约 %.0f mm/s。\n"
" 超过该值的速度会被钳制,因此塔的上部区块不会以请求的速度打印。\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"结束速度(%.0f mm/s超过了耗材丝的最大体积流量%.1f mm³/s默认层高 %.2f mm 时)。\n"
"\n"
"层高已降至 %.2f mm该打印机配置中使用的数值以便塔能够达到请求的速度。"
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"即使采用该打印机配置中使用的最小层高(%.2f mm结束速度%.0f mm/s仍超过耗材丝的最大体积流量%.1f mm³/s。\n"
"\n"
"层高将设为 %.2f mm结束速度将降至 %.0f mm/s。\n"
"\n"
"是否继续?"
# AI Translated
msgid "Continue anyway?"
msgstr "仍要继续吗?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "启用“自动调整”可自动解决该问题,或者仍要继续?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "启用“根据喷嘴自动缩放”和“自动调整”可自动解决该问题,或者仍要继续?"
msgid "Start retraction length: "
msgstr "起始回抽长度"
@@ -20994,6 +21111,9 @@ msgstr ""
"避免翘曲\n"
"您知道吗打印ABS这类易翘曲材料时适当提高热床温度可以降低翘曲的概率。"
#~ msgid "Print order within a single layer."
#~ msgstr "同一层内的打印顺序"
#~ msgid "Bottom"
#~ msgstr "底部"
@@ -21086,9 +21206,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "在写实渲染中渲染投射到打印板上的阴影。"

View File

@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-26 21:59-0300\n"
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
"PO-Revision-Date: 2025-11-28 13:48-0600\n"
"Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n"
"Language-Team: \n"
@@ -3795,6 +3795,10 @@ msgstr "自動擺放中..."
msgid "Arranging"
msgstr "自動擺放"
# AI Translated
msgid "Arranging "
msgstr "自動擺放 "
msgid "Arranging canceled."
msgstr "已取消自動擺放。"
@@ -4675,7 +4679,7 @@ msgid ""
"Too small max volumetric speed.\n"
"Value was reset to 0.5"
msgstr ""
"最大體積速度設定過小\n"
"最大體積流量設定過小\n"
"重設為 0.5"
#, c-format, boost-format
@@ -9151,6 +9155,21 @@ msgstr "使下方層變暗"
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
msgstr "在切片預覽中拖曳層滑桿時,將目前層以下的各層算繪為變暗,如此只有正在檢視的層以全亮度顯示。"
# AI Translated
msgid "Dimmed layer brightness"
msgstr "變暗層的亮度"
msgid "%"
msgstr "%"
# AI Translated
msgid ""
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
msgstr ""
"啟用「使下方層變暗」時,變暗的層以多高的亮度顯示。\n"
"99% 幾乎不會變暗0% 會顯示為全黑。上限為 99%,因為 100% 與停用此選項的效果相同。"
msgid "Login region"
msgstr "登入區域"
@@ -13162,12 +13181,37 @@ msgstr "逐件"
msgid "Intra-layer order"
msgstr "單層順序"
msgid "Print order within a single layer."
msgstr "每一層的列印順序"
# AI Translated
msgid ""
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
"\n"
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
"\n"
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
msgstr ""
"在同一層內走訪各物件實例的順序,這會決定在實例之間移動所花費的空駛量。\n"
"\n"
"預設:以最近鄰方式串接,並以 2-opt 與交叉消除進行改善。通常是不錯的選擇。\n"
"按照物件清單排序:不做任何路徑最佳化,依照物件清單的順序列印各實例。需要可預測、手動控制的順序時使用。\n"
"全部比較(最短路徑):評估所有策略並採用最短的一種。物件實例的順序在整個列印工作中只決定一次,而個別島嶼的排序則逐層決定,因此不同層可能採用不同的策略。切片速度略慢。\n"
"蛇形:逐行往復的蛇形走訪,並以 2-opt 進行改善。非常適合由大量小零件組成的規則陣列。\n"
"\n"
"當同一層中使用多種線材或工具時,會優先減少換料次數:物件會先依線材分組,此設定僅決定每個線材群組內實例的順序,因此整體順序看起來可能不是整個列印板上的最短路徑。"
msgid "As object list"
msgstr "按照物件清單排序"
# AI Translated
msgid "Best of all (shortest path)"
msgstr "全部比較(最短路徑)"
# AI Translated
msgid "Snake"
msgstr "蛇形"
msgid "Slow printing down for better layer cooling"
msgstr "降低列印速度 以得到更好的冷卻"
@@ -18461,6 +18505,20 @@ msgstr ""
"有多個 IP 位址解析到主機名稱 %1%。\n"
"請選擇一個要使用的 IP 位址。"
# AI Translated
msgid "Auto-scale for nozzle"
msgstr "依噴嘴自動縮放"
# AI Translated
msgid ""
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
"Turn scaling off only if you wish to print the reference model exactly as-is."
msgstr ""
"此模型是以 0.4 mm 噴嘴與 0.2 mm 層高為基準設計的。 \n"
"啟用縮放選項後(建議),模型會依目前的噴嘴直徑與合適的層高動態調整尺寸,使測試既準確又容易判讀。\n"
"只有在您想完全按原樣列印參考模型時,才關閉縮放。"
msgid "PA Calibration"
msgstr "PA 校正"
@@ -18597,6 +18655,14 @@ msgstr "起始速度:"
msgid "End speed: "
msgstr "結束速度:"
# AI Translated
msgid "Auto-adjust to max volumetric speed"
msgstr "自動調整以符合最大體積流量"
# AI Translated
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
msgstr "如果結束速度會超過線材的最大體積流量,則自動降低層高(維持標準數值並處於機器限制範圍內)以達到該速度。如果連最小層高也不夠,則改為降低結束速度。"
msgid ""
"Please input valid values:\n"
"start > 10\n"
@@ -18608,6 +18674,57 @@ msgstr ""
"步距 >= 0\n"
"結束 > 開始 + 步距)"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
"\n"
"%s"
msgstr ""
"結束速度(%.0f mm/s超過線材的最大體積流量%.1f mm³/s在目前的線寬與層高下外牆被限制在約 %.0f mm/s。\n"
" 超過該值的速度會被箝制,因此塔的上部區塊不會以要求的速度列印。\n"
"\n"
"%s"
# AI Translated
#, c-format, boost-format
msgid ""
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
"\n"
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
msgstr ""
"結束速度(%.0f mm/s超過線材的最大體積流量%.1f mm³/s預設層高 %.2f mm 時)。\n"
"\n"
"層高已降至 %.2f mm此印表機的設定檔中使用的數值以便塔能夠達到要求的速度。"
# AI Translated
#, c-format, boost-format
msgid ""
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
"\n"
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
"\n"
"Continue?"
msgstr ""
"即使採用此印表機的設定檔中使用的最小層高(%.2f mm結束速度%.0f mm/s仍超過線材的最大體積流量%.1f mm³/s。\n"
"\n"
"層高將設為 %.2f mm結束速度將降至 %.0f mm/s。\n"
"\n"
"是否繼續?"
# AI Translated
msgid "Continue anyway?"
msgstr "仍要繼續嗎?"
# AI Translated
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "啟用「自動調整」可自動解決此問題,或者仍要繼續?"
# AI Translated
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
msgstr "啟用「依噴嘴自動縮放」和「自動調整」可自動解決此問題,或者仍要繼續?"
msgid "Start retraction length: "
msgstr "起始回抽長度:"
@@ -21206,6 +21323,9 @@ msgstr ""
"避免翹曲\n"
"您知道嗎?當列印容易翹曲的材料(如 ABS適當提高熱床溫度可以降低翹曲的機率。"
#~ msgid "Print order within a single layer."
#~ msgstr "每一層的列印順序"
#~ msgid "Bottom"
#~ msgstr "底部"
@@ -21298,9 +21418,6 @@ msgstr ""
#~ msgid "°C"
#~ msgstr "°C"
#~ msgid "%"
#~ msgstr "%"
#~ msgid "Renders cast shadows on the plate in realistic view."
#~ msgstr "在擬真檢視中於列印板上算繪投射陰影。"

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python3
"""Belt temperature-tower asset generator (discrete-provini design).
A vertical temperature tower cannot be sliced on a belt printer, so lay a row of
DISCRETE provini (one per temperature) along the belt (designed Y) with a fixed
surface gap. Each provino is the chevron+arc unit (belt_temp_provino_unit.stl,
keel-first); its temperature is ENGRAVED upright into the 50 mm face — a raised
number would be an unsupported overhang on the belt. The C++ calib_temp belt branch
(Plater.cpp) injects one M104 per zone 70 layers INTO provino i:
print_z[i] = i * PITCH * cos(theta) + 70 * layer_height (theta = 45)
inside the body, not in the empty inter-provino gap (which has no sliced layers for
the event to attach to). PITCH below is the shared geometry contract with that code —
keep them in sync.
Generates one STL per filament temp range used by Temp_Calibration_Dlg.
"""
import numpy as np, trimesh, os
from matplotlib.textpath import TextPath
from matplotlib.font_manager import FontProperties
from shapely.geometry import Polygon as ShPoly
from shapely.ops import unary_union
HERE = os.path.dirname(os.path.abspath(__file__))
UNIT = os.path.join(HERE, 'belt_temp_provino_unit.stl') # single provino, keel-first
SURF_GAP = 25.0 # surface-to-surface gap between provini (mm) — user spec
TEXT_H = 9.0
TEXT_DEPTH = 0.8 # engraving depth (numbers are CUT into the face, not raised:
# a raised number is an unsupported Y-overhang on the belt)
TEXT_OVERSHOOT = 0.6 # extra height poking out of the face for a clean boolean cut
# Temperature ranges (start, end) per filament family, 5 C step. File name encodes them.
RANGES = [(230,190),(270,230),(250,230),(280,240),(240,210),(320,280)]
unit = trimesh.load(UNIT)
dY = unit.bounds[1,1] - unit.bounds[0,1]
PITCH = dY + SURF_GAP # designed-Y pitch == C++ contract constant
print(f"unit dY={dY:.2f} PITCH={PITCH:.3f} (C++ contract: print_z[i]=i*{PITCH:.3f}*cos45)")
# 50 mm face normal (0,-1,1)/sqrt2 ; UPRIGHT basis u=+X det(+1) (verified non-mirrored)
n = np.array([0,-1,1.])/np.sqrt(2)
u = np.array([1,0,0.]); v = np.array([0,1,1.])/np.sqrt(2)
R = np.column_stack([u,v,n])
fn = unit.face_normals; fc = unit.triangles_center; fa = unit.area_faces
sel = (fn@n) > 0.9
face_c = (fc[sel]*fa[sel,None]).sum(0)/fa[sel].sum()
def text_mesh(s):
tp = TextPath((0,0), s, size=TEXT_H, prop=FontProperties(family='DejaVu Sans'))
rings = [ShPoly(p) for p in tp.to_polygons() if len(p)>=3]
rings.sort(key=lambda r:r.area, reverse=True)
used=[False]*len(rings); parts=[]
for i,o in enumerate(rings):
if used[i]: continue
holes=[]
for j in range(i+1,len(rings)):
if not used[j] and o.contains(rings[j]): holes.append(rings[j].exterior.coords); used[j]=True
parts.append(ShPoly(o.exterior.coords,holes)); used[i]=True
poly = unary_union(parts)
geoms = list(poly.geoms) if poly.geom_type=='MultiPolygon' else [poly]
m = trimesh.util.concatenate([trimesh.creation.extrude_polygon(g,height=TEXT_DEPTH+TEXT_OVERSHOOT) for g in geoms])
c = m.bounds.mean(axis=0); m.apply_translation([-c[0],-c[1],0]); return m
for t_start, t_end in RANGES:
temps = list(range(t_start, t_end-1, -5))
parts=[]
for i,T in enumerate(temps):
c = unit.copy(); c.apply_translation([0, i*PITCH, 0])
t = text_mesh(str(T)); M=np.eye(4); M[:3,:3]=R; t.apply_transform(M)
# place the text spanning from TEXT_DEPTH inside the face to TEXT_OVERSHOOT outside,
# then CUT it out of the provino (engrave) — no raised material, no Y-overhang.
t.apply_translation(face_c - n*TEXT_DEPTH + np.array([0,i*PITCH,0]))
c = trimesh.boolean.difference([c, t], engine='manifold')
parts.append(c)
asset = trimesh.util.concatenate(parts)
out = os.path.join(HERE, f"belt_temp_tower_{t_start}_{t_end}.stl")
asset.export(out)
dims = np.round(asset.bounds[1]-asset.bounds[0],1)
wt = all(p.is_watertight for p in parts)
print(f" {t_start}->{t_end}: {len(temps)} zones bbox={dims} watertight={wt} -> {os.path.basename(out)}")

View File

@@ -1,9 +1,13 @@
{
"name": "Custom Printer",
"version": "02.04.00.01",
"version": "02.04.00.04",
"force_update": "0",
"description": "My configurations",
"machine_model_list": [
{
"name": "Generic Belt Printer",
"sub_path": "machine/MyBeltPrinter.json"
},
{
"name": "Generic Klipper Printer",
"sub_path": "machine/MyKlipper.json"
@@ -62,6 +66,14 @@
"name": "0.16mm Optimal @MyKlipper",
"sub_path": "process/0.16mm Optimal @MyKlipper.json"
},
{
"name": "0.12mm Fine @MyBeltPrinter",
"sub_path": "process/0.12mm Fine @MyBeltPrinter.json"
},
{
"name": "0.20mm Standard @MyBeltPrinter",
"sub_path": "process/0.20mm Standard @MyBeltPrinter.json"
},
{
"name": "0.20mm Standard @MyKlipper",
"sub_path": "process/0.20mm Standard @MyKlipper.json"
@@ -262,18 +274,38 @@
"name": "MyKlipper 0.8 nozzle",
"sub_path": "machine/MyKlipper 0.8 nozzle.json"
},
{
"name": "fdm_belt_common",
"sub_path": "machine/fdm_belt_common.json"
},
{
"name": "fdm_toolchanger_common",
"sub_path": "machine/fdm_toolchanger_common.json"
},
{
"name": "MyRepetier 0.4 nozzle",
"sub_path": "machine/MyRepetier 0.4 nozzle.json"
},
{
"name": "MyRRF 0.4 nozzle",
"sub_path": "machine/MyRRF 0.4 nozzle.json"
},
{
"name": "MyBeltPrinter 0.2 nozzle",
"sub_path": "machine/MyBeltPrinter 0.2 nozzle.json"
},
{
"name": "MyBeltPrinter 0.4 nozzle",
"sub_path": "machine/MyBeltPrinter 0.4 nozzle.json"
},
{
"name": "MyBeltPrinter 0.6 nozzle",
"sub_path": "machine/MyBeltPrinter 0.6 nozzle.json"
},
{
"name": "MyBeltPrinter 0.8 nozzle",
"sub_path": "machine/MyBeltPrinter 0.8 nozzle.json"
},
{
"name": "MyRepetier 0.4 nozzle",
"sub_path": "machine/MyRepetier 0.4 nozzle.json"
},
{
"name": "MyToolChanger 0.2 nozzle",
"sub_path": "machine/MyToolChanger 0.2 nozzle.json"

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,27 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.2 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "3w1uyJdmm14QhDnH",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"default_print_profile": "0.12mm Fine @MyBeltPrinter",
"nozzle_diameter": [
"0.2"
],
"max_layer_height": [
"0.16"
],
"min_layer_height": [
"0.04"
],
"printer_variant": "0.2",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.4 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "6nRHUtvJOUffocbu",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.4"
],
"printer_variant": "0.4",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,26 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.6 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "K0m9HbUNwKT4UCJV",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.6"
],
"max_layer_height": [
"0.4"
],
"min_layer_height": [
"0.12"
],
"printer_variant": "0.6",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,26 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.8 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "rHAweDz4eNwttPNA",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.8"
],
"max_layer_height": [
"0.6"
],
"min_layer_height": [
"0.2"
],
"printer_variant": "0.8",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,12 @@
{
"type": "machine_model",
"name": "Generic Belt Printer",
"model_id": "my_belt_01",
"nozzle_diameter": "0.4;0.2;0.6;0.8",
"machine_tech": "FFF",
"family": "MyPrinter",
"bed_model": "Custom_350_bed.stl",
"bed_texture": "orcaslicer_bed_texture.svg",
"hotend_model": "",
"default_materials": "Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System"
}

View File

@@ -0,0 +1,99 @@
{
"type": "machine",
"name": "fdm_belt_common",
"inherits": "fdm_klipper_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "klipper",
"single_extruder_multi_material": "0",
"default_filament_profile": [
"Generic PLA @System"
],
"default_print_profile": "0.20mm Standard @MyBeltPrinter",
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"deretraction_speed": [
"30"
],
"extruder_colour": [
"#FCE94F"
],
"extruder_offset": [
"0x0"
],
"long_retractions_when_cut": [
"0"
],
"nozzle_diameter": [
"0.4"
],
"retract_before_wipe": [
"70%"
],
"retract_length_toolchange": [
"2"
],
"retract_lift_above": [
"0"
],
"retract_lift_below": [
"0"
],
"retract_lift_enforce": [
"All Surfaces"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retract_when_changing_layer": [
"1"
],
"retraction_distances_when_cut": [
"18"
],
"retraction_length": [
"0.8"
],
"retraction_minimum_travel": [
"1"
],
"retraction_speed": [
"30"
],
"travel_slope": [
"3"
],
"wipe": [
"1"
],
"wipe_distance": [
"1"
],
"z_hop": [
"0.4"
],
"z_hop_types": [
"Normal Lift"
],
"gcode_remap_x": "rev_x",
"gcode_remap_y": "pos_z",
"gcode_remap_z": "pos_y",
"printer_extruder_id": [
"1"
],
"belt_printer": "1",
"belt_slice_rotation": "x",
"belt_slice_rotation_angle": "45",
"belt_slice_rotation_global": "1",
"build_plate_tilt_x": "45",
"purge_in_prime_tower": "0",
"scan_first_layer": "0",
"auxiliary_fan": "0"
}

View File

@@ -0,0 +1,20 @@
{
"type": "process",
"name": "0.12mm Fine @MyBeltPrinter",
"inherits": "fdm_process_klipper_common",
"from": "system",
"setting_id": "EugqqdLJ423bgEwN",
"instantiation": "true",
"layer_height": "0.12",
"initial_layer_print_height": "0.12",
"bottom_shell_layers": "5",
"top_shell_layers": "6",
"support_top_z_distance": "0.08",
"support_bottom_z_distance": "0.08",
"skirt_loops": "0",
"skirt_distance": "0",
"compatible_printers": [
"MyBeltPrinter 0.2 nozzle",
"MyBeltPrinter 0.4 nozzle"
]
}

View File

@@ -0,0 +1,17 @@
{
"type": "process",
"name": "0.20mm Standard @MyBeltPrinter",
"inherits": "fdm_process_klipper_common",
"from": "system",
"setting_id": "YzCDAgH3uLOM53pF",
"instantiation": "true",
"layer_height": "0.2",
"initial_layer_print_height": "0.2",
"skirt_loops": "0",
"skirt_distance": "0",
"compatible_printers": [
"MyBeltPrinter 0.4 nozzle",
"MyBeltPrinter 0.6 nozzle",
"MyBeltPrinter 0.8 nozzle"
]
}

View File

@@ -0,0 +1,54 @@
{
"name": "IdeaFormer",
"version": "02.00.00.03",
"force_update": "0",
"description": "IdeaFormer belt printer configurations",
"machine_model_list": [
{
"name": "IdeaFormer IR3 V2",
"sub_path": "machine/IdeaFormer IR3 V2.json"
}
],
"process_list": [
{
"name": "fdm_process_common",
"sub_path": "process/fdm_process_common.json"
},
{
"name": "0.20mm Standard @IdeaFormer IR3 V2",
"sub_path": "process/0.20mm Standard @IdeaFormer IR3 V2.json"
}
],
"filament_list": [
{
"name": "Generic PLA @IdeaFormer IR3 V2",
"sub_path": "filament/Generic PLA @IdeaFormer IR3 V2.json"
},
{
"name": "eSUN PLA @IdeaFormer IR3 V2",
"sub_path": "filament/eSUN PLA @IdeaFormer IR3 V2.json"
},
{
"name": "Generic PETG @IdeaFormer IR3 V2",
"sub_path": "filament/Generic PETG @IdeaFormer IR3 V2.json"
}
],
"machine_list": [
{
"name": "fdm_machine_common",
"sub_path": "machine/fdm_machine_common.json"
},
{
"name": "fdm_klipper_common",
"sub_path": "machine/fdm_klipper_common.json"
},
{
"name": "fdm_belt_common",
"sub_path": "machine/fdm_belt_common.json"
},
{
"name": "IdeaFormer IR3 V2 0.4 nozzle",
"sub_path": "machine/IdeaFormer IR3 V2 0.4 nozzle.json"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

View File

@@ -0,0 +1,113 @@
{
"type": "filament",
"name": "Generic PETG @IdeaFormer IR3 V2",
"inherits": "Generic PETG @System",
"from": "system",
"setting_id": "n4zaXcUUzTqAxq5f",
"instantiation": "true",
"compatible_printers": [
"IdeaFormer IR3 V2 0.4 nozzle"
],
"filament_type": [
"PETG"
],
"filament_vendor": [
"Generic"
],
"filament_settings_id": [
"Generic PETG @IdeaFormer IR3 V2"
],
"filament_diameter": [
"1.75"
],
"filament_density": [
"1.27"
],
"filament_flow_ratio": [
"0.95"
],
"filament_cost": [
"25"
],
"filament_max_volumetric_speed": [
"10"
],
"nozzle_temperature": [
"240"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature_range_low": [
"220"
],
"nozzle_temperature_range_high": [
"260"
],
"temperature_vitrification": [
"70"
],
"hot_plate_temp": [
"80"
],
"hot_plate_temp_initial_layer": [
"80"
],
"cool_plate_temp": [
"80"
],
"cool_plate_temp_initial_layer": [
"80"
],
"textured_plate_temp": [
"80"
],
"textured_plate_temp_initial_layer": [
"80"
],
"fan_min_speed": [
"40"
],
"fan_max_speed": [
"60"
],
"overhang_fan_threshold": [
"25%"
],
"overhang_fan_speed": [
"80"
],
"close_fan_the_first_x_layers": [
"3"
],
"full_fan_speed_layer": [
"8"
],
"slow_down_min_speed": [
"20"
],
"slow_down_layer_time": [
"4"
],
"fan_cooling_layer_time": [
"100"
],
"reduce_fan_stop_start_freq": [
"1"
],
"filament_retraction_length": [
"2"
],
"filament_retraction_speed": [
"40"
],
"filament_deretraction_speed": [
"40"
],
"filament_z_hop": [
"0.4"
],
"filament_start_gcode": [
"; Generic PETG @IdeaFormer IR3 V2 — belt PETG, bed 80C"
]
}

View File

@@ -0,0 +1,113 @@
{
"type": "filament",
"name": "Generic PLA @IdeaFormer IR3 V2",
"inherits": "Generic PLA @System",
"from": "system",
"setting_id": "1xjycsEAFh6KQIhp",
"instantiation": "true",
"compatible_printers": [
"IdeaFormer IR3 V2 0.4 nozzle"
],
"filament_type": [
"PLA"
],
"filament_vendor": [
"Generic"
],
"filament_settings_id": [
"Generic PLA @IdeaFormer IR3 V2"
],
"filament_diameter": [
"1.75"
],
"filament_density": [
"1.24"
],
"filament_flow_ratio": [
"0.98"
],
"filament_cost": [
"20"
],
"filament_max_volumetric_speed": [
"12"
],
"nozzle_temperature": [
"215"
],
"nozzle_temperature_initial_layer": [
"220"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"240"
],
"temperature_vitrification": [
"45"
],
"hot_plate_temp": [
"75"
],
"hot_plate_temp_initial_layer": [
"75"
],
"cool_plate_temp": [
"75"
],
"cool_plate_temp_initial_layer": [
"75"
],
"textured_plate_temp": [
"75"
],
"textured_plate_temp_initial_layer": [
"75"
],
"fan_min_speed": [
"100"
],
"fan_max_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
],
"overhang_fan_speed": [
"100"
],
"close_fan_the_first_x_layers": [
"3"
],
"full_fan_speed_layer": [
"8"
],
"slow_down_min_speed": [
"20"
],
"slow_down_layer_time": [
"4"
],
"fan_cooling_layer_time": [
"100"
],
"reduce_fan_stop_start_freq": [
"1"
],
"filament_retraction_length": [
"1.5"
],
"filament_retraction_speed": [
"35"
],
"filament_deretraction_speed": [
"30"
],
"filament_z_hop": [
"0.4"
],
"filament_start_gcode": [
"; Generic PLA @IdeaFormer IR3 V2 — belt PLA, bed 75C"
]
}

View File

@@ -0,0 +1,35 @@
{
"type": "filament",
"name": "eSUN PLA @IdeaFormer IR3 V2",
"inherits": "Generic PLA @IdeaFormer IR3 V2",
"from": "system",
"setting_id": "XqkviBmFHEglXueX",
"instantiation": "true",
"compatible_printers": [
"IdeaFormer IR3 V2 0.4 nozzle"
],
"filament_type": [
"PLA"
],
"filament_vendor": [
"eSUN"
],
"filament_settings_id": [
"eSUN PLA @IdeaFormer IR3 V2"
],
"nozzle_temperature_initial_layer": [
"200"
],
"nozzle_temperature": [
"200"
],
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.12"
],
"filament_max_volumetric_speed": [
"20"
]
}

View File

@@ -0,0 +1,94 @@
{
"type": "machine",
"name": "IdeaFormer IR3 V2 0.4 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "MDQZgwRgg72lmjtu",
"instantiation": "true",
"printer_model": "IdeaFormer IR3 V2",
"printer_variant": "0.4",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"250x0",
"250x2000",
"0x2000"
],
"printable_height": "250",
"belt_printer_infinite_y": "1",
"thumbnails": [
"48x48/PNG",
"300x300/PNG"
],
"default_filament_profile": [
"Generic PLA @IdeaFormer IR3 V2"
],
"default_print_profile": "0.20mm Standard @IdeaFormer IR3 V2",
"use_relative_e_distances": "1",
"machine_max_acceleration_e": [
"5000"
],
"machine_max_acceleration_extruding": [
"5000"
],
"machine_max_acceleration_retracting": [
"1000"
],
"machine_max_acceleration_travel": [
"9000"
],
"machine_max_acceleration_x": [
"5000"
],
"machine_max_acceleration_y": [
"5000"
],
"machine_max_acceleration_z": [
"100"
],
"machine_max_jerk_e": [
"2.5"
],
"machine_max_jerk_x": [
"10"
],
"machine_max_jerk_y": [
"10"
],
"machine_max_jerk_z": [
"0.4"
],
"machine_max_speed_e": [
"60"
],
"machine_max_speed_x": [
"500"
],
"machine_max_speed_y": [
"500"
],
"machine_max_speed_z": [
"20"
],
"retraction_length": [
"2"
],
"retraction_speed": [
"40"
],
"deretraction_speed": [
"40"
],
"z_hop": [
"0.4"
],
"retract_lift_below": [
"300"
],
"machine_start_gcode": "; === IdeaFormer IR3 V2 Belt Printer Start ===\n; Axes: X=lateral, Y=gantry height (probe), Z=belt\nG90 ; absolute positioning\nM82 ; absolute extruder\nG21 ; millimeters\nG28 ; home all axes\nG1 Y20 F500 ; lift nozzle 20mm from belt\n; Bed + hotend temps come from the active filament profile. Belt PLA requires 75 C bed — use Generic/eSun PLA @IdeaFormer IR3 V2 filament presets to get it automatically.\nM140 S[hot_plate_temp_initial_layer] ; set bed temp\nM104 S[nozzle_temperature_initial_layer] ; hotend temp\nM109 S[nozzle_temperature_initial_layer] ; wait hotend\nM190 S[hot_plate_temp_initial_layer] ; wait bed\n; --- Purge blob ---\nG92 E0 ; zero extruder\nG1 Y.1 ; nozzle 0.1mm above belt\nG1 E15 F1000 ; purge 15mm blob\nG1 Z20 E25 F800 ; belt advance 20mm + extrude\nG1 E23 ; retract 2mm\nG28 Y ; re-probe belt surface\nG1 E25 ; de-retract\n; --- Prime lines (full 250mm bed width) ---\nFMS_on ; filament motion sensor\nG1 X250 E50 F2000 ; prime line 1\nG92 Z0 ; reset belt origin\nG1 Z.4 ; belt advance 0.4mm\nG1 X0 E75 ; prime line 2\nG1 F1000 ; default feedrate\nG92 E0 Z0 ; zero extruder + belt = print origin\n",
"machine_end_gcode": "; === IdeaFormer IR3 V2 Belt Printer End ===\nM400 ; wait for moves to finish\nM104 S0 ; heater off\nM140 S0 ; bed off\nG92 E0 ; zero extruder\nG1 E-5 F300 ; retract 5mm\nG4 P5000 ; wait for ooze\nG91 ; relative mode - keep every end move relative on a belt\nG1 Y20 F1000 ; raise gantry 20mm for clearance over the part\nG1 Z676 F3000 ; advance belt one full machine-depth to eject the part and clean the belt\nG90 ; back to absolute\nG28 X ; home X only - NEVER 'G28' all: that homes Z/belt and reverses the whole print back into the gantry\nFMS_off ; filament motion sensor off\nBED_MESH_CLEAR\nM84 ; disable motors\n",
"machine_pause_gcode": "PAUSE",
"layer_change_gcode": "G92 E0 ; belt: reset extruder at layer change (relative E)"
}

View File

@@ -0,0 +1,12 @@
{
"type": "machine_model",
"name": "IdeaFormer IR3 V2",
"model_id": "IdeaFormer_IR3_V2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "IdeaFormer",
"bed_model": "",
"bed_texture": "",
"hotend_model": "",
"default_materials": "Generic PLA @IdeaFormer IR3 V2;Generic PETG @IdeaFormer IR3 V2"
}

View File

@@ -0,0 +1,99 @@
{
"type": "machine",
"name": "fdm_belt_common",
"inherits": "fdm_klipper_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "klipper",
"single_extruder_multi_material": "0",
"default_filament_profile": [
"Generic PLA @System"
],
"default_print_profile": "0.20mm Standard @IdeaFormer IR3 V2",
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"deretraction_speed": [
"30"
],
"extruder_colour": [
"#FCE94F"
],
"extruder_offset": [
"0x0"
],
"long_retractions_when_cut": [
"0"
],
"nozzle_diameter": [
"0.4"
],
"retract_before_wipe": [
"70%"
],
"retract_length_toolchange": [
"2"
],
"retract_lift_above": [
"0"
],
"retract_lift_below": [
"0"
],
"retract_lift_enforce": [
"All Surfaces"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retract_when_changing_layer": [
"1"
],
"retraction_distances_when_cut": [
"18"
],
"retraction_length": [
"0.8"
],
"retraction_minimum_travel": [
"1"
],
"retraction_speed": [
"30"
],
"travel_slope": [
"3"
],
"wipe": [
"1"
],
"wipe_distance": [
"1"
],
"z_hop": [
"0.4"
],
"z_hop_types": [
"Normal Lift"
],
"gcode_remap_x": "rev_x",
"gcode_remap_y": "pos_z",
"gcode_remap_z": "pos_y",
"printer_extruder_id": [
"1"
],
"belt_printer": "1",
"belt_slice_rotation": "x",
"belt_slice_rotation_angle": "45",
"belt_slice_rotation_global": "1",
"build_plate_tilt_x": "45",
"purge_in_prime_tower": "0",
"scan_first_layer": "0",
"auxiliary_fan": "0"
}

View File

@@ -0,0 +1,141 @@
{
"type": "machine",
"name": "fdm_klipper_common",
"inherits": "fdm_machine_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "klipper",
"machine_max_acceleration_e": [
"5000",
"5000"
],
"machine_max_acceleration_extruding": [
"20000",
"20000"
],
"machine_max_acceleration_retracting": [
"5000",
"5000"
],
"machine_max_acceleration_travel": [
"20000",
"20000"
],
"machine_max_acceleration_x": [
"20000",
"20000"
],
"machine_max_acceleration_y": [
"20000",
"20000"
],
"machine_max_acceleration_z": [
"500",
"200"
],
"machine_max_speed_e": [
"25",
"25"
],
"machine_max_speed_x": [
"500",
"200"
],
"machine_max_speed_y": [
"500",
"200"
],
"machine_max_speed_z": [
"12",
"12"
],
"machine_max_jerk_e": [
"2.5",
"2.5"
],
"machine_max_jerk_x": [
"9",
"9"
],
"machine_max_jerk_y": [
"9",
"9"
],
"machine_max_jerk_z": [
"0.2",
"0.4"
],
"machine_min_extruding_rate": [
"0",
"0"
],
"machine_min_travel_rate": [
"0",
"0"
],
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"printable_height": "250",
"extruder_clearance_radius": "65",
"extruder_clearance_height_to_rod": "36",
"extruder_clearance_height_to_lid": "140",
"printer_settings_id": "",
"printer_technology": "FFF",
"printer_variant": "0.4",
"retraction_minimum_travel": [
"1"
],
"retract_before_wipe": [
"70%"
],
"retract_when_changing_layer": [
"1"
],
"retraction_length": [
"0.8"
],
"retract_length_toolchange": [
"2"
],
"z_hop": [
"0.4"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retraction_speed": [
"30"
],
"deretraction_speed": [
"30"
],
"z_hop_types": "Normal Lift",
"silent_mode": "0",
"single_extruder_multi_material": "1",
"change_filament_gcode": "",
"wipe": [
"1"
],
"default_filament_profile": [
"Generic PLA @System"
],
"default_print_profile": "0.20mm Standard @MyKlipper",
"bed_exclude_area": [
"0x0"
],
"machine_start_gcode": "M190 S[bed_temperature_initial_layer_single]\nM109 S[nozzle_temperature_initial_layer]\nPRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single]\n",
"machine_end_gcode": "PRINT_END",
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
"machine_pause_gcode": "PAUSE",
"scan_first_layer": "0",
"nozzle_type": "undefine",
"auxiliary_fan": "0"
}

View File

@@ -0,0 +1,119 @@
{
"type": "machine",
"name": "fdm_machine_common",
"from": "system",
"instantiation": "false",
"printer_technology": "FFF",
"deretraction_speed": [
"40"
],
"extruder_colour": [
"#FCE94F"
],
"extruder_offset": [
"0x0"
],
"gcode_flavor": "marlin",
"silent_mode": "0",
"machine_max_acceleration_e": [
"5000"
],
"machine_max_acceleration_extruding": [
"10000"
],
"machine_max_acceleration_retracting": [
"1000"
],
"machine_max_acceleration_x": [
"10000"
],
"machine_max_acceleration_y": [
"10000"
],
"machine_max_acceleration_z": [
"500"
],
"machine_max_speed_e": [
"60"
],
"machine_max_speed_x": [
"500"
],
"machine_max_speed_y": [
"500"
],
"machine_max_speed_z": [
"10"
],
"machine_max_jerk_e": [
"5"
],
"machine_max_jerk_x": [
"8"
],
"machine_max_jerk_y": [
"8"
],
"machine_max_jerk_z": [
"0.4"
],
"machine_min_extruding_rate": [
"0"
],
"machine_min_travel_rate": [
"0"
],
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"printable_height": "250",
"extruder_clearance_radius": "65",
"extruder_clearance_height_to_rod": "36",
"extruder_clearance_height_to_lid": "140",
"nozzle_diameter": [
"0.4"
],
"printer_settings_id": "",
"printer_variant": "0.4",
"retraction_minimum_travel": [
"2"
],
"retract_before_wipe": [
"70%"
],
"retract_when_changing_layer": [
"1"
],
"retraction_length": [
"1"
],
"retract_length_toolchange": [
"1"
],
"z_hop": [
"0"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retraction_speed": [
"60"
],
"single_extruder_multi_material": "1",
"change_filament_gcode": "",
"wipe": [
"1"
],
"default_print_profile": "",
"machine_start_gcode": "G0 Z20 F9000\nG92 E0; G1 E-10 F1200\nG28\nM970 Q1 A10 B10 C130 K0\nM970 Q1 A10 B131 C250 K1\nM974 Q1 S1 P0\nM970 Q0 A10 B10 C130 H20 K0\nM970 Q0 A10 B131 C250 K1\nM974 Q0 S1 P0\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nG29 ;Home\nG90;\nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S205;\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder \nG1 X110 Y110 Z2.0 F3000 ;Move Z Axis up",
"machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-4.0 F3600; retract \nG91\nG1 Z3;\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nG90 \nG0 X110 Y200 F3600 \nprint_end",
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
"machine_pause_gcode": "M601"
}

View File

@@ -0,0 +1,23 @@
{
"type": "process",
"name": "0.20mm Standard @IdeaFormer IR3 V2",
"inherits": "fdm_process_common",
"from": "system",
"setting_id": "91atcIwv5728phqX",
"instantiation": "true",
"layer_height": "0.2",
"initial_layer_print_height": "0.2",
"initial_layer_line_width": "0.42",
"wall_loops": "2",
"reduce_infill_retraction": "1",
"detect_overhang_wall": "1",
"skirt_loops": "0",
"skirt_distance": "0",
"sparse_infill_pattern": "grid",
"sparse_infill_speed": "200",
"support_base_pattern": "rectilinear",
"support_interface_pattern": "rectilinear",
"compatible_printers": [
"IdeaFormer IR3 V2 0.4 nozzle"
]
}

View File

@@ -0,0 +1,108 @@
{
"type": "process",
"name": "fdm_process_common",
"from": "system",
"instantiation": "false",
"adaptive_layer_height": "0",
"reduce_crossing_wall": "0",
"max_travel_detour_distance": "0",
"bottom_surface_pattern": "monotonic",
"bottom_shell_thickness": "0",
"bridge_speed": "50",
"brim_width": "5",
"brim_object_gap": "0.1",
"compatible_printers": [],
"compatible_printers_condition": "",
"print_sequence": "by layer",
"default_acceleration": "1000",
"initial_layer_acceleration": "500",
"top_surface_acceleration": "1000",
"travel_acceleration": "1000",
"inner_wall_acceleration": "1000",
"outer_wall_acceleration": "700",
"bridge_no_support": "0",
"draft_shield": "disabled",
"elefant_foot_compensation": "0",
"enable_arc_fitting": "0",
"wall_infill_order": "inner wall/outer wall/infill",
"infill_direction": "45",
"sparse_infill_density": "15%",
"sparse_infill_pattern": "crosshatch",
"initial_layer_print_height": "0.2",
"infill_combination": "0",
"infill_wall_overlap": "25%",
"interface_shells": "0",
"ironing_flow": "10%",
"ironing_spacing": "0.15",
"ironing_speed": "30",
"ironing_type": "no ironing",
"reduce_infill_retraction": "1",
"filename_format": "{input_filename_base}_{layer_height}mm_{filament_type[initial_tool]}_{printer_model}_{print_time}.gcode",
"detect_overhang_wall": "1",
"slowdown_for_curled_perimeters": "1",
"overhang_1_4_speed": "0",
"overhang_2_4_speed": "50",
"overhang_3_4_speed": "30",
"overhang_4_4_speed": "10",
"line_width": "110%",
"inner_wall_line_width": "110%",
"outer_wall_line_width": "100%",
"top_surface_line_width": "93.75%",
"sparse_infill_line_width": "110%",
"initial_layer_line_width": "120%",
"internal_solid_infill_line_width": "120%",
"support_line_width": "96%",
"wall_loops": "3",
"print_settings_id": "",
"raft_layers": "0",
"seam_position": "aligned",
"skirt_distance": "2",
"skirt_height": "3",
"min_skirt_length": "4",
"skirt_loops": "0",
"minimum_sparse_infill_area": "15",
"spiral_mode": "0",
"standby_temperature_delta": "-5",
"enable_support": "0",
"resolution": "0.012",
"support_type": "normal(auto)",
"support_on_build_plate_only": "0",
"support_top_z_distance": "0.2",
"support_bottom_z_distance": "0.2",
"support_filament": "0",
"support_interface_loop_pattern": "0",
"support_interface_filament": "0",
"support_interface_top_layers": "2",
"support_interface_bottom_layers": "2",
"support_interface_spacing": "0.5",
"support_interface_speed": "80",
"support_base_pattern": "default",
"support_base_pattern_spacing": "2.5",
"support_speed": "150",
"support_threshold_angle": "30",
"support_object_xy_distance": "0.35",
"tree_support_branch_angle": "30",
"tree_support_wall_count": "0",
"tree_support_with_infill": "0",
"detect_thin_wall": "0",
"top_surface_pattern": "monotonicline",
"top_shell_thickness": "0.8",
"enable_prime_tower": "1",
"wipe_tower_no_sparse_layers": "0",
"prime_tower_width": "60",
"xy_hole_compensation": "0",
"xy_contour_compensation": "0",
"layer_height": "0.2",
"bottom_shell_layers": "3",
"top_shell_layers": "4",
"bridge_flow": "1",
"initial_layer_speed": "45",
"initial_layer_infill_speed": "45",
"outer_wall_speed": "45",
"inner_wall_speed": "80",
"sparse_infill_speed": "150",
"internal_solid_infill_speed": "150",
"top_surface_speed": "50",
"gap_infill_speed": "30",
"travel_speed": "200"
}

View File

@@ -0,0 +1,54 @@
{
"name": "Printcepts",
"version": "01.00.00.01",
"force_update": "0",
"description": "Printcepts belt printer configurations",
"machine_model_list": [
{
"name": "BabyBelt Pro",
"sub_path": "machine/BabyBelt Pro.json"
}
],
"process_list": [
{
"name": "fdm_process_common",
"sub_path": "process/fdm_process_common.json"
},
{
"name": "0.20mm Standard @BabyBelt Pro",
"sub_path": "process/0.20mm Standard @BabyBelt Pro.json"
}
],
"filament_list": [
{
"name": "Generic PLA @BabyBelt Pro",
"sub_path": "filament/Generic PLA @BabyBelt Pro.json"
},
{
"name": "eSUN PLA @BabyBelt Pro",
"sub_path": "filament/eSUN PLA @BabyBelt Pro.json"
},
{
"name": "Generic PETG @BabyBelt Pro",
"sub_path": "filament/Generic PETG @BabyBelt Pro.json"
}
],
"machine_list": [
{
"name": "fdm_machine_common",
"sub_path": "machine/fdm_machine_common.json"
},
{
"name": "fdm_klipper_common",
"sub_path": "machine/fdm_klipper_common.json"
},
{
"name": "fdm_belt_common",
"sub_path": "machine/fdm_belt_common.json"
},
{
"name": "BabyBelt Pro 0.4 nozzle",
"sub_path": "machine/BabyBelt Pro 0.4 nozzle.json"
}
]
}

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="95.0mm" height="500.0mm" viewBox="0 0 95.0 500.0" preserveAspectRatio="xMidYMid meet">
<!-- Printcepts BabyBelt Pro bed texture: 95 x 500 mm belt plate. -->
<!-- Transparent plate; green (#195F30) BabyBelt Pro logo centered along X, near the bottom edge. -->
<rect x="0" y="0" width="95.0" height="500.0" fill="none"/>
<g transform="translate(14.2500,436.3488) scale(0.067538)">
<g transform="translate(-11.000000,692.938562) scale(0.100000,-0.100000)"
fill="#195F30" stroke="none">
<path d="M1963 5604 l-1423 -1324 0 -2050 0 -2050 443 0 c244 0 741 3 1105 7
l662 6 0 746 c-1 575 -4 768 -14 841 -47 324 -179 486 -473 581 -40 12 -73 26
-73 30 0 4 32 17 72 29 212 64 333 166 378 320 35 121 38 191 32 868 l-5 662
-629 0 c-395 0 -628 4 -628 10 0 5 635 601 1410 1325 776 724 1410 1318 1410
1321 0 2 -190 4 -422 3 l-423 0 -1422 -1325z m-334 -2029 c143 -16 174 -96
173 -446 -2 -411 -24 -458 -224 -462 l-93 -2 -3 450 c-1 248 0 456 3 463 3 9
18 12 47 8 24 -3 67 -8 97 -11z m-4 -1556 c160 -29 173 -62 182 -469 9 -455
-14 -593 -108 -641 -39 -19 -193 -44 -210 -33 -10 6 -13 1147 -3 1157 6 6 45
2 139 -14z"/>
<path d="M3464 5979 c-142 -132 -263 -245 -268 -250 -6 -5 69 -9 190 -9 l199
1 268 249 267 250 -198 0 -198 0 -260 -241z"/>
<path d="M3650 5649 c-135 -126 -254 -238 -265 -249 -19 -20 -18 -20 177 -20
l197 0 228 211 c125 116 246 229 268 250 l40 39 -200 -1 -200 0 -245 -230z"/>
<path d="M2537 5089 c-101 -24 -204 -105 -251 -197 -96 -190 -19 -420 172
-514 l67 -33 2670 0 2670 0 57 27 c74 34 146 107 184 183 43 88 43 230 0 322
-35 76 -113 153 -193 191 l-58 27 -2640 2 c-1513 0 -2656 -3 -2678 -8z m5063
-77 c-57 -37 -118 -111 -140 -168 -31 -82 -25 -206 12 -279 26 -49 93 -121
133 -143 15 -8 -640 -11 -2410 -11 l-2430 0 30 21 c200 146 201 425 1 569
l-39 29 2434 -1 c2263 0 2432 -1 2409 -17z m-4890 -43 c270 -122 185 -526
-109 -522 -257 2 -370 324 -170 485 74 60 194 76 279 37z m5201 -12 c94 -55
140 -135 140 -242 0 -285 -393 -374 -517 -117 -26 54 -30 162 -9 219 28 74 97
139 173 164 53 17 166 4 213 -24z"/>
<path d="M2917 3973 c-4 -174 -7 -550 -7 -835 l0 -518 326 0 326 0 -7 150 -7
150 110 0 110 0 11 -32 c5 -18 26 -86 46 -150 l36 -118 325 0 c179 0 323 4
320 9 -3 4 -155 374 -337 822 -182 448 -333 820 -336 827 -4 9 -105 12 -457
12 l-453 0 -6 -317z m773 -745 c0 -5 -47 -8 -104 -8 l-103 0 -7 92 c-3 50 -6
202 -5 337 l1 246 109 -330 c60 -181 109 -333 109 -337z"/>
<path d="M4680 3455 l0 -835 448 0 c693 1 885 16 985 80 99 63 126 132 134
340 12 327 -44 405 -342 476 -28 7 -27 8 25 19 199 42 255 95 267 248 11 146
-32 285 -110 353 -145 126 -329 153 -1049 154 l-358 0 0 -835z m846 520 c36
-23 44 -54 44 -162 0 -152 -29 -183 -170 -183 l-40 0 0 186 0 187 71 -6 c39
-3 82 -13 95 -22z m4 -625 c33 -18 40 -52 40 -208 0 -200 -9 -214 -143 -228
l-67 -7 0 233 0 233 74 -6 c41 -3 84 -10 96 -17z"/>
<path d="M6150 4286 c0 -3 131 -242 290 -531 l290 -526 0 -304 0 -305 385 0
385 0 0 299 0 299 305 533 305 534 -377 3 c-207 1 -381 -2 -385 -6 -16 -16
-110 -258 -172 -444 l-62 -187 -18 77 c-18 75 -139 450 -171 525 l-15 37 -380
0 c-209 0 -380 -2 -380 -4z"/>
<path d="M2910 1355 l0 -1185 830 0 830 0 0 240 0 240 -350 0 -350 0 0 255 0
255 300 0 300 0 0 230 0 230 -300 0 -300 0 0 220 0 220 320 0 320 0 0 240 0
240 -800 0 -800 0 0 -1185z"/>
<path d="M4680 1355 l0 -1185 775 0 775 0 0 240 0 240 -295 0 -295 0 0 945 0
945 -480 0 -480 0 0 -1185z"/>
<path d="M5800 2300 l0 -240 280 0 280 0 0 -945 0 -945 480 0 480 0 0 945 0
945 285 0 285 0 0 240 0 240 -1045 0 -1045 0 0 -240z"/>
<path d="M8032 1358 l-2 -1188 1008 1 c621 1 971 5 912 10 -309 27 -631 139
-885 306 -593 391 -984 1122 -1025 1918 -4 77 -8 -394 -8 -1047z"/>
<path d="M7441 1934 c-43 -36 -59 -70 -70 -148 -18 -124 16 -252 76 -291 32
-21 226 -33 328 -20 114 14 161 97 153 269 -5 96 -24 151 -68 191 -20 18 -39
20 -205 23 l-182 3 -32 -27z m389 -199 c7 -8 10 -22 6 -30 -4 -13 -34 -15
-186 -15 -189 0 -202 3 -186 45 8 22 348 22 366 0z"/>
<path d="M7450 1267 c-14 -6 -35 -32 -47 -57 -21 -41 -23 -58 -23 -222 l0
-178 270 0 270 0 0 105 0 105 -121 0 -120 0 3 28 3 27 118 3 117 3 0 99 0 100
-113 0 c-121 0 -138 -7 -162 -65 -8 -19 -9 -19 -12 2 -10 55 -116 84 -183 50z
m134 -203 c15 -38 8 -44 -54 -44 -62 0 -69 6 -54 44 9 23 99 23 108 0z"/>
<path d="M466 1193 l-29 -43 -163 0 -164 0 0 -235 0 -235 165 0 165 0 27 -42
28 -42 3 163 c1 89 1 233 0 319 l-3 157 -29 -42z"/>
<path d="M7443 620 c-48 -20 -58 -60 -61 -262 l-4 -188 271 0 271 0 0 110 0
110 -110 0 -110 0 0 70 c0 76 -21 145 -51 160 -22 12 -176 12 -206 0z m161
-186 c15 -39 8 -44 -64 -44 -72 0 -79 5 -64 44 9 23 119 23 128 0z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,113 @@
{
"type": "filament",
"name": "Generic PETG @BabyBelt Pro",
"inherits": "Generic PETG @System",
"from": "system",
"setting_id": "gCzHpDNgVwQR6tgk",
"instantiation": "true",
"compatible_printers": [
"BabyBelt Pro 0.4 nozzle"
],
"filament_type": [
"PETG"
],
"filament_vendor": [
"Generic"
],
"filament_settings_id": [
"Generic PETG @BabyBelt Pro"
],
"filament_diameter": [
"1.75"
],
"filament_density": [
"1.27"
],
"filament_flow_ratio": [
"0.95"
],
"filament_cost": [
"25"
],
"filament_max_volumetric_speed": [
"10"
],
"nozzle_temperature": [
"240"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature_range_low": [
"220"
],
"nozzle_temperature_range_high": [
"260"
],
"temperature_vitrification": [
"70"
],
"hot_plate_temp": [
"80"
],
"hot_plate_temp_initial_layer": [
"80"
],
"cool_plate_temp": [
"80"
],
"cool_plate_temp_initial_layer": [
"80"
],
"textured_plate_temp": [
"80"
],
"textured_plate_temp_initial_layer": [
"80"
],
"fan_min_speed": [
"40"
],
"fan_max_speed": [
"60"
],
"overhang_fan_threshold": [
"25%"
],
"overhang_fan_speed": [
"80"
],
"close_fan_the_first_x_layers": [
"3"
],
"full_fan_speed_layer": [
"8"
],
"slow_down_min_speed": [
"20"
],
"slow_down_layer_time": [
"4"
],
"fan_cooling_layer_time": [
"100"
],
"reduce_fan_stop_start_freq": [
"1"
],
"filament_retraction_length": [
"2"
],
"filament_retraction_speed": [
"40"
],
"filament_deretraction_speed": [
"40"
],
"filament_z_hop": [
"0.4"
],
"filament_start_gcode": [
"; Generic PETG @BabyBelt Pro — belt PETG, bed 80C"
]
}

View File

@@ -0,0 +1,113 @@
{
"type": "filament",
"name": "Generic PLA @BabyBelt Pro",
"inherits": "Generic PLA @System",
"from": "system",
"setting_id": "24PpcnhVx9v5f4fD",
"instantiation": "true",
"compatible_printers": [
"BabyBelt Pro 0.4 nozzle"
],
"filament_type": [
"PLA"
],
"filament_vendor": [
"Generic"
],
"filament_settings_id": [
"Generic PLA @BabyBelt Pro"
],
"filament_diameter": [
"1.75"
],
"filament_density": [
"1.24"
],
"filament_flow_ratio": [
"0.98"
],
"filament_cost": [
"20"
],
"filament_max_volumetric_speed": [
"12"
],
"nozzle_temperature": [
"215"
],
"nozzle_temperature_initial_layer": [
"220"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"240"
],
"temperature_vitrification": [
"45"
],
"hot_plate_temp": [
"75"
],
"hot_plate_temp_initial_layer": [
"75"
],
"cool_plate_temp": [
"75"
],
"cool_plate_temp_initial_layer": [
"75"
],
"textured_plate_temp": [
"75"
],
"textured_plate_temp_initial_layer": [
"75"
],
"fan_min_speed": [
"100"
],
"fan_max_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
],
"overhang_fan_speed": [
"100"
],
"close_fan_the_first_x_layers": [
"3"
],
"full_fan_speed_layer": [
"8"
],
"slow_down_min_speed": [
"20"
],
"slow_down_layer_time": [
"4"
],
"fan_cooling_layer_time": [
"100"
],
"reduce_fan_stop_start_freq": [
"1"
],
"filament_retraction_length": [
"1.5"
],
"filament_retraction_speed": [
"35"
],
"filament_deretraction_speed": [
"30"
],
"filament_z_hop": [
"0.4"
],
"filament_start_gcode": [
"; Generic PLA @BabyBelt Pro — belt PLA, bed 75C"
]
}

View File

@@ -0,0 +1,35 @@
{
"type": "filament",
"name": "eSUN PLA @BabyBelt Pro",
"inherits": "Generic PLA @BabyBelt Pro",
"from": "system",
"setting_id": "EH3X7oE0DU5tSpjW",
"instantiation": "true",
"compatible_printers": [
"BabyBelt Pro 0.4 nozzle"
],
"filament_type": [
"PLA"
],
"filament_vendor": [
"eSUN"
],
"filament_settings_id": [
"eSUN PLA @BabyBelt Pro"
],
"nozzle_temperature_initial_layer": [
"200"
],
"nozzle_temperature": [
"200"
],
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.12"
],
"filament_max_volumetric_speed": [
"20"
]
}

View File

@@ -0,0 +1,87 @@
{
"type": "machine",
"name": "BabyBelt Pro 0.4 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "34OWINlJpJgA9DwQ",
"instantiation": "true",
"printer_model": "BabyBelt Pro",
"printer_variant": "0.4",
"nozzle_diameter": [
"0.4"
],
"default_filament_profile": [
"Generic PLA @BabyBelt Pro"
],
"default_print_profile": "0.20mm Standard @BabyBelt Pro",
"printable_area": [
"0x0",
"95x0",
"95x500",
"0x500"
],
"printable_height": "100",
"best_object_pos": "0.5,0.05",
"nozzle_type": [
"hardened_steel"
],
"printer_extruder_id": [
"1"
],
"printer_extruder_variant": [
"Direct Drive Standard"
],
"thumbnails": [
"48x48/PNG",
"300x300/PNG"
],
"machine_max_acceleration_e": [
"500",
"5000"
],
"machine_max_acceleration_extruding": [
"500",
"20000"
],
"machine_max_acceleration_retracting": [
"500",
"5000"
],
"machine_max_acceleration_x": [
"500",
"20000"
],
"machine_max_acceleration_y": [
"500",
"20000"
],
"machine_max_junction_deviation": [
"0.01"
],
"machine_max_speed_x": [
"50",
"200"
],
"machine_max_speed_y": [
"50",
"200"
],
"machine_max_speed_z": [
"5",
"12"
],
"retraction_length": [
"1.5"
],
"retraction_speed": [
"20"
],
"deretraction_speed": [
"25"
],
"retract_lift_enforce": [
"Top and Bottom"
],
"support_chamber_temp_control": "0",
"machine_start_gcode": ";Start GCode\nPRINT_START ANGLE=[belt_slice_rotation_angle] EXTRUDER=[nozzle_temperature_initial_layer] BED=[hot_plate_temp_initial_layer] MATERIAL=[filament_type]\n"
}

View File

@@ -0,0 +1,12 @@
{
"type": "machine_model",
"name": "BabyBelt Pro",
"model_id": "Printcepts_BabyBelt_Pro",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Printcepts",
"bed_model": "",
"bed_texture": "BabyBelt Pro_bed_texture.svg",
"hotend_model": "",
"default_materials": "Generic PLA @BabyBelt Pro;Generic PETG @BabyBelt Pro"
}

View File

@@ -0,0 +1,99 @@
{
"type": "machine",
"name": "fdm_belt_common",
"inherits": "fdm_klipper_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "klipper",
"single_extruder_multi_material": "0",
"default_filament_profile": [
"Generic PLA @System"
],
"default_print_profile": "0.20mm Standard @BabyBelt Pro",
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"deretraction_speed": [
"30"
],
"extruder_colour": [
"#FCE94F"
],
"extruder_offset": [
"0x0"
],
"long_retractions_when_cut": [
"0"
],
"nozzle_diameter": [
"0.4"
],
"retract_before_wipe": [
"70%"
],
"retract_length_toolchange": [
"2"
],
"retract_lift_above": [
"0"
],
"retract_lift_below": [
"0"
],
"retract_lift_enforce": [
"All Surfaces"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retract_when_changing_layer": [
"1"
],
"retraction_distances_when_cut": [
"18"
],
"retraction_length": [
"0.8"
],
"retraction_minimum_travel": [
"1"
],
"retraction_speed": [
"30"
],
"travel_slope": [
"3"
],
"wipe": [
"1"
],
"wipe_distance": [
"1"
],
"z_hop": [
"0.4"
],
"z_hop_types": [
"Normal Lift"
],
"gcode_remap_x": "rev_x",
"gcode_remap_y": "pos_z",
"gcode_remap_z": "pos_y",
"printer_extruder_id": [
"1"
],
"belt_printer": "1",
"belt_slice_rotation": "x",
"belt_slice_rotation_angle": "45",
"belt_slice_rotation_global": "1",
"build_plate_tilt_x": "45",
"purge_in_prime_tower": "0",
"scan_first_layer": "0",
"auxiliary_fan": "0"
}

View File

@@ -0,0 +1,141 @@
{
"type": "machine",
"name": "fdm_klipper_common",
"inherits": "fdm_machine_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "klipper",
"machine_max_acceleration_e": [
"5000",
"5000"
],
"machine_max_acceleration_extruding": [
"20000",
"20000"
],
"machine_max_acceleration_retracting": [
"5000",
"5000"
],
"machine_max_acceleration_travel": [
"20000",
"20000"
],
"machine_max_acceleration_x": [
"20000",
"20000"
],
"machine_max_acceleration_y": [
"20000",
"20000"
],
"machine_max_acceleration_z": [
"500",
"200"
],
"machine_max_speed_e": [
"25",
"25"
],
"machine_max_speed_x": [
"500",
"200"
],
"machine_max_speed_y": [
"500",
"200"
],
"machine_max_speed_z": [
"12",
"12"
],
"machine_max_jerk_e": [
"2.5",
"2.5"
],
"machine_max_jerk_x": [
"9",
"9"
],
"machine_max_jerk_y": [
"9",
"9"
],
"machine_max_jerk_z": [
"0.2",
"0.4"
],
"machine_min_extruding_rate": [
"0",
"0"
],
"machine_min_travel_rate": [
"0",
"0"
],
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"printable_height": "250",
"extruder_clearance_radius": "65",
"extruder_clearance_height_to_rod": "36",
"extruder_clearance_height_to_lid": "140",
"printer_settings_id": "",
"printer_technology": "FFF",
"printer_variant": "0.4",
"retraction_minimum_travel": [
"1"
],
"retract_before_wipe": [
"70%"
],
"retract_when_changing_layer": [
"1"
],
"retraction_length": [
"0.8"
],
"retract_length_toolchange": [
"2"
],
"z_hop": [
"0.4"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retraction_speed": [
"30"
],
"deretraction_speed": [
"30"
],
"z_hop_types": "Normal Lift",
"silent_mode": "0",
"single_extruder_multi_material": "1",
"change_filament_gcode": "",
"wipe": [
"1"
],
"default_filament_profile": [
"Generic PLA @System"
],
"default_print_profile": "0.20mm Standard @MyKlipper",
"bed_exclude_area": [
"0x0"
],
"machine_start_gcode": "M190 S[bed_temperature_initial_layer_single]\nM109 S[nozzle_temperature_initial_layer]\nPRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single]\n",
"machine_end_gcode": "PRINT_END",
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
"machine_pause_gcode": "PAUSE",
"scan_first_layer": "0",
"nozzle_type": "undefine",
"auxiliary_fan": "0"
}

View File

@@ -0,0 +1,119 @@
{
"type": "machine",
"name": "fdm_machine_common",
"from": "system",
"instantiation": "false",
"printer_technology": "FFF",
"deretraction_speed": [
"40"
],
"extruder_colour": [
"#FCE94F"
],
"extruder_offset": [
"0x0"
],
"gcode_flavor": "marlin",
"silent_mode": "0",
"machine_max_acceleration_e": [
"5000"
],
"machine_max_acceleration_extruding": [
"10000"
],
"machine_max_acceleration_retracting": [
"1000"
],
"machine_max_acceleration_x": [
"10000"
],
"machine_max_acceleration_y": [
"10000"
],
"machine_max_acceleration_z": [
"500"
],
"machine_max_speed_e": [
"60"
],
"machine_max_speed_x": [
"500"
],
"machine_max_speed_y": [
"500"
],
"machine_max_speed_z": [
"10"
],
"machine_max_jerk_e": [
"5"
],
"machine_max_jerk_x": [
"8"
],
"machine_max_jerk_y": [
"8"
],
"machine_max_jerk_z": [
"0.4"
],
"machine_min_extruding_rate": [
"0"
],
"machine_min_travel_rate": [
"0"
],
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"printable_height": "250",
"extruder_clearance_radius": "65",
"extruder_clearance_height_to_rod": "36",
"extruder_clearance_height_to_lid": "140",
"nozzle_diameter": [
"0.4"
],
"printer_settings_id": "",
"printer_variant": "0.4",
"retraction_minimum_travel": [
"2"
],
"retract_before_wipe": [
"70%"
],
"retract_when_changing_layer": [
"1"
],
"retraction_length": [
"1"
],
"retract_length_toolchange": [
"1"
],
"z_hop": [
"0"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retraction_speed": [
"60"
],
"single_extruder_multi_material": "1",
"change_filament_gcode": "",
"wipe": [
"1"
],
"default_print_profile": "",
"machine_start_gcode": "G0 Z20 F9000\nG92 E0; G1 E-10 F1200\nG28\nM970 Q1 A10 B10 C130 K0\nM970 Q1 A10 B131 C250 K1\nM974 Q1 S1 P0\nM970 Q0 A10 B10 C130 H20 K0\nM970 Q0 A10 B131 C250 K1\nM974 Q0 S1 P0\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nG29 ;Home\nG90;\nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S205;\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder \nG1 X110 Y110 Z2.0 F3000 ;Move Z Axis up",
"machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-4.0 F3600; retract \nG91\nG1 Z3;\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nG90 \nG0 X110 Y200 F3600 \nprint_end",
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
"machine_pause_gcode": "M601"
}

View File

@@ -0,0 +1,23 @@
{
"type": "process",
"name": "0.20mm Standard @BabyBelt Pro",
"inherits": "fdm_process_common",
"from": "system",
"setting_id": "JGfGtqX6CWjCt437",
"instantiation": "true",
"layer_height": "0.2",
"initial_layer_print_height": "0.2",
"initial_layer_line_width": "0.42",
"wall_loops": "2",
"reduce_infill_retraction": "1",
"detect_overhang_wall": "1",
"skirt_loops": "0",
"skirt_distance": "0",
"sparse_infill_pattern": "grid",
"sparse_infill_speed": "200",
"support_base_pattern": "rectilinear",
"support_interface_pattern": "rectilinear",
"compatible_printers": [
"BabyBelt Pro 0.4 nozzle"
]
}

View File

@@ -0,0 +1,108 @@
{
"type": "process",
"name": "fdm_process_common",
"from": "system",
"instantiation": "false",
"adaptive_layer_height": "0",
"reduce_crossing_wall": "0",
"max_travel_detour_distance": "0",
"bottom_surface_pattern": "monotonic",
"bottom_shell_thickness": "0",
"bridge_speed": "50",
"brim_width": "5",
"brim_object_gap": "0.1",
"compatible_printers": [],
"compatible_printers_condition": "",
"print_sequence": "by layer",
"default_acceleration": "1000",
"initial_layer_acceleration": "500",
"top_surface_acceleration": "1000",
"travel_acceleration": "1000",
"inner_wall_acceleration": "1000",
"outer_wall_acceleration": "700",
"bridge_no_support": "0",
"draft_shield": "disabled",
"elefant_foot_compensation": "0",
"enable_arc_fitting": "0",
"wall_infill_order": "inner wall/outer wall/infill",
"infill_direction": "45",
"sparse_infill_density": "15%",
"sparse_infill_pattern": "crosshatch",
"initial_layer_print_height": "0.2",
"infill_combination": "0",
"infill_wall_overlap": "25%",
"interface_shells": "0",
"ironing_flow": "10%",
"ironing_spacing": "0.15",
"ironing_speed": "30",
"ironing_type": "no ironing",
"reduce_infill_retraction": "1",
"filename_format": "{input_filename_base}_{layer_height}mm_{filament_type[initial_tool]}_{printer_model}_{print_time}.gcode",
"detect_overhang_wall": "1",
"slowdown_for_curled_perimeters": "1",
"overhang_1_4_speed": "0",
"overhang_2_4_speed": "50",
"overhang_3_4_speed": "30",
"overhang_4_4_speed": "10",
"line_width": "110%",
"inner_wall_line_width": "110%",
"outer_wall_line_width": "100%",
"top_surface_line_width": "93.75%",
"sparse_infill_line_width": "110%",
"initial_layer_line_width": "120%",
"internal_solid_infill_line_width": "120%",
"support_line_width": "96%",
"wall_loops": "3",
"print_settings_id": "",
"raft_layers": "0",
"seam_position": "aligned",
"skirt_distance": "2",
"skirt_height": "3",
"min_skirt_length": "4",
"skirt_loops": "0",
"minimum_sparse_infill_area": "15",
"spiral_mode": "0",
"standby_temperature_delta": "-5",
"enable_support": "0",
"resolution": "0.012",
"support_type": "normal(auto)",
"support_on_build_plate_only": "0",
"support_top_z_distance": "0.2",
"support_bottom_z_distance": "0.2",
"support_filament": "0",
"support_interface_loop_pattern": "0",
"support_interface_filament": "0",
"support_interface_top_layers": "2",
"support_interface_bottom_layers": "2",
"support_interface_spacing": "0.5",
"support_interface_speed": "80",
"support_base_pattern": "default",
"support_base_pattern_spacing": "2.5",
"support_speed": "150",
"support_threshold_angle": "30",
"support_object_xy_distance": "0.35",
"tree_support_branch_angle": "30",
"tree_support_wall_count": "0",
"tree_support_with_infill": "0",
"detect_thin_wall": "0",
"top_surface_pattern": "monotonicline",
"top_shell_thickness": "0.8",
"enable_prime_tower": "1",
"wipe_tower_no_sparse_layers": "0",
"prime_tower_width": "60",
"xy_hole_compensation": "0",
"xy_contour_compensation": "0",
"layer_height": "0.2",
"bottom_shell_layers": "3",
"top_shell_layers": "4",
"bridge_flow": "1",
"initial_layer_speed": "45",
"initial_layer_infill_speed": "45",
"outer_wall_speed": "45",
"inner_wall_speed": "80",
"sparse_infill_speed": "150",
"internal_solid_infill_speed": "150",
"top_surface_speed": "50",
"gap_infill_speed": "30",
"travel_speed": "200"
}

View File

@@ -26,6 +26,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform vec4 uniform_color;

View File

@@ -23,6 +23,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform mat4 view_model_matrix;
@@ -73,8 +74,8 @@ void main()
// Point in homogenous coordinates.
world_pos = volume_world_matrix * vec4(v_position, 1.0);
// z component of normal vector in world coordinate used for slope shading
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
// dot product of world normal with up direction, used for slope shading
world_normal_z = slope.actived ? dot(normalize(slope.volume_world_normal_matrix * v_normal), slope.up_direction) : 0.0;
gl_Position = projection_matrix * position;
if (is_outline) {

View File

@@ -37,6 +37,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform SlopeDetection slope;
@@ -85,7 +86,7 @@ void main()
color = LightBlue;
alpha = 1.0;
}
else if( transformed_normal.z < slope.normal_z - EPSILON)
else if( dot(transformed_normal, slope.up_direction) < slope.normal_z - EPSILON)
{
color = color * 0.5 + LightRed * 0.5;
alpha = 1.0;

View File

@@ -24,6 +24,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform SlopeDetection slope;
void main()

View File

@@ -26,6 +26,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform vec4 uniform_color;

View File

@@ -23,6 +23,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform mat4 view_model_matrix;
@@ -73,8 +74,8 @@ void main()
// Point in homogenous coordinates.
world_pos = volume_world_matrix * vec4(v_position, 1.0);
// z component of normal vector in world coordinate used for slope shading
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
// dot product of world normal with up direction, used for slope shading
world_normal_z = slope.actived ? dot(normalize(slope.volume_world_normal_matrix * v_normal), slope.up_direction) : 0.0;
gl_Position = projection_matrix * position;
if (is_outline) {

View File

@@ -37,6 +37,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform SlopeDetection slope;
@@ -87,7 +88,7 @@ void main()
color = LightBlue;
alpha = 1.0;
}
else if( transformed_normal.z < slope.normal_z - EPSILON)
else if( dot(transformed_normal, slope.up_direction) < slope.normal_z - EPSILON)
{
color = color * 0.5 + LightRed * 0.5;
alpha = 1.0;

View File

@@ -24,6 +24,7 @@ struct SlopeDetection
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
vec3 up_direction;
};
uniform SlopeDetection slope;
void main()

View File

@@ -602,15 +602,17 @@ function SourceLabel(source) {
return "Mine";
case "subscribed":
return "Subscribed";
case "orphaned":
return "Orphaned";
default:
return "Local";
}
}
// Shared Local/Subscribed/Mine pill, used both after the row name and in the info panel.
// Shared source pill, used both after the row name and in the info panel.
function SourceBadge(source) {
const normalized = String(source || "").toLowerCase();
const variant = (normalized === "mine" || normalized === "subscribed") ? normalized : "local";
const variant = (normalized === "mine" || normalized === "subscribed" || normalized === "orphaned") ? normalized : "local";
const badge = document.createElement("span");
badge.className = `plugin-source-badge source-${variant}`;
badge.textContent = SourceLabel(source);
@@ -654,7 +656,7 @@ function LabelCell(plugin, isExpanded = false, capabilityCount = 0, nameRanges =
const labelCell = document.createElement("span");
labelCell.className = "label-cell";
const hasCloudLink = plugin.source === "mine" || plugin.source === "subscribed";
const hasCloudLink = plugin.source === "mine" || plugin.source === "subscribed" || plugin.source === "orphaned";
const pluginLabelText = plugin.label || plugin.name || plugin.plugin_id || "";
const canExpand = capabilityCount > 0;
@@ -705,7 +707,7 @@ function LabelCell(plugin, isExpanded = false, capabilityCount = 0, nameRanges =
function SourceCell(plugin) {
const cell = document.createElement("span");
const normalized = String(plugin.source || "").toLowerCase();
const variant = (normalized === "mine" || normalized === "subscribed") ? normalized : "local";
const variant = (normalized === "mine" || normalized === "subscribed" || normalized === "orphaned") ? normalized : "local";
cell.className = `source-cell source-${variant}`;
const sourceLabel = document.createElement("span");
@@ -1233,7 +1235,7 @@ function RenderDescription(plugin) {
return;
}
const isCloud = plugin && (plugin.source === "mine" || plugin.source === "subscribed");
const isCloud = plugin && (plugin.source === "mine" || plugin.source === "subscribed" || plugin.source === "orphaned");
if (isCloud && String(plugin?.sharing_token || "")) {
node.appendChild(document.createTextNode("View on OrcaCloud "));
const link = document.createElement("a");
@@ -1370,6 +1372,13 @@ function RenderDetailSummary(container, plugin) {
message.textContent = errorText || StatusDescription(plugin);
container.appendChild(message);
if (plugin.orphaned === true) {
const warning = document.createElement("div");
warning.className = "detail-description detail-warning-text";
warning.textContent = "Orphaned: This plugin is no longer subscribed or available in OrcaCloud. The local copy remains installed and can still be used.";
container.appendChild(warning);
}
const updateStatus = GetUpdateStatus(plugin);
if (updateStatus === "update_available") {
const note = document.createElement("div");

View File

@@ -251,6 +251,11 @@ body.pane-resizing {
font-weight: 600;
}
.source-cell.source-orphaned {
color: var(--plugin-status-warn);
font-weight: 600;
}
.source-cell.source-local {
color: var(--plugin-source-neutral-text);
}
@@ -648,6 +653,10 @@ body.pane-resizing {
color: var(--plugin-status-danger);
}
.detail-warning-text {
color: var(--plugin-status-warn);
}
.detail-status-chip {
display: inline-flex;
align-items: center;
@@ -915,6 +924,11 @@ body.pane-resizing {
color: var(--plugin-source-subscribed-text);
}
.plugin-source-badge.source-orphaned {
background: var(--plugin-status-warn-bg);
color: var(--plugin-status-warn);
}
.plugin-cloud-link {
color: var(--plugin-link-text);
cursor: pointer;

View File

@@ -2,11 +2,13 @@
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:rescap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/3"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
xmlns:virtualization="http://schemas.microsoft.com/appx/manifest/virtualization/windows10"
IgnorableNamespaces="uap rescap rescap3 desktop6 virtualization">
IgnorableNamespaces="uap uap3 rescap rescap3 desktop desktop6 virtualization">
<Identity Name="@MSIX_IDENTITY_NAME@"
Publisher="@MSIX_PUBLISHER@"
@@ -64,6 +66,20 @@
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="orcaslicer" />
</uap:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="prusaslicer" />
</uap:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="bambustudio" />
</uap:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="cura" />
</uap:Extension>
<uap3:Extension Category="windows.appExecutionAlias" EntryPoint="Windows.FullTrustApplication">
<uap3:AppExecutionAlias>
<desktop:ExecutionAlias Alias="orca-slicer.exe" />
</uap3:AppExecutionAlias>
</uap3:Extension>
</Extensions>
</Application>
</Applications>

View File

@@ -202,10 +202,25 @@ void AppConfig::set_defaults()
if (get("seq_top_layer_only").empty())
set("seq_top_layer_only", "1");
// ORCA: darken layers below the current one while scrubbing the preview (ported from preFlight)
// ORCA: darken the layers the preview layer slider is not scrubbed to
if (get("preview_dim_previous_layers").empty())
set_bool("preview_dim_previous_layers", false);
// ORCA: brightness of those dimmed layers, in percent. 0 = black, capped at 99 because
// 100 would render them unchanged, which is what disabling the option already does
if (get("preview_dim_previous_layers_brightness").empty())
set("preview_dim_previous_layers_brightness", "40");
else {
int brightness = 40;
try {
brightness = std::stoi(get("preview_dim_previous_layers_brightness"));
}
catch (...) {
brightness = 40;
}
set("preview_dim_previous_layers_brightness", std::to_string(std::max(0, std::min(brightness, 99))));
}
if (get("filaments_area_preferred_count").empty())
set("filaments_area_preferred_count", "10");

516
src/libslic3r/BeltBrim.cpp Normal file
View File

@@ -0,0 +1,516 @@
#include "BeltBrim.hpp"
#include "ClipperUtils.hpp"
#include "Flow.hpp"
#include "Layer.hpp"
#include "Polygon.hpp"
#include "Print.hpp"
#include "ShortestPath.hpp"
#include "Support/BeltFloorContext.hpp"
#include <algorithm>
namespace Slic3r {
// ---------------------------------------------------------------- scaling
static inline Point scale_u_point(const Point &p, int from_axis, double factor)
{
// llround, not a cast: casting truncates toward zero, so a round trip would
// walk every vertex toward the origin by up to one unit per pass.
return from_axis == 0 ?
Point(coord_t(std::llround(double(p.x()) * factor)), p.y()) :
Point(p.x(), coord_t(std::llround(double(p.y()) * factor)));
}
static inline void scale_u_polygon(Polygon &poly, int from_axis, double factor)
{
for (Point &p : poly.points)
p = scale_u_point(p, from_axis, factor);
}
ExPolygons belt_scale_u(const ExPolygons &src, const BeltBrimFrame &frame, double factor)
{
ExPolygons out = src;
for (ExPolygon &ex : out) {
scale_u_polygon(ex.contour, frame.from_axis, factor);
for (Polygon &hole : ex.holes)
scale_u_polygon(hole, frame.from_axis, factor);
}
return out;
}
Polylines belt_scale_u(const Polylines &src, const BeltBrimFrame &frame, double factor)
{
Polylines out = src;
for (Polyline &pl : out)
for (Point &p : pl.points)
p = scale_u_point(p, frame.from_axis, factor);
return out;
}
// ---------------------------------------------------------------- sweep
ExPolygons sweep_ex(const ExPolygons &src, const Point &t)
{
if (src.empty())
return {};
if (t == Point(0, 0))
return src;
// One parallelogram per boundary edge. Together with P and P + t these
// cover the Minkowski sum exactly: for any q = p + s*t with p in P and
// s in [0, 1], let s* be the smallest lambda >= 0 with q - lambda*t in P.
// Either s* == 0 (so q is in P) or q - s* * t lies on some boundary edge e,
// putting q in that edge's parallelogram. Hole edges must be included, or
// holes narrower than t along t would wrongly survive the sweep.
Polygons quads;
for (const ExPolygon &ex : src)
for (size_t c = 0; c < ex.num_contours(); ++ c)
for (const Line &e : ex.contour_or_hole(c).lines()) {
if (e.a == e.b)
continue;
Polygon q;
q.points = { e.a, e.b, e.b + t, e.a + t };
// The non-zero fill rule counts a clockwise ring as -1, which
// would punch a hole instead of adding material. Edges parallel
// to t give a zero-area quad; Clipper discards those harmlessly.
if (q.is_clockwise())
q.reverse();
quads.emplace_back(std::move(q));
}
ExPolygons shifted = src;
for (ExPolygon &ex : shifted)
ex.translate(t);
// union_ex(ExPolygons, Polygons) uses pftNonZero, which is the fill rule the
// argument above relies on.
return union_ex(union_ex(src, shifted), quads);
}
// ---------------------------------------------------------------- brim region
ExPolygons belt_brim_region(const ExPolygons &footprint_flat,
bool has_outer,
bool has_inner,
coord_t brim_width,
coord_t object_gap,
coord_t leading,
coord_t lateral,
const BeltBrimFrame &frame)
{
if (footprint_flat.empty() || (! has_outer && ! has_inner))
return {};
ExPolygons out;
if (has_outer) {
// Offset the outer ring from the contours only, so a hole cannot punch
// through it. Same reasoning as the plate brim in Brim.cpp.
Polygons contours;
contours.reserve(footprint_flat.size());
for (const ExPolygon &ex : footprint_flat)
contours.emplace_back(ex.contour);
// Inner and outer boundary offset from the same polygon, to avoid
// round-off mismatch between them.
ExPolygons inner = offset_ex(contours, float(object_gap), jtRound, SCALED_RESOLUTION);
// Close the interior before offsetting outwards. A belt contact patch is often a
// narrow, broken-up strip, and the offset rings of two islands less than
// 2 x brim_width apart merge and fill the space between them - space that lies
// UNDER the part, which is not what "outer brim" means. Closing also swallows
// holes in the patch for the same reason. Concavity-filling only, so an apron or
// any other outward protrusion is untouched.
ExPolygons envelope = brim_width > 0 ? closing_ex(inner, float(brim_width)) : inner;
ExPolygons base = envelope;
if (leading > 0) {
// Sweep downhill from the gapped keep-out, so the apron is contiguous with
// the ring instead of starting inside the gap.
const Point t = frame.from_axis == 0 ?
Point(frame.downhill_sign() * leading, 0) :
Point(0, frame.downhill_sign() * leading);
base = union_ex(base, sweep_ex(envelope, t));
}
if (lateral > 0) {
// Across the belt, both ways. Swept from `base` so the apron is widened
// too, and in the flattened frame the cross-belt axis is unscaled, so this
// distance is already a true on-belt distance.
const Point t = frame.from_axis == 0 ? Point(0, lateral) : Point(lateral, 0);
ExPolygons widened = union_ex(sweep_ex(base, t), sweep_ex(base, Point(-t.x(), -t.y())));
base = union_ex(base, to_polygons(widened));
}
ExPolygons outer = offset_ex(base, float(brim_width), jtRound, SCALED_RESOLUTION);
expolygons_append(out, diff_ex(outer, envelope));
}
if (has_inner) {
// Holes reversed so a negative offset grows inward, mirroring Brim.cpp.
// No apron here: an apron growing into a hole interior is never useful.
Polygons holes;
for (const ExPolygon &ex : footprint_flat)
polygons_append(holes, ex.holes);
polygons_reverse(holes);
if (! holes.empty()) {
ExPolygons hole_inner = offset_ex(holes, - float(brim_width + object_gap));
ExPolygons hole_outer = offset_ex(holes, - float(object_gap));
expolygons_append(out, intersection_ex(diff_ex(hole_outer, hole_inner), holes));
}
}
return union_ex(out);
}
// ---------------------------------------------------------------- line lattice
std::vector<coord_t> belt_brim_line_positions(coord_t u_lo,
coord_t u_hi,
coord_t pitch_u,
coord_t u_anchor)
{
std::vector<coord_t> out;
if (pitch_u <= 0 || u_hi <= u_lo)
return out;
// Walk the lattice from just below u_lo. Integer arithmetic throughout, so
// the half-open interval needs no epsilon: a point landing exactly on u_hi
// belongs to the next band.
int64_t k = int64_t(std::floor(double(u_lo - u_anchor) / double(pitch_u))) - 1;
while (u_anchor + coord_t(k) * pitch_u < u_lo)
++ k;
for (;; ++ k) {
const coord_t u = u_anchor + coord_t(k) * pitch_u;
if (u >= u_hi)
break;
out.emplace_back(u);
}
return out;
}
// ---------------------------------------------------------------- pipeline
// A band of the belt surface as an explicit box, clamped to `bounds` along the
// shear axis. Deliberately not BeltFloorContext::surface_polygon(): those
// half-planes span +-1000 mm, which is wasteful to clip against and dangerous to
// feed through the flattening scale.
static Polygon band_box(const BoundingBox &bounds, int from_axis, coordf_t u_lo, coordf_t u_hi)
{
coord_t lo = scale_(u_lo);
coord_t hi = scale_(u_hi);
const coord_t bmin = from_axis == 0 ? bounds.min.x() : bounds.min.y();
const coord_t bmax = from_axis == 0 ? bounds.max.x() : bounds.max.y();
lo = std::max(lo, bmin);
hi = std::min(hi, bmax);
Polygon poly;
if (hi <= lo)
return poly;
if (from_axis == 0)
poly.points = { Point(lo, bounds.min.y()), Point(hi, bounds.min.y()),
Point(hi, bounds.max.y()), Point(lo, bounds.max.y()) };
else
poly.points = { Point(bounds.min.x(), lo), Point(bounds.max.x(), lo),
Point(bounds.max.x(), hi), Point(bounds.min.x(), hi) };
return poly;
}
// Everything the per-band line generator needs, gathered once per object.
struct BeltBrimContext
{
BeltFloorContext ctx;
BeltBrimFrame frame;
ExPolygons region; // brim region, object-local slicing XY
BoundingBox region_bbox;
Flow brim_flow;
coord_t pitch_u = 0;
coord_t u_anchor = 0;
double in_plane_pitch = 0.; // mm
};
// Emit the cross-belt brim lines that belong to the band [print_z - height, print_z].
static void belt_brim_band_paths(const BeltBrimContext &bc,
coordf_t print_z,
coordf_t height,
const Polygons &obstacles,
ExtrusionEntityCollection &out,
ExPolygons &areas_out)
{
coordf_t u_lo = bc.ctx.cutoff_u(print_z - height);
coordf_t u_hi = bc.ctx.cutoff_u(print_z);
if (u_lo > u_hi)
std::swap(u_lo, u_hi);
// How wide this band is measured ON the belt, versus one nominal bead.
const double band_in_plane = (u_hi - u_lo) * bc.frame.u_stretch();
// Fraction of the layer height at which a line sits above the belt. Toward the
// downhill edge, so the sheet is reasonably thick while the nozzle stays clear of
// the belt itself.
static constexpr double BAND_CLEARANCE_FRACTION = 0.75;
std::vector<coord_t> us;
double uniform_clearance = 0.; // 0 => derive per line from its own position
double line_pitch = bc.in_plane_pitch;
if (band_in_plane <= bc.in_plane_pitch + EPSILON) {
// Steep belt, which is the normal case: the band is narrower than one bead, so
// exactly one line fits. Place it at a FIXED fraction of the band rather than
// on a nominal-spacing lattice. On a lattice each line lands at an arbitrary
// point in its band, the clearance sweeps [0, height] from band to band, and the
// bead width therefore varies by 2x - visible as ragged, uneven brim lines.
// Anchoring to the band makes the clearance identical everywhere, so every bead
// is the same width.
//
// The spacing is then whatever the bands give (height / sin(tilt) on the belt)
// rather than the nominal bead spacing, so the flow below is matched to THAT
// pitch. Matched flow at the real pitch is what keeps the sheet uniform and
// gap-free; using nominal flow at band spacing would over-feed it.
us.push_back(scale_(bc.ctx.cutoff_u(print_z - BAND_CLEARANCE_FRACTION * height)));
uniform_clearance = BAND_CLEARANCE_FRACTION * height;
line_pitch = band_in_plane;
} else {
// Shallow belt: the band is wider than a bead, so it takes several lines and they
// have to sit on the nominal lattice. Their clearances then differ, and so do
// their widths - unavoidable here, but shallow belts are the rare case.
us = belt_brim_line_positions(scale_(u_lo), scale_(u_hi), bc.pitch_u, bc.u_anchor);
}
if (us.empty())
return;
const Polygons region_polys = to_polygons(bc.region);
// One lattice line at a time: the clearance - and therefore the extrusion
// volume - is a property of the line's u, so the pieces of different lines
// must not be pooled before the flow is resolved.
// Overshoot the region so the clip, not the line's ends, decides the extent.
const coord_t margin = coord_t(SCALED_EPSILON) + 1;
for (const coord_t u : us) {
Polyline line;
if (bc.frame.from_axis == 0)
line.points = { Point(u, coord_t(bc.region_bbox.min.y() - margin)),
Point(u, coord_t(bc.region_bbox.max.y() + margin)) };
else
line.points = { Point(coord_t(bc.region_bbox.min.x() - margin), u),
Point(coord_t(bc.region_bbox.max.x() + margin), u) };
Polylines pieces = intersection_pl(Polylines{ line }, region_polys);
if (! obstacles.empty())
pieces = diff_pl(pieces, obstacles);
if (pieces.empty())
continue;
// Nozzle-to-belt clearance for this line. Constant along the line, because the
// belt height depends only on the shear-axis coordinate. Band-anchored lines
// share one clearance by construction; lattice lines (shallow belts) each get
// their own, clamped so neither end of a band yields an unprintable bead.
double clearance = uniform_clearance;
if (clearance <= 0.) {
const Point probe = bc.frame.from_axis == 0 ? Point(u, 0) : Point(0, u);
clearance = print_z - bc.ctx.floor_print_z(probe);
clearance = std::min(std::max(clearance, 0.5 * height), height);
}
// with_cross_section, not with_height: it reaches the prescribed volume while
// KEEPING the extrusion spacing, so the bead is sized to fill exactly one
// pitch x clearance cell of the sheet.
const Flow f = bc.brim_flow.with_cross_section(float(line_pitch * clearance));
// Footprint of these beads, for the first-layer convex hull and bbox.
for (const Polygon &p : offset(pieces, 0.5f * float(f.scaled_width())))
areas_out.emplace_back(ExPolygon(p));
extrusion_entities_append_paths(out.entities, chain_polylines(std::move(pieces)),
erBrim, f.mm3_per_mm(), f.width(), float(clearance));
}
}
// Union of everything extruded at `print_z` that the brim must keep clear of, expressed
// in `self`'s local slicing frame. Includes `self` itself: its slice at this Z can
// overhang outside the belt footprint and land in the brim ring, which the flattened
// brim_object_gap - a belt-plane separation - does not cover.
//
// THREADING: this runs inside posSupportMaterial, which Print::process() executes for all
// objects in a tbb::parallel_for (Print.cpp). Object slices are finished by then and safe
// to read across objects, but SUPPORT layers are not: another object's thread may be
// inside clear_support_layers() - which deletes the SupportLayer pointers - right now, so
// touching a foreign object's support_layers() here is a use-after-free. Only this
// object's own supports are consulted; they are complete, because make_belt_brim() runs at
// the tail of this object's own generate_support_material(). The cost is that the brim
// does not dodge a *different* object's support at the same Z, which needs the objects to
// overlap in the belt direction in the first place.
// `region_bbox` bounds the brim; anything outside it cannot clip a brim line, so whole
// objects are skipped without materialising their polygons. On a typical plate the
// objects do not overlap and every foreign object drops out here, which matters because
// this runs once per band - hundreds of times per object.
static Polygons belt_brim_obstacles(const Print &print, const PrintObject &self,
const BoundingBox &region_bbox, coordf_t print_z, coordf_t tol)
{
const Point shift_self = self.instances().empty() ? Point(0, 0)
: self.instances().front().shift_without_plate_offset();
Polygons out;
for (const PrintObject *o : print.objects()) {
const bool is_self = (o == &self);
for (const PrintInstance &inst : o->instances()) {
const Point delta = inst.shift_without_plate_offset() - shift_self;
if (const Layer *l = o->get_layer_at_printz(print_z, tol)) {
BoundingBox lb = get_extents(l->lslices);
lb.translate(delta.x(), delta.y());
if (lb.overlap(region_bbox)) {
Polygons ps = to_polygons(l->lslices);
for (Polygon &p : ps)
p.translate(delta);
polygons_append(out, std::move(ps));
}
}
if (! is_self)
continue;
if (const SupportLayer *sl = o->get_support_layer_at_printz(print_z, tol)) {
Polygons ps = sl->support_fills.polygons_covered_by_spacing();
for (Polygon &p : ps)
p.translate(delta);
polygons_append(out, std::move(ps));
}
}
}
if (out.size() < 2)
return out; // union_() of 0 or 1 polygons is pure overhead
return union_(out);
}
void make_belt_brim(PrintObject &object)
{
object.clear_belt_brim();
if (! object.has_belt_brim())
return;
const Print &print = *object.print();
BeltBrimContext bc;
if (! bc.ctx.init(object.slicing_parameters(), print.config()))
return;
bc.frame = BeltBrimFrame{ bc.ctx.shear_factor(), bc.ctx.from_axis() };
const size_t nlayers = object.layers().size();
if (nlayers == 0)
return;
// 1. Belt footprint: the union of each layer's slice clipped to that layer's
// own contact band. This is the object's bottom face, which on a belt is
// spread over every layer instead of sitting in layer 0.
ExPolygons footprint_acc;
for (size_t i = 0; i < nlayers; ++ i) {
const Layer &layer = *object.layers()[i];
if (layer.lslices.empty())
continue;
// print_z - height, not the previous layer's print_z: variable layer
// heights make the latter wrong.
coordf_t u_lo = bc.ctx.cutoff_u(layer.print_z - layer.height);
coordf_t u_hi = bc.ctx.cutoff_u(layer.print_z);
if (u_lo > u_hi)
std::swap(u_lo, u_hi);
BoundingBox bb = get_extents(layer.lslices);
bb.offset(scale_(1.));
const Polygon band = band_box(bb, bc.frame.from_axis, u_lo, u_hi);
if (band.empty())
continue;
expolygons_append(footprint_acc, intersection_ex(layer.lslices, Polygons{ band }));
}
const ExPolygons footprint = union_ex(footprint_acc);
if (footprint.empty())
return;
// 2. Brim region, offset in the flattened (true on-belt) metric.
const PrintObjectConfig &cfg = object.config();
bc.brim_flow = print.brim_flow();
const double flow_w = bc.brim_flow.scaled_spacing() * SCALING_FACTOR;
// Quantize to an even number of lines, as the plate brim does.
const coord_t width = scale_(std::floor(cfg.brim_width.value / flow_w / 2) * flow_w * 2);
const coord_t leading = scale_(cfg.leading_brim_length.value);
const coord_t lateral = scale_(cfg.extra_brim_width.value);
const coord_t gap = scale_(cfg.brim_object_gap.value);
// Belt printers collapse Auto / Mouse ear / Painted to outer-only: the auto width
// heuristic and flat ear discs have no meaning on a tilted plane. Leading-edge-only
// is an outer brim too; it is narrowed down to the first contact below.
const BrimType bt = cfg.brim_type.value;
const bool has_outer = bt == btOuterOnly || bt == btOuterAndInner
|| bt == btAutoBrim || bt == btEar || bt == btPainted
|| bt == btLeadingEdgeOnly;
const bool has_inner = bt == btInnerOnly || bt == btOuterAndInner;
bc.region = belt_unflatten(
belt_brim_region(belt_flatten(footprint, bc.frame), has_outer, has_inner,
width, gap, leading, lateral, bc.frame),
bc.frame);
if (bt == btLeadingEdgeOnly && ! bc.region.empty()) {
// Keep only what lies at or downhill of the object's FIRST contact with the
// belt, so the part is supported as it lands and nothing is printed alongside
// it afterwards. The cut is the uphill edge of the first layer's contact band:
// everything past it belongs to later contacts.
const coordf_t u_cut = bc.ctx.cutoff_u(object.layers().front()->print_z);
BoundingBox keep_bb = get_extents(bc.region);
keep_bb.offset(scale_(1.));
const bool low_side = bc.frame.shear > 0.; // downhill is -u
const Polygon keep = band_box(keep_bb, bc.frame.from_axis,
low_side ? unscale<double>(bc.frame.from_axis == 0 ? keep_bb.min.x() : keep_bb.min.y()) : u_cut,
low_side ? u_cut : unscale<double>(bc.frame.from_axis == 0 ? keep_bb.max.x() : keep_bb.max.y()));
bc.region = keep.empty() ? ExPolygons{} : intersection_ex(bc.region, Polygons{ keep });
}
if (bc.region.empty())
return;
bc.region_bbox = get_extents(bc.region);
// 3. Line lattice. Fixed pitch in the flattened metric, anchored at the
// footprint's leading-most edge so lines stay collinear across
// disconnected islands and across the apron prologue.
bc.pitch_u = std::max<coord_t>(1, coord_t(bc.brim_flow.scaled_spacing() * bc.frame.cos_tilt()));
bc.in_plane_pitch = unscale<double>(bc.pitch_u) * bc.frame.u_stretch();
{
const BoundingBox fbb = get_extents(footprint);
const bool low_side = bc.frame.shear > 0.;
bc.u_anchor = bc.frame.from_axis == 0 ? (low_side ? fbb.min.x() : fbb.max.x())
: (low_side ? fbb.min.y() : fbb.max.y());
}
// 4. Bands coincident with an object layer.
std::vector<ExtrusionEntityCollection> by_layer(nlayers);
std::vector<ExPolygons> areas_by_layer(nlayers);
for (size_t i = 0; i < nlayers; ++ i) {
const Layer &layer = *object.layers()[i];
const Polygons obstacles = belt_brim_obstacles(print, object, bc.region_bbox, layer.print_z, 0.5 * layer.height);
belt_brim_band_paths(bc, layer.print_z, layer.height, obstacles, by_layer[i], areas_by_layer[i]);
}
// 5. Apron prologue: the part of the region downhill of the object's first
// layer, which has no object layer to ride on.
std::vector<BeltBrimBand> prologue;
{
const Layer &first = *object.layers().front();
const coordf_t h = first.height;
const bool low_side = bc.frame.shear > 0.;
const coord_t u_lead_s = bc.frame.from_axis == 0
? (low_side ? bc.region_bbox.min.x() : bc.region_bbox.max.x())
: (low_side ? bc.region_bbox.min.y() : bc.region_bbox.max.y());
const coordf_t u_lead = unscale<double>(u_lead_s);
// print_z at which the belt surface crosses the region's leading edge.
const coordf_t z_lead = bc.ctx.shear_factor() * u_lead
+ bc.ctx.floor_offset() + bc.ctx.z_shift();
if (h > EPSILON)
for (coordf_t z = first.print_z - h; z > z_lead - h; z -= h) {
const Polygons obstacles = belt_brim_obstacles(print, object, bc.region_bbox, z, 0.5 * h);
BeltBrimBand band;
band.print_z = z;
band.height = h;
belt_brim_band_paths(bc, z, h, obstacles, band.fills, band.areas);
if (! band.fills.empty())
prologue.emplace_back(std::move(band));
}
// Lowest Z first, so collect_layers_to_print sees them in print order.
std::reverse(prologue.begin(), prologue.end());
}
object.set_belt_brim(std::move(by_layer), std::move(areas_by_layer), std::move(prologue));
}
} // namespace Slic3r

169
src/libslic3r/BeltBrim.hpp Normal file
View File

@@ -0,0 +1,169 @@
#ifndef slic3r_BeltBrim_hpp_
#define slic3r_BeltBrim_hpp_
#include "ExPolygon.hpp"
#include "ExtrusionEntityCollection.hpp"
#include "Point.hpp"
#include "Polyline.hpp"
#include <cmath>
#include <vector>
// Belt-printer brim geometry.
//
// A belt printer slices in a ROTATED frame, so the belt surface is not the
// Z=0 bed plane but a tilted plane in slicing space:
//
// z_slicing(u) = shear * u + floor_offset + z_shift, u = X or Y
//
// where `shear == tan(tilt)` (SlicingParameters::belt_floor_shear_factor) and
// the axis is selected by SlicingParameters::belt_floor_from_axis. See
// Support/BeltFloorContext.hpp for the canonical accessors.
//
// Consequences that drive everything in this file:
//
// * A horizontal slicing layer touches the belt only along a narrow strip at
// its leading edge, `layer_height / shear` wide (~0.2 mm at 45 degrees).
// The object's belt footprint - its bottom face - is therefore spread over
// every layer, not contained in layer 0.
// * Distances measured in slicing XY are NOT on-belt distances: moving `du`
// along the shear axis travels `du / cos(tilt)` across the belt. So brim
// offsets have to be taken in a "flattened" space where the shear axis is
// stretched by `1 / cos(tilt)`, then mapped back.
// * Brim ahead of the part (downhill) lies at slicing Z BELOW the object's
// first layer, because the object's layer 0 is precisely its leading
// contact with the belt.
//
// Everything here is pure geometry on ExPolygons/Polylines so it can be unit
// tested without a Print. Keep user-visible strings out of this file: it is
// not listed in localization/i18n/list.txt.
namespace Slic3r {
// Tilt window within which the BELT plane, not the bed plane, is the adhesion
// surface. Below ~1 degree a belt is a flat bed as far as adhesion goes, and the
// contact band would be layer_height/sin(tilt) - tens of millimetres - so the
// ordinary plate brim is both correct and cheaper. Above ~85 degrees the whole
// brim compresses into a sliver and is not worth generating.
inline constexpr double BELT_BRIM_MIN_TILT_DEG = 1.;
inline constexpr double BELT_BRIM_MAX_TILT_DEG = 85.;
// Description of the tilted belt plane, reduced to what the brim geometry needs.
struct BeltBrimFrame
{
// tan(tilt). Sign selects which way is downhill.
double shear = 0.;
// 0 = X, 1 = Y. Matches BeltFloorContext::from_axis().
int from_axis = 1;
// 1 / cos(tilt). Stretch factor that turns a projected distance along
// `from_axis` into the true distance travelled across the belt.
double u_stretch() const { return std::sqrt(1. + shear * shear); }
// cos(tilt). The inverse mapping.
double cos_tilt() const { return 1. / this->u_stretch(); }
// Downhill is where the belt surface is lower, i.e. printed earlier, i.e.
// the leading edge of the part. For shear > 0 that is -u.
int downhill_sign() const { return shear > 0. ? -1 : +1; }
};
// Scale only the `from_axis` component by `factor`, rounding to nearest.
//
// Deliberately not MultiPoint::scale(fx, fy) / ExPolygon::scale(fx, fy): those
// truncate toward zero, which is asymmetric about the origin and loses up to a
// full coordinate unit per vertex on every round trip.
ExPolygons belt_scale_u(const ExPolygons &src, const BeltBrimFrame &frame, double factor);
Polylines belt_scale_u(const Polylines &src, const BeltBrimFrame &frame, double factor);
// Into / out of the space where Euclidean offsets equal true on-belt distances.
inline ExPolygons belt_flatten(const ExPolygons &src, const BeltBrimFrame &frame)
{ return belt_scale_u(src, frame, frame.u_stretch()); }
inline ExPolygons belt_unflatten(const ExPolygons &src, const BeltBrimFrame &frame)
{ return belt_scale_u(src, frame, frame.cos_tilt()); }
// Minkowski sum of `src` with the segment [0, t]: the region swept by sliding
// `src` along t. Used to grow the brim downhill for "extra brim width".
//
// Implemented as union_(P, P + t, {parallelogram per boundary edge}) over ALL
// contours including holes, with every parallelogram forced counter-clockwise
// so the non-zero fill rule closes holes narrower than t along the sweep
// direction. A hole survives exactly when it is wider than |t| measured along
// t - not when it is wider in its narrowest Euclidean direction.
ExPolygons sweep_ex(const ExPolygons &src, const Point &t);
// Brim region for one already-flattened belt footprint. All lengths are scaled
// and measured in the flattened (true on-belt) metric.
//
// `has_outer` / `has_inner` are the resolved BrimType: belt printers collapse
// Auto / Mouse ear / Painted to outer-only, so the caller does that mapping and
// this function never needs PrintConfig.
//
// Two directional extras are applied to the footprint before the outer offset, so
// each one buys reach in one direction only:
//
// `leading` (leading_brim_length) sweeps the footprint DOWNHILL along the belt,
// so every leading-facing edge gains an apron ahead of it.
// `lateral` (extra_brim_width) sweeps it BOTH WAYS across the belt, widening
// the brim sideways without pushing it further ahead or behind.
//
// Neither is applied to the inner (hole) ring.
ExPolygons belt_brim_region(const ExPolygons &footprint_flat,
bool has_outer,
bool has_inner,
coord_t brim_width,
coord_t object_gap,
coord_t leading,
coord_t lateral,
const BeltBrimFrame &frame);
// Brim line positions for one layer band.
//
// Lines sit on a fixed lattice `u_anchor + k * pitch_u` so the on-belt spacing
// between neighbouring brim lines is constant regardless of how the lattice
// falls across layer bands. Snapping to band centres instead would quantise
// the spacing to whole bands and under-deposit by ~35% at 45 degrees.
//
// The band is half-open, [u_lo, u_hi), so every lattice point belongs to
// exactly one band: none duplicated at a boundary, none dropped. A band
// narrower than the pitch simply yields nothing; a band much wider (shallow
// tilt) yields several lines.
std::vector<coord_t> belt_brim_line_positions(coord_t u_lo,
coord_t u_hi,
coord_t pitch_u,
coord_t u_anchor);
// ---------------------------------------------------------------- pipeline
// One brim-only layer printed BEFORE the object's first layer, carrying the
// apron that has to be stuck to the belt ahead of the part.
//
// Deliberately not a Layer subclass. A synthetic Layer would inherit id()
// semantics that leak into initial-layer temperature selection, the spiral vase
// probe, gradual interpolation, avoid-crossing-perimeters and cooling, all of
// which key off Layer::id() == 0 or off a layer's regions. A plain record
// carries only what the emitter needs.
//
// `height` is the LAYER height, used for the Z move and ordering metadata only.
// Each extrusion path inside `fills` carries its own height, equal to that
// line's nozzle-to-belt clearance, which varies across the band.
struct BeltBrimBand
{
coordf_t print_z = 0.;
coordf_t height = 0.;
// erBrim paths in the object's local slicing frame, untranslated.
ExtrusionEntityCollection fills;
// Footprint of those paths, for the first-layer convex hull / bbox.
ExPolygons areas;
};
class PrintObject;
// Generate the belt brim for one object: fills its per-object-layer bands and
// its apron prologue. No-op unless PrintObject::has_belt_brim().
//
// Runs inside posSupportMaterial rather than the brim step, because the prologue
// print_z values must exist before ToolOrdering is built at psWipeTower.
void make_belt_brim(PrintObject &object);
} // namespace Slic3r
#endif // slic3r_BeltBrim_hpp_

View File

@@ -0,0 +1,76 @@
#include "BeltGCode.hpp"
#include "BeltGCodeWriter.hpp"
#include "BeltTransform.hpp"
#include "Print.hpp"
namespace Slic3r {
void BeltGCode::init_belt_writer(Print &print, bool is_bbl_printers)
{
if (!print.config().belt_printer.value)
return;
auto belt_writer = std::make_unique<BeltGCodeWriter>();
belt_writer->set_is_bbl_machine(is_bbl_printers);
// Axis remap and build volume max are set by base GCode after init_belt_writer returns.
belt_writer->set_belt_back_transform(print.config());
belt_writer->set_machine_frame_transform(print.config());
m_writer = std::move(belt_writer);
}
void BeltGCode::write_belt_header(GCodeOutputStream &file, const Print &print)
{
if (!print.config().belt_printer.value)
return;
const auto &full_cfg = print.full_print_config();
// Slicing rotation: the belt tilt (axis + angle) and the single source of truth
// for the physical tilt the G-code viewer uses to enable belt view.
file.write_format("; belt_slice_rotation = %s\n", full_cfg.opt_serialize("belt_slice_rotation").c_str());
file.write_format("; belt_slice_rotation_angle = %.1f\n", print.config().belt_slice_rotation_angle.value);
file.write_format("; belt_slice_rotation_global = %d\n", print.config().belt_slice_rotation_global.value ? 1 : 0);
// Pre-slice remap configs
file.write_format("; preslice_remap_x = %s\n", full_cfg.opt_serialize("preslice_remap_x").c_str());
file.write_format("; preslice_remap_y = %s\n", full_cfg.opt_serialize("preslice_remap_y").c_str());
file.write_format("; preslice_remap_z = %s\n", full_cfg.opt_serialize("preslice_remap_z").c_str());
file.write_format("; preslice_remap_global = %d\n", print.config().preslice_remap_global.value ? 1 : 0);
file.write_format("; belt_preslice_global = %d\n", print.config().belt_preslice_global.value ? 1 : 0);
// Machine-frame transform: shear (tan) + scale (1/cos) derived from the belt
// tilt angle (or belt_frame_tilt_angle when decoupled).
file.write_format("; belt_frame_tilt_decouple = %d\n", print.config().belt_frame_tilt_decouple.value ? 1 : 0);
file.write_format("; belt_frame_tilt_angle = %.1f\n", print.config().belt_frame_tilt_angle.value);
}
void BeltGCode::on_set_origin(const PrintObject * /*obj*/, const Point & /*inst_shift*/)
{
// Global pre-slice mode: adjust origin using computed correction.
// Transform the origin through the belt pipeline so that
// back_transform(T * origin) = origin (correct machine position).
//
// Flags that trigger this path:
// belt_preslice_global — full pipeline (rotation * remap) is global
// preslice_remap_global — only the pre-slice remap is global
// belt_slice_rotation_global — slicing rotation treated as global (matches
// the per-instance Z-offset added in PrintObjectSlice.cpp)
// The XY origin adjustment uses the FULL forward transform, because the
// back_transform applied during G-code emission is always the inverse of
// the full pipeline.
bool use_global = m_config.belt_preslice_global.value
|| (m_config.preslice_remap_global.value
&& BeltTransformPipeline::has_preslice_remap(m_config))
|| (m_config.belt_slice_rotation_global.value
&& m_config.belt_slice_rotation.value != BeltRotationAxis::None
&& std::abs(m_config.belt_slice_rotation_angle.value) > EPSILON);
if (!use_global || !m_config.belt_printer.value)
return;
// Adjust origin: transform through belt forward pipeline so that
// the back-transform correctly recovers model-space positions.
Transform3d T = BeltTransformPipeline::build_forward_transform(m_config);
Vec2d cur_origin = this->origin();
Vec3d origin3d(cur_origin.x(), cur_origin.y(), 0.);
Vec3d adjusted = T.linear() * origin3d;
this->set_origin(Vec2d(adjusted.x(), adjusted.y()));
}
} // namespace Slic3r

View File

@@ -0,0 +1,23 @@
#pragma once
#include "GCode.hpp"
namespace Slic3r {
// Belt-printer-specific GCode export.
//
// Inherits from GCode and overrides virtual hooks to:
// - Create a BeltGCodeWriter instead of a plain GCodeWriter
// - Write belt configuration to the G-code header
// - Adjust the origin for global pre-slice transforms when switching instances
// - Disable arc fitting (G2/G3 not supported on belt printers)
class BeltGCode : public GCode
{
protected:
void init_belt_writer(Print &print, bool is_bbl_printers) override;
void write_belt_header(GCodeOutputStream &file, const Print &print) override;
void on_set_origin(const PrintObject *obj, const Point &inst_shift) override;
bool should_disable_arc_fitting() const override { return true; }
};
} // namespace Slic3r

View File

@@ -0,0 +1,277 @@
#include "BeltGCodeWriter.hpp"
#include "FirstLayerPlane.hpp"
#include "Geometry.hpp"
#include <boost/log/trivial.hpp>
namespace Slic3r {
namespace {
// Decide whether a particular destination point gets first-layer treatment.
// When the plane evaluator is active, distance from the plane wins; otherwise
// fall back to the layer-coarse m_is_first_layer flag set by the caller.
inline bool belt_point_on_first_layer(
const FirstLayerPlane *plane,
double first_layer_thickness_mm,
bool layer_first_flag,
const Vec3d &point_slicing_mm)
{
if (plane && plane->is_active())
return plane->is_first_layer(point_slicing_mm, first_layer_thickness_mm);
return layer_first_flag;
}
} // namespace
// ---- Belt configuration ---------------------------------------------------
void BeltGCodeWriter::set_belt_back_transform(const PrintConfig &config)
{
m_belt_back_transform.init_from_config(config);
}
void BeltGCodeWriter::set_machine_frame_transform(const PrintConfig &config)
{
m_machine_frame_transform.init_from_config(config);
}
Vec3d BeltGCodeWriter::to_machine_coords(const Vec3d &pos) const
{
// Step 1+2: To Cartesian (back_transform + axis_remap).
// In world-coordinates mode (PA line / PA pattern calibration) the input
// already describes a point relative to the belt surface, so the
// slicer->world back-transform is skipped and only the machine kinematics
// (axis remap + frame shear/scale) are applied.
Vec3d after_back = m_world_coordinates ? pos : m_belt_back_transform.apply(pos);
Vec3d result = apply_axis_remap(after_back);
Vec3d after_remap = result;
// Step 3: Machine-frame transform (belt frame tilt) applied LAST so it acts
// as a global linear transform on the placed coords.
Vec3d final = m_machine_frame_transform.apply(result);
// [BELT-DEBUG] One-shot log per layer transition (i.e. when the input Z
// crosses an integer mm boundary) to keep the log volume manageable while
// still capturing one sample per ~5 layers. Shows the full pipeline so
// Case A vs Case B can be compared step-by-step.
static thread_local int s_last_logged_z = std::numeric_limits<int>::min();
int z_bucket = static_cast<int>(std::floor(pos.z() * 5.0)); // every 0.2mm
if (z_bucket != s_last_logged_z) {
s_last_logged_z = z_bucket;
BOOST_LOG_TRIVIAL(trace) << "[BELT-DEBUG] to_machine_coords"
<< " slicer_in=(" << pos.x() << "," << pos.y() << "," << pos.z() << ")"
<< " after_back=(" << after_back.x() << "," << after_back.y() << "," << after_back.z() << ")"
<< " after_remap=(" << after_remap.x() << "," << after_remap.y() << "," << after_remap.z() << ")"
<< " final=(" << final.x() << "," << final.y() << "," << final.z() << ")"
<< " mft_active=" << m_machine_frame_transform.is_active()
<< " back_active=" << m_belt_back_transform.is_active();
}
return final;
}
// ---- Overridden movement methods ------------------------------------------
std::string BeltGCodeWriter::travel_to_xy(const Vec2d &point, const std::string &comment)
{
m_pos(0) = point(0);
m_pos(1) = point(1);
this->set_current_position_clear(true);
Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
// Belt printer: transform to machine coordinates (XY travel also needs Z due to YZ rotation)
Vec3d machine = to_machine_coords(Vec3d(point_on_plate.x(), point_on_plate.y(), m_pos.z()));
GCodeG1Formatter w;
w.emit_xyz(machine);
const bool first_layer_for_point = belt_point_on_first_layer(
m_first_layer_plane, m_first_layer_thickness_mm, m_is_first_layer,
Vec3d(point.x(), point.y(), m_pos.z()));
auto speed = first_layer_for_point
? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
: this->config.travel_speed.get_at(m_cached_extruder_idx);
w.emit_f(speed * 60.0);
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
return w.string();
}
std::string BeltGCodeWriter::lazy_lift(LiftType lift_type, bool spiral_vase)
{
// Belt printer: force NormalLift since SpiralLift and SlopeLift compute
// slope angles that don't account for the YZ coordinate rotation.
return GCodeWriter::lazy_lift(LiftType::NormalLift, spiral_vase);
}
std::string BeltGCodeWriter::eager_lift(const LiftType type)
{
// Belt printer: force NormalLift (SpiralLift/SlopeLift don't account for YZ rotation).
return GCodeWriter::eager_lift(LiftType::NormalLift);
}
std::string BeltGCodeWriter::_travel_to_z(double z, const std::string &comment)
{
m_pos(2) = z;
double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx);
if (speed == 0.) {
const bool first_layer_for_point = belt_point_on_first_layer(
m_first_layer_plane, m_first_layer_thickness_mm, m_is_first_layer,
Vec3d(m_pos.x(), m_pos.y(), z));
speed = first_layer_for_point ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
: this->config.travel_speed.get_at(m_cached_extruder_idx);
}
// Belt printer: a Z-only move in slicing frame needs to emit both Y and Z in machine coords.
Vec3d machine = to_machine_coords(Vec3d(m_pos.x() - m_x_offset, m_pos.y() - m_y_offset, z));
GCodeG1Formatter w;
w.emit_xyz(machine);
w.emit_f(speed * 60.0);
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
return w.string();
}
std::string BeltGCodeWriter::extrude_to_xy(const Vec2d &point, double dE, const std::string &comment, bool force_no_extrusion)
{
m_pos(0) = point(0);
m_pos(1) = point(1);
if (std::abs(dE) <= std::numeric_limits<double>::epsilon())
force_no_extrusion = true;
if (!force_no_extrusion)
filament()->extrude(dE);
Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
// Belt printer: transform and emit XYZ (Y and Z are coupled)
Vec3d machine = to_machine_coords(Vec3d(point_on_plate.x(), point_on_plate.y(), m_pos.z()));
GCodeG1Formatter w;
w.emit_xyz(machine);
if (!force_no_extrusion)
w.emit_e(filament()->E());
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
return w.string();
}
std::string BeltGCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment, bool force_no_extrusion)
{
m_pos = point;
m_lifted = 0;
if (!force_no_extrusion)
filament()->extrude(dE);
Vec3d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset, point(2) };
point_on_plate = to_machine_coords(point_on_plate);
GCodeG1Formatter w;
w.emit_xyz(point_on_plate);
if (!force_no_extrusion)
w.emit_e(filament()->E());
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
return w.string();
}
std::string BeltGCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment, bool force_z)
{
// Belt-specific override of travel_to_xyz.
// Key differences from base:
// 1. All coordinates go through to_machine_coords()
// 2. Always emit full XYZ (can't split XY and Z due to coupling)
// 3. Lift type forced to NormalLift (handled by lazy_lift/eager_lift overrides)
Vec3d dest_point = point;
const bool first_layer_for_point = belt_point_on_first_layer(
m_first_layer_plane, m_first_layer_thickness_mm, m_is_first_layer, point);
auto travel_speed =
first_layer_for_point ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
: this->config.travel_speed.get_at(m_cached_extruder_idx);
// Handle pending z_hop
if (std::abs(m_to_lift) > EPSILON) {
assert(std::abs(m_lifted) < EPSILON);
if ((!this->is_current_position_clear() || m_pos != dest_point) &&
m_to_lift + m_pos(2) > point(2)) {
m_lifted = m_to_lift + m_pos(2) - point(2);
dest_point(2) = m_to_lift + m_pos(2);
}
m_to_lift = 0.;
std::string slop_move;
Vec3d source = { m_pos(0) - m_x_offset, m_pos(1) - m_y_offset, m_pos(2) };
Vec3d target = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
Vec3d delta = target - source;
Vec2d delta_no_z = { delta(0), delta(1) };
if (delta(2) > 0 && delta_no_z.norm() != 0.0f) {
// Belt: SpiralLift and SlopeLift are disabled (lazy_lift forces NormalLift),
// but handle NormalLift and fallthrough.
if (m_to_lift_type == LiftType::SlopeLift &&
this->is_current_position_clear() &&
atan2(delta(2), delta_no_z.norm()) < this->filament()->travel_slope()) {
Vec2d temp = delta_no_z.normalized() * delta(2) / tan(this->filament()->travel_slope());
Vec3d slope_top_point = Vec3d(temp(0), temp(1), delta(2)) + source;
slope_top_point = to_machine_coords(slope_top_point);
GCodeG1Formatter w0;
w0.emit_xyz(slope_top_point);
w0.emit_f(travel_speed * 60.0);
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
slop_move = w0.string();
}
else if (m_to_lift_type == LiftType::NormalLift && this->is_current_position_clear()) {
// Only lift-in-place when the current position is known. On a normal
// printer _travel_to_z emits a Z-only move, but in belt mode Z is coupled
// to Y/X, so _travel_to_z re-emits the current m_pos through the belt
// shear. At print start (and after custom gcode) m_pos.xy is still the
// uninitialised origin (0,0), which shears into a bogus machine point
// (e.g. X=bed_max, Y=layer_z) far up the gantry. Skipping the separate
// lift here is safe: there is nothing to lift over yet, and the
// xy_z_move below travels straight to the destination with full XYZ,
// establishing the correct position. This mirrors the SlopeLift branch
// above, which already guards on is_current_position_clear().
slop_move = _travel_to_z(target.z(), "normal lift Z");
}
}
std::string xy_z_move;
{
Vec3d emit_target = to_machine_coords(target);
GCodeG1Formatter w0;
// Belt mode: always emit full XYZ since Y and Z are coupled
w0.emit_xyz(emit_target);
w0.emit_f(travel_speed * 60.0);
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
xy_z_move = w0.string();
}
m_pos = dest_point;
this->set_current_position_clear(true);
return slop_move + xy_z_move;
}
else if (!force_z && !this->will_move_z(point(2))) {
double nominal_z = m_pos(2) - m_lifted;
m_lifted -= (point(2) - nominal_z);
if (std::abs(m_lifted) < EPSILON)
m_lifted = 0.;
this->set_current_position_clear(true);
return this->travel_to_xy(to_2d(point));
}
else {
m_lifted = 0;
}
Vec3d point_on_plate = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
point_on_plate = to_machine_coords(point_on_plate);
// Belt mode: always emit full XYZ
GCodeG1Formatter w;
w.emit_xyz(point_on_plate);
// Use the first-layer-aware travel_speed computed at the top of this function,
// not the raw config travel_speed, so initial-layer travels are correctly slowed.
w.emit_f(travel_speed * 60.0);
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
m_pos = dest_point;
this->set_current_position_clear(true);
return w.string();
}
} // namespace Slic3r

View File

@@ -0,0 +1,64 @@
#pragma once
#include "GCodeWriter.hpp"
#include "GCode/BeltBackTransform.hpp"
#include "GCode/MachineFrameTransform.hpp"
namespace Slic3r {
class FirstLayerPlane;
// Belt-printer-specific GCode writer.
//
// Inherits from GCodeWriter and overrides movement methods to apply
// coordinate transformation (back-transform, axis remap, machine-frame
// transform) and emit coupled XYZ moves (Y and Z are coupled due to belt tilt).
class BeltGCodeWriter : public GCodeWriter
{
public:
BeltGCodeWriter() : GCodeWriter() {}
// Belt configuration (axis remap is inherited from GCodeWriter)
void set_belt_back_transform(const PrintConfig &config);
void set_machine_frame_transform(const PrintConfig &config);
Vec3d to_machine_coords(const Vec3d &pos) const;
// World-coordinates mode: incoming coordinates are treated as points
// relative to the physical belt surface (X across, Y along the belt,
// Z height above it) instead of slicing-frame coordinates — the
// slicer->world back-transform is skipped. Used by the PA line / PA
// pattern calibration generators, whose logical bed coordinates describe
// first-layer drawings on the build surface.
void set_world_coordinates(bool enable) { m_world_coordinates = enable; }
// First-layer plane: when set to a non-null active evaluator, travel
// speed selection consults the plane per-move and uses
// initial_layer_travel_speed for points within first_layer_height_mm
// of the plane (regardless of slicing layer index).
void set_first_layer_plane(const FirstLayerPlane *plane,
double first_layer_height_mm) {
m_first_layer_plane = plane;
m_first_layer_thickness_mm = first_layer_height_mm;
}
// Overridden movement methods
std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string()) override;
std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string(), bool force_z = false) override;
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false) override;
std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false) override;
std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false) override;
std::string eager_lift(const LiftType type) override;
protected:
std::string _travel_to_z(double z, const std::string &comment) override;
private:
BeltBackTransform m_belt_back_transform;
MachineFrameTransform m_machine_frame_transform;
bool m_world_coordinates = false;
// Borrowed pointer; lifetime owned by GCode. null = inactive.
const FirstLayerPlane *m_first_layer_plane = nullptr;
double m_first_layer_thickness_mm = 0.;
};
} // namespace Slic3r

View File

@@ -0,0 +1,143 @@
#include "BeltSliceStrategy.hpp"
#include "Model.hpp"
#include <limits>
#include <boost/log/trivial.hpp>
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
#include <iomanip>
#include <sstream>
#include <thread>
#endif
namespace Slic3r {
void BeltSliceStrategy::apply_preslice_transforms(Transform3d &trafo,
const PrintConfig &config,
const ModelVolumePtrs &model_volumes,
double *out_belt_min_z)
{
// 1. Standalone pre-slice axis remap (works without belt mode).
const bool has_remap = BeltTransformPipeline::has_preslice_remap(config);
if (has_remap)
trafo = BeltTransformPipeline::build_preslice_remap(config) * trafo;
// 2. Belt rotation — the sole mesh-side belt transform (matching
// BeltTransformPipeline::build_forward_transform). Only active in
// belt-printer mode.
bool has_rotation = false;
if (config.belt_printer.value) {
const Matrix3d rot = BeltTransformPipeline::build_rotation_matrix(config, &has_rotation);
if (has_rotation) {
Transform3d belt_xform = Transform3d::Identity();
belt_xform.linear() = rot;
trafo = belt_xform * trafo;
}
}
if (!has_remap && !has_rotation)
return;
// 3. Z-shift — detect if the mesh clips below the build plate after the
// transforms and lift it. Each mesh vertex must be brought into object space
// via mv->get_matrix() before applying the full trafo (which is in object
// space). Missing this on assemblies (where per-volume get_matrix() positions
// each volume within the object) would compute min_z against mesh-local vertex
// coordinates rather than object-space coordinates, so volumes translated along
// the slicer's Z axis would be silently excluded from the bound check.
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
// Capture the incoming trafo for diagnostic logging.
// This is the slicer-frame transform AFTER remap + rotation but BEFORE z_shift.
const Transform3d trafo_pre_shift = trafo;
auto log_mat = [](const Matrix3d &m) {
std::ostringstream ss;
ss << std::fixed << std::setprecision(4);
ss << "[[" << m(0,0) << "," << m(0,1) << "," << m(0,2) << "],"
<< "[" << m(1,0) << "," << m(1,1) << "," << m(1,2) << "],"
<< "[" << m(2,0) << "," << m(2,1) << "," << m(2,2) << "]]";
return ss.str();
};
auto log_vec3 = [](const Vec3d &v) {
std::ostringstream ss;
ss << std::fixed << std::setprecision(4);
ss << "(" << v.x() << "," << v.y() << "," << v.z() << ")";
return ss.str();
};
BOOST_LOG_TRIVIAL(trace) << "[BELT-DEBUG] apply_preslice_transforms enter"
<< " has_rotation=" << has_rotation
<< " has_remap=" << has_remap
<< " trafo.linear=" << log_mat(trafo_pre_shift.linear())
<< " trafo.translation=" << log_vec3(trafo_pre_shift.translation())
<< " volumes=" << model_volumes.size();
#endif
double min_z = std::numeric_limits<double>::max();
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
int vol_idx = 0;
#endif
for (const ModelVolume *mv : model_volumes) {
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
if (!mv->is_model_part()) { ++vol_idx; continue; }
#else
if (!mv->is_model_part()) continue;
#endif
Transform3d vol_trafo = trafo * mv->get_matrix();
const auto &its = mv->mesh().its;
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
// Per-volume bbox in mesh-frame and post-trafo slicer-frame.
Vec3d mesh_min(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
Vec3d mesh_max(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
Vec3d slicer_min(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
Vec3d slicer_max(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
double vol_min_z = std::numeric_limits<double>::max();
#endif
for (const stl_vertex &v : its.vertices) {
Vec3d vm = v.cast<double>();
Vec3d pt = vol_trafo * vm;
min_z = std::min(min_z, pt.z());
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
mesh_min = mesh_min.cwiseMin(vm);
mesh_max = mesh_max.cwiseMax(vm);
slicer_min = slicer_min.cwiseMin(pt);
slicer_max = slicer_max.cwiseMax(pt);
vol_min_z = std::min(vol_min_z, pt.z());
#endif
}
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
BOOST_LOG_TRIVIAL(trace) << "[BELT-DEBUG] vol[" << vol_idx
<< "] id=" << mv->id().id << " name='" << mv->name << "'"
<< " mesh_bbox_min=" << log_vec3(mesh_min) << " mesh_bbox_max=" << log_vec3(mesh_max)
<< " get_matrix.translation=" << log_vec3(mv->get_matrix().translation())
<< " slicer_bbox_min=" << log_vec3(slicer_min) << " slicer_bbox_max=" << log_vec3(slicer_max)
<< " vol_min_z=" << vol_min_z;
++vol_idx;
#endif
}
const double z_shift_val = (min_z < 0. && min_z != std::numeric_limits<double>::max()) ? -min_z : 0.;
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
BOOST_LOG_TRIVIAL(trace) << "[BELT-DEBUG] combined min_z=" << min_z
<< " z_shift_val=" << z_shift_val;
#endif
if (z_shift_val > 0.) {
Transform3d z_shift = Transform3d::Identity();
z_shift.matrix()(2, 3) = z_shift_val;
trafo = z_shift * trafo;
}
// out_belt_min_z is only meaningful in belt mode; the standalone-remap path
// never reported it.
if (out_belt_min_z && config.belt_printer.value) {
const double new_val = (min_z != std::numeric_limits<double>::max()) ? min_z : 0.;
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
BOOST_LOG_TRIVIAL(trace) << "[BELT-DEBUG] write m_belt_min_z tid=" << std::this_thread::get_id()
<< " target=" << out_belt_min_z << " old=" << *out_belt_min_z << " new=" << new_val;
#endif
*out_belt_min_z = new_val;
}
#ifdef SLIC3R_BELT_DIAGNOSTIC_LOG
BOOST_LOG_TRIVIAL(trace) << "[BELT-DEBUG] apply_preslice_transforms exit"
<< " final_trafo.linear=" << log_mat(trafo.linear())
<< " final_trafo.translation=" << log_vec3(trafo.translation());
#endif
}
} // namespace Slic3r

View File

@@ -0,0 +1,36 @@
#pragma once
#include "libslic3r.h"
#include "Point.hpp"
#include "BeltTransform.hpp"
#include "PrintConfig.hpp"
#include "Model.hpp"
namespace Slic3r {
// Belt printer / pre-slice transform strategy.
//
// Composes, in order, the pre-slice mesh transforms applied before slicing:
// 1. Pre-slice axis remap (standalone — works without belt mode)
// 2. Belt rotation (the sole mesh-side belt transform; shear & scale are a
// g-code-side stage, see MachineFrameTransform)
// 3. Per-object Z-shift that lifts the mesh above the build plate
//
// Isolates this belt/remap-specific logic from the generic slicing pipeline in
// PrintObjectSlice.cpp.
class BeltSliceStrategy
{
public:
// Apply the pre-slice remap + belt rotation + Z-shift to `trafo` in place.
// No-op when neither a remap nor a belt rotation is configured.
//
// out_belt_min_z (if non-null) receives the minimum mesh Z after the
// transforms, but only in belt-printer mode — the standalone-remap path
// never reported it.
static void apply_preslice_transforms(Transform3d &trafo,
const PrintConfig &config,
const ModelVolumePtrs &model_volumes,
double *out_belt_min_z = nullptr);
};
} // namespace Slic3r

View File

@@ -0,0 +1,223 @@
#include "BeltTransform.hpp"
#include "Model.hpp"
#include <limits>
namespace Slic3r {
// ---- Matrix builders ------------------------------------------------------
Transform3d BeltTransformPipeline::build_preslice_remap(const PrintConfig &config)
{
Transform3d pre_remap = Transform3d::Identity();
if (!has_preslice_remap(config))
return pre_remap;
int pre_rx = int(config.preslice_remap_x.value);
int pre_ry = int(config.preslice_remap_y.value);
int pre_rz = int(config.preslice_remap_z.value);
// Each remap value selects a source axis and sign.
auto remap_column = [](int r) -> Vec3d {
int axis = r % 3;
Vec3d col = Vec3d::Zero();
if (r < 3) col[axis] = 1.0; // +axis
else if (r < 6) col[axis] = -1.0; // -axis
else col[axis] = -1.0; // Rev: max - pos = -(pos - max)
return col;
};
Matrix3d remap_lin;
remap_lin.col(0) = remap_column(pre_rx);
remap_lin.col(1) = remap_column(pre_ry);
remap_lin.col(2) = remap_column(pre_rz);
pre_remap.linear() = remap_lin;
// Translation for Rev modes (needs build volume extents).
if (pre_rx >= 6 || pre_ry >= 6 || pre_rz >= 6) {
BoundingBoxf bbox_bed(config.printable_area.values);
Vec3d vol_max(bbox_bed.max.x(), bbox_bed.max.y(),
config.printable_height.value);
Vec3d remap_trans = Vec3d::Zero();
auto add_rev = [&](int r, int out) {
if (r >= 6) remap_trans[out] = vol_max[r % 3];
};
add_rev(pre_rx, 0);
add_rev(pre_ry, 1);
add_rev(pre_rz, 2);
pre_remap.translation() = remap_trans;
}
return pre_remap;
}
Matrix3d BeltTransformPipeline::build_rotation_matrix(const PrintConfig &config, bool *has_rot_out)
{
BeltRotationAxis axis = config.belt_slice_rotation.value;
double angle_deg = config.belt_slice_rotation_angle.value;
bool active = axis != BeltRotationAxis::None && std::abs(angle_deg) > EPSILON;
if (has_rot_out) *has_rot_out = active;
if (!active)
return Matrix3d::Identity();
double angle_rad = Geometry::deg2rad(angle_deg);
Vec3d unit_axis;
switch (axis) {
case BeltRotationAxis::X: unit_axis = Vec3d::UnitX(); break;
case BeltRotationAxis::Y: unit_axis = Vec3d::UnitY(); break;
case BeltRotationAxis::Z: unit_axis = Vec3d::UnitZ(); break;
default: return Matrix3d::Identity();
}
return Eigen::AngleAxisd(angle_rad, unit_axis).toRotationMatrix();
}
Transform3d BeltTransformPipeline::build_forward_transform(const PrintConfig &config)
{
// Mesh-side belt transform: rotation applied after the pre-slice axis remap.
// (Shear & scale are a g-code-side stage, not part of the mesh transform.)
Transform3d pre_remap = build_preslice_remap(config);
Matrix3d rot = build_rotation_matrix(config);
Transform3d combined = Transform3d::Identity();
combined.linear() = rot;
combined = combined * pre_remap;
return combined;
}
// ---- Bounding box remap ---------------------------------------------------
BoundingBoxf3 BeltTransformPipeline::remap_bbox(const BoundingBoxf3 &bb, const PrintConfig &config)
{
int pre_rx = int(config.preslice_remap_x.value);
int pre_ry = int(config.preslice_remap_y.value);
int pre_rz = int(config.preslice_remap_z.value);
if (pre_rx == int(RemapAxis::PosX) &&
pre_ry == int(RemapAxis::PosY) &&
pre_rz == int(RemapAxis::PosZ))
return bb; // Identity remap.
auto remap_coord = [](int r, const Vec3d &v) -> double {
int axis = r % 3;
if (r < 3) return v[axis];
return -v[axis];
};
Vec3d mn = bb.min.cast<double>(), mx = bb.max.cast<double>();
BoundingBoxf3 rbb;
for (int i = 0; i < 8; ++i) {
Vec3d c((i & 1) ? mx.x() : mn.x(),
(i & 2) ? mx.y() : mn.y(),
(i & 4) ? mx.z() : mn.z());
Vec3d rc(remap_coord(pre_rx, c), remap_coord(pre_ry, c), remap_coord(pre_rz, c));
if (i == 0) rbb = BoundingBoxf3(rc, rc);
else rbb.merge(rc);
}
return rbb;
}
BoundingBoxf3 BeltTransformPipeline::remap_bbox(const ModelObject &model_object, const PrintConfig &config)
{
return remap_bbox(model_object.raw_bounding_box(), config);
}
// ---- Belt floor parameters ------------------------------------------------
// Shared implementation for both PrintConfig and DynamicPrintConfig.
// Template avoids duplicating the math for the two config types.
namespace {
template<typename Config>
BeltTransformPipeline::BeltHeightResult compute_belt_height_and_floor_impl(
const Config &config, const BoundingBoxf3 &bb, double original_height)
{
BeltTransformPipeline::BeltHeightResult result;
result.object_height = original_height;
// Extract the mesh rotation from config (the sole mesh-side belt transform).
BeltRotationAxis rot_axis;
double rot_angle;
if constexpr (std::is_same_v<Config, PrintConfig>) {
rot_axis = config.belt_slice_rotation.value;
rot_angle = config.belt_slice_rotation_angle.value;
} else {
// DynamicPrintConfig path
auto get_float = [&](const char *key) {
auto *opt = config.template option<ConfigOptionFloat>(key);
return opt ? opt->value : 0.0;
};
auto get_rot_axis = [&](const char *key) {
auto *opt = config.template option<ConfigOptionEnum<BeltRotationAxis>>(key);
return opt ? opt->value : BeltRotationAxis::None;
};
rot_axis = get_rot_axis("belt_slice_rotation");
rot_angle = get_float("belt_slice_rotation_angle");
}
bool has_rotation = rot_axis != BeltRotationAxis::None && std::abs(rot_angle) > EPSILON;
if (!has_rotation)
return result;
// Rotation path: sweep the 8 bbox corners through R to get the rotated height,
// then derive the belt floor (the image of machine-Z = 0 under R).
double angle_rad = Geometry::deg2rad(rot_angle);
Vec3d unit_axis;
switch (rot_axis) {
case BeltRotationAxis::X: unit_axis = Vec3d::UnitX(); break;
case BeltRotationAxis::Y: unit_axis = Vec3d::UnitY(); break;
case BeltRotationAxis::Z: unit_axis = Vec3d::UnitZ(); break;
default: unit_axis = Vec3d::UnitX(); break;
}
Matrix3d R = Eigen::AngleAxisd(angle_rad, unit_axis).toRotationMatrix();
double min_rz = std::numeric_limits<double>::max();
double max_rz = std::numeric_limits<double>::lowest();
for (int i = 0; i < 8; ++i) {
Vec3d c((i & 1) ? bb.max.x() : bb.min.x(),
(i & 2) ? bb.max.y() : bb.min.y(),
(i & 4) ? bb.max.z() : bb.min.z());
double z = (R * c).z();
min_rz = std::min(min_rz, z);
max_rz = std::max(max_rz, z);
}
result.object_height = max_rz - min_rz;
// Belt floor in slicer-frame is the image of z_machine = 0 under R.
// R(+α, X): point (·, y, 0) → (·, cos α · y, sin α · y) ⇒ z = tan(α) · y_s
// R(+α, Y): point (x, ·, 0) → (cos α · x, ·, -sin α · x) ⇒ z = -tan(α) · x_s
// R(+α, Z): point (·, ·, 0) → (·, ·, 0); no tilt → no floor
double sin_a = std::sin(angle_rad), cos_a = std::cos(angle_rad);
switch (rot_axis) {
case BeltRotationAxis::X:
result.floor_params.shear_factor = (std::abs(cos_a) > EPSILON) ? sin_a / cos_a : 0.;
result.floor_params.from_axis = 1; // Y
break;
case BeltRotationAxis::Y:
result.floor_params.shear_factor = (std::abs(cos_a) > EPSILON) ? -sin_a / cos_a : 0.;
result.floor_params.from_axis = 0; // X
break;
case BeltRotationAxis::Z:
default:
result.floor_params.shear_factor = 0.0;
result.floor_params.from_axis = 1;
break;
}
result.floor_params.z_shift = bb.min.z() + ((min_rz < 0.) ? -min_rz : 0.);
return result;
}
} // anonymous namespace
BeltTransformPipeline::BeltHeightResult BeltTransformPipeline::compute_belt_height_and_floor(
const PrintConfig &config, const BoundingBoxf3 &remapped_bbox, double original_height)
{
return compute_belt_height_and_floor_impl(config, remapped_bbox, original_height);
}
BeltTransformPipeline::BeltHeightResult BeltTransformPipeline::compute_belt_height_and_floor(
const DynamicPrintConfig &config, const BoundingBoxf3 &remapped_bbox, double original_height)
{
return compute_belt_height_and_floor_impl(config, remapped_bbox, original_height);
}
} // namespace Slic3r

View File

@@ -0,0 +1,152 @@
#pragma once
#include "libslic3r.h"
#include "Point.hpp"
#include "BoundingBox.hpp"
#include "PrintConfig.hpp"
#include "Geometry.hpp"
#include <cmath>
namespace Slic3r {
class ModelObject;
// Shared belt-printer transform math.
//
// The pre-slice pipeline applied in PrintObjectSlice.cpp is:
// trafo_out = z_shift * rotation * pre_remap * trafo_in
//
// Rotation is the sole mesh-side belt transform; shear & scale are applied
// to the g-code instead (see MachineFrameTransform). This class provides the
// building blocks so every call site uses the same implementation. z_shift is
// object-dependent (computed from mesh vertex bounds) and is NOT included in
// build_forward_transform(). The machine-frame shear/scale is derived directly
// from the tilt angle in MachineFrameTransform and no longer lives here.
//
// Design note: this mesh-rotation approach replaced an earlier pre-shear
// method (now removed). While that initial pre-shear method was instrumental
// in getting belt printer slicing off the ground in the first place, its place is
// in the past. A big thank you goes to the Unlayered3D team, who recommended
// switching to a pre-slice rotation stage instead. Doing so keeps the slicing
// operation isometric — no distortion of the sliced geometry — while the
// non-orthogonal machine-axis compensation is confined to a g-code-side shear/scale
// derived from the same tilt angle.
//
// This fixed a number of issues, including several issues noticed by hotcubcar
// regarding adaptive infills not working, gyroid becoming anisotropic, and more
// that were all mostly resolved as a result of the switch.
//
// This also means that the pre-slice rotation transform methodology can be used
// more cleanly on non-belt printers.
// - HarrierPigeon (Joseph Robertson)
class BeltTransformPipeline
{
public:
// ---- Identity checks --------------------------------------------------
static bool has_preslice_remap(const PrintConfig &config)
{
return int(config.preslice_remap_x.value) != int(RemapAxis::PosX) ||
int(config.preslice_remap_y.value) != int(RemapAxis::PosY) ||
int(config.preslice_remap_z.value) != int(RemapAxis::PosZ);
}
// Overload accepting DynamicPrintConfig (used in static slicing_parameters).
static bool has_preslice_remap(const DynamicPrintConfig &config)
{
auto get_int = [&](const char *key) -> int {
auto *opt = config.option<ConfigOptionEnum<RemapAxis>>(key);
return opt ? int(opt->value) : 0;
};
return get_int("preslice_remap_x") != int(RemapAxis::PosX) ||
get_int("preslice_remap_y") != int(RemapAxis::PosY) ||
get_int("preslice_remap_z") != int(RemapAxis::PosZ);
}
static bool has_rotation(const PrintConfig &config)
{
return config.belt_slice_rotation.value != BeltRotationAxis::None &&
std::abs(config.belt_slice_rotation_angle.value) > EPSILON;
}
// Physical belt tilt derived from the slicing rotation — the single source of
// truth for bed rendering, support gravity tilt and the bed-exclusion
// projection. Returns the tilt magnitude in degrees split onto the X and Y
// build-plate tilt axes according to the rotation axis:
// rotation about X → tilt_x = angle (gantry tilts in the YZ plane)
// rotation about Y → tilt_y = angle (gantry tilts in the XZ plane)
// rotation about Z / None → no tilt (in-plane spin doesn't tilt the belt)
// The magnitude uses abs(angle) so a negative rotation still reports a positive
// physical tilt.
struct PhysicalTilt { double tilt_x_deg = 0.; double tilt_y_deg = 0.; };
static PhysicalTilt physical_tilt(BeltRotationAxis axis, double angle_deg)
{
PhysicalTilt t;
double mag = std::abs(angle_deg);
switch (axis) {
case BeltRotationAxis::X: t.tilt_x_deg = mag; break;
case BeltRotationAxis::Y: t.tilt_y_deg = mag; break;
default: break; // Z / None: no physical tilt
}
return t;
}
static PhysicalTilt physical_tilt(const PrintConfig &config)
{
return physical_tilt(config.belt_slice_rotation.value,
config.belt_slice_rotation_angle.value);
}
// ---- Matrix builders --------------------------------------------------
// Build the pre-slice axis remap transform (includes Rev-mode translation).
static Transform3d build_preslice_remap(const PrintConfig &config);
// Build the 3x3 rotation matrix from belt_slice_rotation* config.
// Returns Identity if rotation axis is None or angle is ~0.
// Also sets has_rot_out if non-null.
static Matrix3d build_rotation_matrix(const PrintConfig &config, bool *has_rot_out = nullptr);
// Combined forward transform (rotation * pre_remap) — the mesh-side belt
// transform that BeltSliceStrategy applies and BeltBackTransform inverts.
// Does NOT include the per-object Z-shift.
static Transform3d build_forward_transform(const PrintConfig &config);
// ---- Bounding box remap -----------------------------------------------
// Remap a bounding box through the pre-slice axis remap.
// Returns the original bbox if remap is identity.
static BoundingBoxf3 remap_bbox(const BoundingBoxf3 &bb, const PrintConfig &config);
static BoundingBoxf3 remap_bbox(const ModelObject &model_object, const PrintConfig &config);
// ---- Belt floor parameters --------------------------------------------
struct BeltFloorParams {
double shear_factor = 0.0;
int from_axis = 1;
double z_shift = 0.0;
};
// Result of computing belt height + floor params.
struct BeltHeightResult {
double object_height; // Effective object height after shear/scale
BeltFloorParams floor_params;
};
// Compute effective object height and belt floor parameters from config
// and pre-remapped bounding box. original_height is the input height
// (bb.size().z() or model_object.max_z()).
static BeltHeightResult compute_belt_height_and_floor(
const PrintConfig &config, const BoundingBoxf3 &remapped_bbox,
double original_height);
// Overload for DynamicPrintConfig (used by static slicing_parameters).
static BeltHeightResult compute_belt_height_and_floor(
const DynamicPrintConfig &config, const BoundingBoxf3 &remapped_bbox,
double original_height);
};
} // namespace Slic3r

View File

@@ -32,15 +32,13 @@ static void append_and_translate(ExPolygons &dst, const ExPolygons &src, const P
for (; dst_idx < dst.size(); ++dst_idx)
dst[dst_idx].translate(instance_shift);
}
// BBS: generate brim area by objs
static void append_and_translate(ExPolygons& dst, const ExPolygons& src,
const PrintInstance& instance, size_t instance_idx, std::map<ObjectInstanceID, ExPolygons>& brimAreaMap) {
// Orca: Translate the brim area into print coordinates and store it per instance.
static void append_and_translate(const ExPolygons& src, const PrintInstance& instance,
size_t instance_idx, std::map<ObjectInstanceID, ExPolygons>& brimAreaMap) {
ExPolygons srcShifted = src;
Point instance_shift = instance.shift_without_plate_offset();
for (size_t src_idx = 0; src_idx < srcShifted.size(); ++src_idx)
srcShifted[src_idx].translate(instance_shift);
srcShifted = diff_ex(srcShifted, dst);
//expolygons_append(dst, temp2);
for (ExPolygon& expoly : srcShifted)
expoly.translate(instance_shift);
expolygons_append(brimAreaMap[{ instance.print_object->id(), instance_idx }], std::move(srcShifted));
}
@@ -455,7 +453,9 @@ static ExPolygons outer_inner_brim_area(const Print& print,
const bool use_auto_brim_ears = object->config().brim_type == btEar;
const bool use_brim_ears = object->config().brim_type == btPainted;
const bool has_inner_brim = brim_type == btInnerOnly || brim_type == btOuterAndInner || use_auto_brim_ears || use_brim_ears;
const bool has_outer_brim = brim_type == btOuterOnly || brim_type == btOuterAndInner || brim_type == btAutoBrim || use_auto_brim_ears || use_brim_ears;
// btLeadingEdgeOnly is a belt-printer mode; on a flat bed there is no leading
// edge, so it degrades to an ordinary outer brim rather than silently to none.
const bool has_outer_brim = brim_type == btOuterOnly || brim_type == btOuterAndInner || brim_type == btAutoBrim || brim_type == btLeadingEdgeOnly || use_auto_brim_ears || use_brim_ears;
coord_t ear_detection_length = scale_(object->config().brim_ears_detection_length.value);
coordf_t brim_ears_max_angle = object->config().brim_ears_max_angle.value;
//ORCA: Select brim base slices from EFC-compensated outline when enabled.
@@ -572,7 +572,7 @@ static ExPolygons outer_inner_brim_area(const Print& print,
for (size_t instance_idx = 0; instance_idx < object->instances().size(); ++instance_idx) {
const PrintInstance& instance = object->instances()[instance_idx];
if (!brim_area_object.empty())
append_and_translate(brim_area, brim_area_object, instance, instance_idx, brimAreaMap);
append_and_translate(brim_area_object, instance, instance_idx, brimAreaMap);
append_and_translate(no_brim_area, no_brim_area_object, instance);
append_and_translate(holes, holes_object, instance);
append_and_translate(objectIslands, objectIsland, instance);
@@ -870,11 +870,30 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
std::vector<unsigned int>& printExtruders,
std::map<ObjectInstanceID, ExPolygons>* objectBrimAreasByInstanceOut)
{
// Belt printers never use the flat plate brim.
//
// With a tilted belt the brim has to be laid onto the belt plane over many layers,
// which BeltBrim.cpp does during posSupportMaterial. With an untilted belt this
// could in principle fall through and produce an ordinary brim, but it would never
// reach the G-code: the plate brim is emitted out of skirt_brim_groups(), which
// _make_skirt() builds, and that returns early for every belt printer. Running the
// generator anyway would just burn time on geometry nobody prints.
if (print.config().belt_printer.value)
return;
std::map<ObjectInstanceID, ExPolygons> brimAreaMap;
Flow flow = print.brim_flow();
ExPolygons islands_area_ex = outer_inner_brim_area(print,
float(flow.scaled_spacing()), brimAreaMap, objPrintVec, printExtruders);
if (!print.config().combine_brims) {
ExPolygons claimed_area;
for (auto& [_, areas] : brimAreaMap) {
areas = diff_ex(areas, claimed_area);
expolygons_append(claimed_area, areas);
}
}
// BBS: Find boundingbox of the first layer
for (const ObjectID printObjID : print.print_object_ids()) {
BoundingBox bbx;

View File

@@ -176,6 +176,31 @@ BuildVolume::BuildVolume(const std::vector<Vec2d> &printable_area, const double
BOOST_LOG_TRIVIAL(debug) << "BuildVolume printable_area clasified as: " << this->type_name();
}
void BuildVolume::set_belt_printer(bool enabled, double angle_deg, bool infinite_y)
{
m_is_belt_printer = enabled;
m_belt_angle = angle_deg;
m_belt_infinite_y = infinite_y;
// Restart from the unmodified bbox each call. Without this, toggling
// belt mode off (or switching infinite_y true→false) would leave the
// extents inflated and break collision / object_state checks.
BoundingBoxf bboxf = get_extents(m_bed_shape);
m_bboxf = BoundingBoxf3{ to_3d(bboxf.min, 0.), to_3d(bboxf.max, m_max_print_height) };
if (enabled) {
if (infinite_y) {
// Extend the Y bound to a very large value for infinite belt.
m_bboxf.max.y() = 100000.;
}
// Belt printer: the Z extent already equals printable_height (set above), which
// is the usable vertical clearance above the belt. The gantry's axis range is
// sized to reach height/cos(tilt), so no diagonal scaling is applied here — this
// keeps the live "outside build volume" highlight in agreement with Print::validate().
(void) angle_deg;
}
}
#if 0
// Tests intersections of projected triangles, not just their vertices against a bounding box.
// This test also correctly evaluates collision of a non-convex object with the bounding box.
@@ -384,6 +409,11 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i
build_volume.max.z() = std::numeric_limits<double>::max();
if (ignore_bottom)
build_volume.min.z() = -std::numeric_limits<double>::max();
// Belt printer: extend Y bounds for infinite Y.
if (m_is_belt_printer && m_belt_infinite_y) {
build_volume.min.y() = -std::numeric_limits<double>::max();
build_volume.max.y() = std::numeric_limits<double>::max();
}
BoundingBox3Base<Vec3f> build_volumef(build_volume.min.cast<float>(), build_volume.max.cast<float>());
// The following test correctly interprets intersection of a non-convex object with a rectangular build volume.
//return rectangle_test(its, trafo, to_2d(build_volume.min), to_2d(build_volume.max), build_volume.max.z());

View File

@@ -57,6 +57,10 @@ public:
// Initialize from PrintConfig::printable_area and PrintConfig::printable_height
BuildVolume(const std::vector<Vec2d> &printable_area, const double printable_height, const std::vector<std::vector<Vec2d>> &extruder_areas, const std::vector<double>& extruder_printable_heights);
// Belt printer configuration.
void set_belt_printer(bool enabled, double angle_deg, bool infinite_y);
bool is_belt_printer() const { return m_is_belt_printer; }
// Source data, unscaled coordinates.
const std::vector<Vec2d>& printable_area() const { return m_bed_shape; }
double printable_height() const { return m_max_print_height; }
@@ -80,7 +84,7 @@ public:
indexed_triangle_set bounding_mesh(bool scale=true) const;
// Center of the print bed, unscaled.
Vec2d bed_center() const { return to_2d(m_bboxf.center()); }
Vec2d bed_center() const { return get_extents(m_bed_shape).center(); }
// Convex hull of polygon(), scaled.
const Polygon& convex_hull() const { return m_convex_hull; }
// Smallest enclosing circle of polygon(), scaled.
@@ -139,6 +143,10 @@ private:
// Source definition of the print volume height (PrintConfig::printable_height)
double m_max_print_height { 0.f };
std::vector<double> m_extruder_printable_height;
// Belt printer state.
bool m_is_belt_printer { false };
double m_belt_angle { 0. };
bool m_belt_infinite_y { false };
// Derived values.
BuildVolume_Type m_type { BuildVolume_Type::Invalid };

View File

@@ -80,6 +80,18 @@ set(lisbslic3r_sources
BoundingBox.hpp
BridgeDetector.cpp
BridgeDetector.hpp
BeltBrim.cpp
BeltBrim.hpp
BeltGCode.cpp
BeltGCode.hpp
BeltGCodeWriter.cpp
BeltGCodeWriter.hpp
BeltSliceStrategy.cpp
BeltSliceStrategy.hpp
BeltTransform.cpp
BeltTransform.hpp
FirstLayerPlane.cpp
FirstLayerPlane.hpp
Brim.cpp
BrimEarsPoint.hpp
Brim.hpp
@@ -210,6 +222,10 @@ set(lisbslic3r_sources
GCode/AdaptivePAProcessor.hpp
GCode/AvoidCrossingPerimeters.cpp
GCode/AvoidCrossingPerimeters.hpp
GCode/BeltBackTransform.cpp
GCode/BeltBackTransform.hpp
GCode/MachineFrameTransform.cpp
GCode/MachineFrameTransform.hpp
GCode/ConflictChecker.cpp
GCode/ConflictChecker.hpp
GCode/CoolingBuffer.cpp
@@ -418,6 +434,8 @@ set(lisbslic3r_sources
SlicingAdaptive.hpp
Slicing.cpp
Slicing.hpp
Support/BeltFloorContext.cpp
Support/BeltFloorContext.hpp
Support/SupportCommon.cpp
Support/SupportCommon.hpp
Support/SupportLayer.hpp

View File

@@ -2,6 +2,7 @@
#define slic3r_Config_hpp_
#include <assert.h>
#include <algorithm>
#include <map>
#include <climits>
#include <cfloat>
@@ -780,10 +781,14 @@ public:
this->values[i] = rhs_vec->values[i];
modified = true;
} else {
if ((i < default_index.size()) && (default_index[i] < default_value.size()))
// Orca: a negative slot (failed variant lookup) must not silently collapse the
// whole array to the first slot's value — the int-vs-size_t comparison used to
// promote -1 past the bounds check. Keep the slot's own value (get_at-style
// clamp) when no valid index is available.
if ((i < default_index.size()) && (default_index[i] >= 0) && (size_t(default_index[i]) < default_value.size()))
this->values[i] = default_value[default_index[i]];
else
this->values[i] = default_value[0];
this->values[i] = default_value[std::min(i, default_value.size() - 1)];
}
}
return modified;
@@ -2106,6 +2111,11 @@ public:
throw ConfigurationError("ConfigOptionEnumGeneric: Assigning an incompatible type");
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
this->value = rhs->getInt();
// Orca: options embedded in a StaticPrintConfig are constructed without a keys_map;
// adopt the source's so a later serialize() can emit names.
if (this->keys_map == nullptr)
if (auto rhs_generic = dynamic_cast<const ConfigOptionEnumGeneric *>(rhs))
this->keys_map = rhs_generic->keys_map;
}
std::string serialize() const override
@@ -2162,7 +2172,12 @@ public:
if (rhs->type() != this->type())
throw ConfigurationError("ConfigOptionEnumGeneric: Assigning an incompatible type");
// rhs could be of the following type: ConfigOptionEnumsGeneric
this->values = dynamic_cast<const ConfigOptionEnumsGenericTempl *>(rhs)->values;
auto rhs_enums = dynamic_cast<const ConfigOptionEnumsGenericTempl *>(rhs);
this->values = rhs_enums->values;
// Orca: options embedded in a StaticPrintConfig are constructed without a keys_map;
// adopt the source's so a later serialize() emits names instead of empty tokens.
if (this->keys_map == nullptr)
this->keys_map = rhs_enums->keys_map;
}
std::string serialize() const override

View File

@@ -396,6 +396,11 @@ inline void translate(ExPolygons &expolys, const Point &p) {
expoly.translate(p);
}
inline void translate(Polygons &polys, const Point &p) {
for (Polygon &poly : polys)
poly.translate(p);
}
inline void polygons_append(Polygons &dst, const ExPolygon &src)
{
dst.reserve(dst.size() + src.holes.size() + 1);

View File

@@ -0,0 +1,225 @@
#include "FirstLayerPlane.hpp"
#include "BeltTransform.hpp"
#include <algorithm>
#include <climits>
#include <cmath>
namespace Slic3r {
namespace {
// Build the row of the gcode-axis-remap matrix R that produces machine_Z,
// AS A FUNCTION OF a slicing-frame point in the GCode generator's coordinate
// space. Without back-transform this is just R.row(2). With back-transform
// the writer applies F^-1 before R, so the effective row is (R * F^-1).row(2).
//
// Returns a pair (gradient, constant) such that:
// machine_Z(p_slicing) = gradient.dot(p_slicing) + constant
struct MachineZAffine {
Vec3d gradient = Vec3d::UnitZ();
double constant = 0.0;
};
MachineZAffine compute_machine_z_affine(const PrintConfig &config)
{
MachineZAffine out;
// R is the matrix form of GCodeWriter::apply_axis_remap. Each output axis
// i picks one slicing-frame component (with sign + optional Rev mode
// translation) based on m_remap_{x,y,z}. We only need row 2 (the z output)
// since machine_Z is what defines the first-layer plane.
int rz = int(config.gcode_remap_z.value);
int axis = rz % 3;
double sign;
double trans;
if (rz < int(RemapAxis::NegX)) { // 0..2 = PosX/Y/Z
sign = 1.0;
trans = 0.0;
} else if (rz < int(RemapAxis::RevX)) { // 3..5 = NegX/Y/Z
sign = -1.0;
trans = 0.0;
} else { // 6..8 = RevX/Y/Z
sign = -1.0;
BoundingBoxf bbox_bed(config.printable_area.values);
Vec3d vol_max(bbox_bed.max.x(),
bbox_bed.max.y(),
config.printable_height.value);
trans = vol_max[axis];
}
Vec3d r_row = Vec3d::Zero();
r_row[axis] = sign;
// Without back-transform, machine_Z(slicing) = r_row · slicing + trans.
out.gradient = r_row;
out.constant = trans;
if (config.gcode_back_transform.value && config.belt_printer.value) {
// BeltGCodeWriter applies F^-1 before R when back-transform is on.
// So machine_Z(slicing) = r_row · (F^-1 · slicing) + trans
// = (r_row^T · F^-1) · slicing + trans
// We need to compose r_row with F^-1 from the LEFT (treating r_row as
// a row vector). Eigen makes this easy: it's just F^-1.transpose() * r_row.
Transform3d forward = BeltTransformPipeline::build_forward_transform(config);
Transform3d inverse = forward.inverse();
// Note: forward.translation() is normally zero (per-print transforms
// don't add a translation; the per-object z_shift is added separately
// in PrintObjectSlice). We still incorporate inverse.translation() in
// case a Rev-mode preslice_remap puts a translation in F.
Vec3d composed_grad = inverse.linear().transpose() * r_row;
double composed_trans =
r_row.dot(inverse.translation()) + trans;
out.gradient = composed_grad;
out.constant = composed_trans;
}
return out;
}
} // namespace
FirstLayerPlane::FirstLayerPlane(const PrintConfig &config)
{
// -------- Resolve Auto -------------------------------------------------
FirstLayerPlaneMode mode = config.first_layer_plane.value;
if (mode == FirstLayerPlaneMode::Auto) {
bool belt_affine_active = config.belt_printer.value &&
config.belt_slice_rotation.value != BeltRotationAxis::None &&
std::abs(config.belt_slice_rotation_angle.value) > EPSILON;
mode = belt_affine_active ? FirstLayerPlaneMode::BeltAffine
: FirstLayerPlaneMode::XY;
}
m_mode = mode;
// -------- Band thickness ----------------------------------------------
// Note: layer_height lives in PrintObjectConfig, not PrintConfig, so we
// can't fall back to it from here. initial_layer_print_height is in
// PrintConfig and is the right default anyway (the legacy first-layer
// semantics used initial_layer_print_height, not the regular one).
double thickness = config.first_layer_plane_thickness.value;
if (thickness <= 0.0)
thickness = config.initial_layer_print_height.value;
if (thickness <= 0.0)
thickness = 0.2;
m_thickness_mm = thickness;
const double user_offset = config.first_layer_plane_offset.value;
// -------- Build the plane ---------------------------------------------
auto set_axis_aligned = [&](const Vec3d &n_unit, double offset_along_n) {
m_normal = n_unit;
m_offset = offset_along_n;
};
switch (mode) {
case FirstLayerPlaneMode::XY:
// Legacy XY plane. Inactive: short-circuit to layer-index path.
set_axis_aligned(Vec3d::UnitZ(), user_offset);
m_active = false;
return;
case FirstLayerPlaneMode::YZ:
set_axis_aligned(Vec3d::UnitX(), user_offset);
m_active = true;
return;
case FirstLayerPlaneMode::XZ:
set_axis_aligned(Vec3d::UnitY(), user_offset);
m_active = true;
return;
case FirstLayerPlaneMode::BeltAffine: {
// Compute the slicing-frame plane that maps to machine_Z = user_offset
// under the gcode axis remap (and optional back-transform).
MachineZAffine mz = compute_machine_z_affine(config);
double cmag = mz.gradient.norm();
if (cmag < EPSILON) {
// Degenerate: slicing point doesn't affect machine_Z. Fall back.
set_axis_aligned(Vec3d::UnitZ(), user_offset);
m_active = false;
return;
}
// Plane equation: gradient · slicing = user_offset - constant
const double K = user_offset - mz.constant;
m_normal = mz.gradient / cmag;
m_offset = K / cmag;
m_active = true;
return;
}
case FirstLayerPlaneMode::Auto:
// Should have been resolved above.
m_active = false;
return;
}
m_active = false;
}
double FirstLayerPlane::distance_from_plane(const Vec3d &point_slicing_mm) const
{
return m_normal.dot(point_slicing_mm) - m_offset;
}
bool FirstLayerPlane::is_first_layer(const Vec3d &point_slicing_mm,
double first_layer_height_mm) const
{
if (!m_active)
return false;
return distance_from_plane(point_slicing_mm) < first_layer_height_mm;
}
int FirstLayerPlane::effective_layer_index(const Vec3d &point_slicing_mm) const
{
if (!m_active)
return INT_MAX / 2; // Effectively "way past first layer".
double d = distance_from_plane(point_slicing_mm);
if (d <= 0.0)
return 0;
return int(std::floor(d / m_thickness_mm));
}
int FirstLayerPlane::min_effective_index_for_xy_bbox(
const BoundingBoxf &xy_bbox_mm, double slicing_z_mm) const
{
if (!m_active)
return INT_MAX / 2;
// For the rectangular bbox in (x, y) at fixed z, the smallest value of
// (n.x*x + n.y*y + n.z*z - offset) is achieved at one of the four
// corners, with the smaller component picked when the corresponding
// normal coefficient is positive.
const double x_for_min = (m_normal.x() >= 0.0)
? xy_bbox_mm.min.x() : xy_bbox_mm.max.x();
const double y_for_min = (m_normal.y() >= 0.0)
? xy_bbox_mm.min.y() : xy_bbox_mm.max.y();
const double dmin = m_normal.x() * x_for_min
+ m_normal.y() * y_for_min
+ m_normal.z() * slicing_z_mm
- m_offset;
if (dmin <= 0.0)
return 0;
return int(std::floor(dmin / m_thickness_mm));
}
int FirstLayerPlane::min_effective_index_for_bbox3(
const BoundingBoxf3 &bbox_mm) const
{
if (!m_active)
return INT_MAX / 2;
const double x_for_min = (m_normal.x() >= 0.0)
? bbox_mm.min.x() : bbox_mm.max.x();
const double y_for_min = (m_normal.y() >= 0.0)
? bbox_mm.min.y() : bbox_mm.max.y();
const double z_for_min = (m_normal.z() >= 0.0)
? bbox_mm.min.z() : bbox_mm.max.z();
const double dmin = m_normal.x() * x_for_min
+ m_normal.y() * y_for_min
+ m_normal.z() * z_for_min
- m_offset;
if (dmin <= 0.0)
return 0;
return int(std::floor(dmin / m_thickness_mm));
}
} // namespace Slic3r

View File

@@ -0,0 +1,76 @@
#ifndef slic3r_FirstLayerPlane_hpp_
#define slic3r_FirstLayerPlane_hpp_
#include "libslic3r.h"
#include "Point.hpp"
#include "BoundingBox.hpp"
#include "PrintConfig.hpp"
namespace Slic3r {
// Decides which extrusions get "first layer" treatment (no fan, slow speed,
// initial-layer accel/jerk, deferred temperature drop) by reference to a
// configurable plane in slicing-frame coordinates rather than the slicing
// layer index.
//
// On a normal flat-bed printer the plane is XY at slicing_Z = 0 and the
// evaluator is INACTIVE — every call site short-circuits back to the legacy
// `Layer::id() == 0` test. On a belt printer with a Z-from-Y shear the
// belt surface (machine_Z = 0) maps to a plane in slicing-frame coordinates
// derived from the gcode axis remap, so layer-index-based detection no
// longer matches the physical first printed surface.
//
// Plane representation: unit normal `n` (slicing frame) and offset along
// the normal such that the plane equation is `n · p == offset`. Signed
// perpendicular distance is `d(p) = n · p - offset`. Positive distance
// means "away from the belt surface", negative means "below the plane".
class FirstLayerPlane
{
public:
explicit FirstLayerPlane(const PrintConfig &config);
// Inactive when the legacy XY layer-index path should be used. This
// covers all non-belt printers and any belt printer where the user
// explicitly picked XY mode.
bool is_active() const { return m_active; }
FirstLayerPlaneMode effective_mode() const{ return m_mode; }
double band_thickness_mm() const { return m_thickness_mm; }
const Vec3d & normal() const { return m_normal; }
double plane_offset() const { return m_offset; }
// Signed perpendicular distance from a slicing-frame point to the plane.
double distance_from_plane(const Vec3d &point_slicing_mm) const;
// True if perpendicular distance < first_layer_height_mm. When the
// evaluator is inactive this returns false (call sites should fall back
// to the legacy per-layer path before reaching this function).
bool is_first_layer(const Vec3d &point_slicing_mm,
double first_layer_height_mm) const;
// floor((distance - 0) / band_thickness), clamped to [0, +inf). Used
// for "first N layers" thresholds (fan, slow_down_layers). Returns 0
// for points within the band. Returns INT_MAX/2 when inactive.
int effective_layer_index(const Vec3d &point_slicing_mm) const;
// Min effective index over a 2D bbox at a fixed slicing_Z. Used for
// layer-level decisions (e.g. temperature transition gate) where we
// don't want to walk every extrusion in the layer. For axis-aligned
// planes this is exact; for tilted planes it's a tight lower bound
// (the plane projection of the bbox's extreme corner).
int min_effective_index_for_xy_bbox(const BoundingBoxf &xy_bbox_mm,
double slicing_z_mm) const;
// Same as above but the bbox spans a Z range too.
int min_effective_index_for_bbox3(const BoundingBoxf3 &bbox_mm) const;
private:
bool m_active = false;
FirstLayerPlaneMode m_mode = FirstLayerPlaneMode::XY;
Vec3d m_normal = Vec3d::UnitZ(); // unit, slicing frame
double m_offset = 0.0; // n·p == m_offset
double m_thickness_mm = 0.0;
};
} // namespace Slic3r
#endif // slic3r_FirstLayerPlane_hpp_

View File

@@ -78,7 +78,7 @@ public:
Standard_Boolean UserBreak() override { return should_stop.load(); }
void Show(const Message_ProgressScope&, const Standard_Boolean) override {
std::cout << "Progress: " << GetPosition() << "%" << std::endl;
std::cout << "Progress: " << std::fixed << std::setprecision(2) << 100.0 * GetPosition() << "%" << std::endl;
}
private:
std::atomic<bool>& should_stop;

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More