Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44a3033a96 |
@@ -262,9 +262,9 @@ and a band is not a "gesture" in the `CadLevel::Gesture` sense because nothing h
|
||||
|---|---|---|---|---|---|
|
||||
| `Move` | — | `update_hover` / `update_solid_hover` (**non-consuming**, returns false) | — | passthrough | hover only asks for a repaint, `:10022-10025` |
|
||||
| `LeftDown` | orbit may begin | latch press, **return false** | — | consume-or-orbit is the canvas's call | `:10058-10063`; consuming here killed orbit once already |
|
||||
| `LeftDrag` > 8 px | — | start + drive band, **consume**, when Shift is held or the left button has no camera action | — | otherwise the left button's drag action (Preferences > Control) | the band is Prepare's Shift+left-drag rectangle selection |
|
||||
| `LeftDrag` > 8 px | — | start + drive band, **consume** | — | no longer orbits in this canvas | middle-drag orbits, right-drag pans (`:10013-10016`) |
|
||||
| `LeftUp` | — | commit pick **or** resolve band | — | — | `:10035-10041` |
|
||||
| `MiddleDrag` / `RightDrag` | — | must not see it | — | the button's drag action (Preferences > Control) | camera gestures never reach the FSM; a right press reaches the tool only once its release shows it was a click |
|
||||
| `MiddleDrag` / `RightDrag` | — | must not see it | — | orbit / pan | camera gestures never reach the FSM |
|
||||
| `RightClick` | — | — | offer menu | — | `snaporca-xmh6` open: a right-click that only clears the sketch selection eats the offer |
|
||||
| `Esc` | — | — | `escape()` ladder | — | one route whatever holds focus (`:4228-4231`) |
|
||||
| `Del` / `Backspace` | — | `delete_selected_or_last_sketch_entity()` | char hook | — | `:4260` |
|
||||
|
||||
@@ -135,7 +135,7 @@ contract between them is stated in code rather than spread across handlers.
|
||||
| --- | --- | --- |
|
||||
| `Transient` | a value field or a popup menu | closes it; the tool stays armed |
|
||||
| `Gesture` | an uncommitted delta — an entity being drawn, a body being dragged | reverts it; committed work is untouched |
|
||||
| `Tool` | a feature card, Sketch waiting for its plane, an armed sketch tool, a constrain session | exits it; drawn entities survive |
|
||||
| `Tool` | a feature card, an armed sketch tool, a constrain session | exits it; drawn entities survive |
|
||||
| `Idle` | nothing transient | clears the selection, a Feature tree or Bodies row included; leaves a sketch session only if it is empty |
|
||||
|
||||
`cad_escape_level()` is a `constexpr` free function over a POD of four booleans rather than a
|
||||
@@ -149,66 +149,26 @@ explicit selection, the sketch ribbon's Cancel, which asks first, or `Ctrl+Z`. A
|
||||
*session* is deliberately not a `Tool` level; it is the environment the `Idle` level lives in,
|
||||
which makes the destructive path unrepresentable rather than merely unlikely.
|
||||
|
||||
A body Move is the one `Gesture` that outlives the press: its gizmo stays up between drags until
|
||||
Confirm keeps the placement or `Esc` or Cancel puts the body back. Until then the selection is
|
||||
held — a click off the gizmo only steers the camera — and undo is refused, since the placement
|
||||
is not in the history. Anything that starts another edit (a feature card, a sketch, placing
|
||||
imported art or text, another body's Move, a rebuild) keeps the placement, as switching gizmos
|
||||
keeps a move in Prepare. The panel ends the Move in one place (`DesignPanel::end_body_move`), so
|
||||
the gizmo, the Move / Rotate card and the ✓/✗ cannot outlive one another.
|
||||
|
||||
Right-click is read at button-up against one budget, 3 px of drift, applied to the whole press
|
||||
rather than to its end points: a press that wandered past the budget at any moment is
|
||||
navigation, even if it comes back to where it started, which is what stops a slow, careful
|
||||
orbit from ending in a menu. There is no time budget — a gesture that means something different
|
||||
when it is slow is exactly what the interaction charter rules out. The raycast uses the press
|
||||
position, not the release. The sketch tool sees a right press only once the release has shown it
|
||||
was a click: the press itself goes to the camera, which may pan or orbit with that button, and the
|
||||
canvas replays it to the tool on a stationary release. A tool that uses the click (to terminate a
|
||||
chain, say) keeps the menu closed. Past either budget the event is navigation, and navigation
|
||||
does not transition the state machine.
|
||||
position, not the release. An armed sketch tool that already consumed the right
|
||||
button (to terminate a chain, say) declines to also open a menu, through a read-and-clear flag.
|
||||
Past either budget the event is navigation, and navigation does not transition the state
|
||||
machine.
|
||||
|
||||
Navigation itself is Prepare's: the camera reads the drag actions set in Preferences > Control
|
||||
for each button, and in the Touchpad camera style a move with Alt held orbits and one with Shift
|
||||
held pans, whatever tool is armed. The left button is shared with picking and drawing, so a tool
|
||||
handle or a press that draws takes it first, as a gizmo does in Prepare; a whole body is swept
|
||||
with a rectangle on plain left-drag only while no camera action is assigned to the left button,
|
||||
and with Shift+left-drag otherwise — Prepare's own rectangle selection.
|
||||
for each button. The left button is shared with picking, so a whole body is swept with a
|
||||
rectangle on plain left-drag only while no camera action is assigned to it, and with
|
||||
Shift+left-drag otherwise — Prepare's own rectangle selection.
|
||||
|
||||
Entering a sketch changes two things at once so the mode is legible: a banner above the
|
||||
Entering a sketch changes three things at once so the mode is legible: a banner above the
|
||||
canvas (a sibling of the canvas, not a child over it — on GTK a child window over a
|
||||
`wxGLCanvas` is a native window and does not reliably stack over GL), and `N` to look normal to
|
||||
the plane. The printer bed stays: there is no sketch grid, so the plate grid is the only ground
|
||||
reference a sketch has. Code that changes either belongs with a change to this section.
|
||||
|
||||
Sketch mode is never entered without a plane under it, so the banner, the sketch keys and the
|
||||
sketch offer always have a session to act on. Sketch on a picked flat face or reference plane opens
|
||||
the session on it at once. With nothing picked it stays in Feature mode and waits for one — an
|
||||
armed `Tool`, left with `Esc` or ✗, and ended by anything that starts another edit — and the
|
||||
reference plane or flat face clicked next opens the session. A picked plane is a selection like a
|
||||
face: the sketch on it uses it up, and `Esc` or a click on nothing lets go of it, so a plane that
|
||||
can no longer be seen never decides where the next sketch goes.
|
||||
|
||||
The reference planes — XY, XZ and YZ through the modeling origin, with their half-axes — are
|
||||
drawn on demand, because three translucent squares over every model are noise once they are not
|
||||
the thing being picked. Sketch brings them up while it waits for a plane, which is exactly when
|
||||
they are picked, and the session the pick opens takes them away; a live session draws none. The
|
||||
Feature tree's Origin row keeps them up outside a sketch. Its state is a view preference in
|
||||
AppConfig rather than part of the recipe, so it costs the project format nothing. The Plane tool
|
||||
keeps its own rule: the planes and the datums as Offset bases, and nothing for the other methods,
|
||||
where a click on a plane would rewrite the datum's references. The `P` and `A` keys are a
|
||||
separate, unpickable view helper and do not follow the Origin row.
|
||||
|
||||
The Bed row, under the Origin row, is the printer bed's switch in the same way: it draws or hides
|
||||
the bed and its plate grid in every mode. It is a view preference in AppConfig too, and the bed is
|
||||
shown until it is turned off.
|
||||
|
||||
The two rows are view switches, not history, and the tree says so: they sit unframed on the Feature
|
||||
tree's card, above the features' own framed list, and stay put while the features scroll. A click
|
||||
never selects either row, since a selected Origin or Bed would have nothing to edit, move or
|
||||
delete; the eye and the right-click menu are the only targets, and a row's label dims while its
|
||||
thing is hidden, as a hidden body's does. Because the block never takes the focus, `Ctrl+Shift+O`
|
||||
and `Ctrl+Shift+B` flip the Origin and the Bed from the keyboard.
|
||||
`wxGLCanvas` is a native window and does not reliably stack over GL), the printer bed muted so
|
||||
a plate grid is never read as a sketch grid, and `N` to look normal to the plane. Code that
|
||||
changes any of the three belongs with a change to this section.
|
||||
|
||||
## Rendering the bodies
|
||||
|
||||
@@ -229,15 +189,6 @@ degenerate edges are left out (`GeometryEngine::display_edges`), and the polylin
|
||||
once per shape, keyed by its `TShape`, because a recompute that leaves a body unchanged is the
|
||||
common case.
|
||||
|
||||
While a feature card is open, its preview ghost is the whole model the candidate would produce,
|
||||
drawn translucent over the bodies, so every face the feature leaves alone is in both at the same
|
||||
depth. The ghost is drawn with a depth bias that pushes it back (`GLVolume::depth_bias`), so on a shared face
|
||||
the body always wins instead of the two copies z-fighting, and the ghost shows only where the
|
||||
result reaches past the bodies. Material a feature removes lies inside the old solid and would not
|
||||
show at all, so the tools whose result mostly coincides with the body — Fillet/Chamfer, Draft,
|
||||
Hole and the Mate hover — hide the bodies once the preview is valid and draw the result alone,
|
||||
opaque.
|
||||
|
||||
## Showing what is selected
|
||||
|
||||
A selection is drawn on the faces it names, never as a tint over the body: a translucent
|
||||
@@ -263,17 +214,7 @@ replay costs up to a recompute, so the panel finds the faces once per row and to
|
||||
generation, off the UI thread, and only while no feature card is open. One selection is live at
|
||||
a time: a viewport pick clears the feature row and a feature row clears the viewport pick, as the
|
||||
Feature tree and Bodies list do between themselves. `Esc`, a click on empty space and an
|
||||
empty rubber band all let go of it, whichever list or pick made it — except while a body Move is
|
||||
open, which holds the selection until it ends (see the interaction contract).
|
||||
|
||||
Zoom to selection, on a Feature tree or Bodies row and in its right-click menu, frames one thing
|
||||
along the current view direction, as the canvas's Fit button frames the selection. On a body it
|
||||
frames the body whole, hidden or not, from its display mesh: the viewport never selects a hidden
|
||||
body, so the selection cannot stand in for it. On a sketch it frames the sketch's own geometry,
|
||||
drawn, consumed or suppressed; on any other feature, the faces the feature made, found as the row
|
||||
highlight finds them and from the same cache. From the offer it frames whatever the selection is,
|
||||
a body again included. A feature that is not a sketch and makes no faces, such as a datum plane
|
||||
or a suppressed Extrude, has no Zoom to selection.
|
||||
empty rubber band all let go of it, whichever list or pick made it.
|
||||
|
||||
## Following the app
|
||||
|
||||
@@ -290,21 +231,9 @@ The tab is a page of Orca's main window and answers to the same settings as Prep
|
||||
- **Sidebar icons.** Every clickable icon in the sidebar shows a hover chip. The card-header and
|
||||
constraint-row buttons are Orca's self-painted `Button`, because a native button cannot take a
|
||||
hover background on macOS. The Feature tree and Bodies lists are a custom-drawn
|
||||
`DesignRowList` rather than a `wxTreeCtrl`, so each row carries its own actions — Zoom to
|
||||
selection, Edit, Show/hide and Delete on a feature, Zoom to selection, Move, Show/hide and
|
||||
Delete on a body, and only Show/hide on the Origin and Bed rows, a separate non-selectable list
|
||||
above the features — and the eye shows whether that row is hidden. A feature with nothing to
|
||||
frame keeps a blank cell where Zoom to selection would be, so every icon stays in its column.
|
||||
- **Plates.** This is the one thing the tab does not follow. The canvas has a bed of its own at
|
||||
the printer bed's home position, whichever plate Prepare has current, and a new document's
|
||||
modeling origin is that bed's centre. A bed that followed the current plate would slide out
|
||||
from under a design: the origin is fixed once per document, baked into every sketch plane and
|
||||
saved in the recipe, while the current plate can change between visits. Commit to Plate does
|
||||
not need it either, since the committed object is placed on an empty spot of the current
|
||||
plate. What the canvas does read from the plate is moved onto its bed: the exclude areas, the
|
||||
plate box the camera orbits about when nothing is picked (`GLCanvas3D::_current_plate_box`),
|
||||
and the first view, which starts from Prepare's camera turned to the tab's iso view: the CAD
|
||||
isometric from the front-right corner that Home returns to, not Prepare's front-left one.
|
||||
`DesignRowList` rather than a `wxTreeCtrl`, so each row carries its own actions — Edit,
|
||||
Show/hide and Delete on a feature, Move, Show/hide and Delete on a body — and the eye shows
|
||||
whether that row is hidden.
|
||||
- **Viewport text.** The status line and the active tool's values are drawn by the canvas in
|
||||
its ImGui pass, so they go with the canvas: a top-level window over GL does not follow its
|
||||
frame and was left floating over other applications.
|
||||
@@ -327,12 +256,12 @@ permanent row index, verbs that do not apply shown disabled **in place with thei
|
||||
rather than removed. The invariant is that a verb's row index is identical in every selection
|
||||
where it appears and that adding a verb never moves an existing one — the hand learns the
|
||||
position, so the menu is never re-sorted, compacted or adaptively ordered. Above the families
|
||||
sits one *flat* row, holding Rename, Color and Zoom to selection — what a selection is opened for
|
||||
most: its verbs are items of their own at the top of the menu rather than a family's submenu. It
|
||||
is appended after the eight, so it moved no existing index, and it reads the same from the
|
||||
viewport and from a row of the Bodies list.
|
||||
sits one *flat* row, holding Rename and Color — what a selection is opened for most: its verbs are
|
||||
items of their own at the top of the menu rather than a family's submenu. It is appended after
|
||||
the eight, so it moved no existing index, and it reads the same from the viewport and from a row
|
||||
of the Bodies list.
|
||||
|
||||
An invariant across 93 verbs and 20 selection kinds does not survive by review, so the map
|
||||
An invariant across 92 verbs and 20 selection kinds does not survive by review, so the map
|
||||
exists once, as data: `scripts/CAD/tool_atlas.json` carries every verb with its row, key, icon,
|
||||
accepted selections, preconditions and refusal string, and `scripts/CAD/gen_offer_table.py`
|
||||
emits `src/slic3r/GUI/CAD/DesignOffer.hpp` from it. The header is checked in and never
|
||||
|
||||
@@ -36,13 +36,8 @@ override is not available in these profiles. The source's `EXCLUDE_E_START` and
|
||||
`EXCLUDE_E_END` internal markers become comments rather than printer commands.
|
||||
|
||||
Pressure-advance restoration and automatic pressure-advance emission use the
|
||||
selected filament preset's settings. The INDX filament presets include
|
||||
`fdm_filament_template_indx`, whose start G-code sets the filament's pressure
|
||||
advance with `M572` and then starts the firmware's automatic calibration with
|
||||
`M573 R`, the commands PrusaSlicer emits after a tool change; the station purge
|
||||
disables pressure advance before it. The template also carries Prusa's
|
||||
multi-tool ramming and a 10 mm³ minimal purge. These profiles do not impose
|
||||
machine-owned filament overrides. Dock-fan control retains the source's material and layer
|
||||
selected filament preset's settings. These profiles do not impose machine-owned
|
||||
filament overrides. Dock-fan control retains the source's material and layer
|
||||
conditions; shutdown parks the tool and turns off the used heaters and dock fan.
|
||||
|
||||
## Configuration boundaries
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"><path d="M2 9 14 9 22 15 10 15Z"/><path d="M2 9V11L10 17H22V15M10 15V17"/><path d="M6 9 14 15M10 9 18 15M6 12H18"/></svg>
|
||||
|
Before Width: | Height: | Size: 301 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"><path d="M3.15 19.57V4.43A1.28 1.28 0 0 1 4.43 3.15H17.05L20.85 6.95V19.57A1.28 1.28 0 0 1 19.57 20.85H4.43A1.28 1.28 0 0 1 3.15 19.57ZM8.2 3.15V5.68A1.28 1.28 0 0 0 9.48 6.95H14.52A1.28 1.28 0 0 0 15.8 5.68V3.15M17.05 20.85V15.8A1.28 1.28 0 0 0 15.8 14.53H8.2A1.28 1.28 0 0 0 6.95 15.8V20.85"/></svg>
|
||||
|
Before Width: | Height: | Size: 481 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8.08,10.74 8.08,5.4M8.08,10.74 15.55,4.87M17.15,10.2 15.55,4.87M4.88,8.6 8.62,20.87M17.15,10.2 20.89,16.07M8.08,10.74 12.78,15.54 17.15,10.2M17.15,19.8 12.78,15.54 8.62,20.87M4.88,8.6 8.08,10.74 17.15,10.2 19.82,7M8.08,10.74 8.62,20.87M17.15,10.2 17.15,19.8" fill="none" stroke="#949494" stroke-width="0.6" stroke-linecap="round" stroke-linejoin="round"/><polygon points="4.88,8.6 8.08,5.4 15.55,4.87 19.82,7 20.89,16.07 17.15,19.8 8.62,20.87 4.35,17.14" fill="none" stroke="#949494" stroke-width="0.85" stroke-linejoin="round"/><polygon points="2.84,4.68 7.32,4.68 7.32,2.84 11.29,5.86 7.32,8.88 7.32,7.04 2.84,7.04" style="fill:#009688;stroke:#009688;stroke-width:0.4;stroke-linejoin:round"/></svg>
|
||||
|
Before Width: | Height: | Size: 794 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"><rect x="3.15" y="3.15" width="17.7" height="17.7" rx="1.28"/><path d="M7.6 12H16.4M12 7.6V16.4"/></svg>
|
||||
|
Before Width: | Height: | Size: 284 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"><path d="M5.88 3.88H17.16M3.88 5.88V17.16M19.16 5.88V12.38M5.88 19.16H12.38M9.85 7.85H13.2M7.85 9.85V13.2M14.92 9.85A7.35 7.35 0 0 1 9.85 14.92"/><path d="M2.83 2.83h2.1v2.1h-2.1zM18.11 2.83h2.1v2.1h-2.1zM2.83 18.11h2.1v2.1h-2.1zM6.8 6.8h2.1v2.1h-2.1zM14.15 6.8h2.1v2.1h-2.1zM6.8 14.15h2.1v2.1h-2.1z" fill="#949494" stroke="none"/><polygon points="16.01,13.19 18.3,13.19 18.3,16.01 21.12,16.01 21.12,18.3 18.3,18.3 18.3,21.12 16.01,21.12 16.01,18.3 13.19,18.3 13.19,16.01 16.01,16.01" style="fill:#009688;stroke:#009688;stroke-width:0.4;stroke-linejoin:round"/></svg>
|
||||
|
Before Width: | Height: | Size: 747 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 1.5 23 23"><path d="M3.0 9.0 L16.0 9.0 L16.0 21.0 L3.0 21.0 ZM3.0 9.0 L7.0 5.0 L20.0 5.0 L16.0 9.0M20.0 5.0 L20.0 17.0 L16.0 21.0" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"/><path d="M6.168410256410256 13.423897435897436V13.868410256410256Q5.908923076923077 13.744307692307691 5.678769230769231 13.683384615384615Q5.448615384615385 13.622461538461538 5.23425641025641 13.622461538461538Q4.861948717948718 13.622461538461538 4.66 13.766871794871793Q4.458051282051283 13.91128205128205 4.458051282051283 14.177538461538461Q4.458051282051283 14.400923076923076 4.592307692307693 14.514871794871794Q4.726564102564103 14.628820512820512 5.101128205128205 14.69876923076923L5.3764102564102565 14.755179487179486Q5.886358974358975 14.852205128205128 6.128923076923078 15.09702564102564Q6.37148717948718 15.341846153846152 6.37148717948718 15.75251282051282Q6.37148717948718 16.242153846153844 6.043179487179488 16.49487179487179Q5.7148717948717955 16.747589743589742 5.080820512820513 16.747589743589742Q4.841641025641026 16.747589743589742 4.572000000000001 16.693435897435897Q4.302358974358975 16.639282051282052 4.013538461538462 16.53323076923077V16.063897435897434Q4.291076923076924 16.219589743589744 4.557333333333334 16.2985641025641Q4.823589743589745 16.37753846153846 5.080820512820513 16.37753846153846Q5.471179487179487 16.37753846153846 5.683282051282052 16.224102564102562Q5.895384615384616 16.070666666666664 5.895384615384616 15.786358974358974Q5.895384615384616 15.538153846153845 5.743076923076924 15.398256410256408Q5.590769230769231 15.258358974358973 5.243282051282051 15.188410256410256L4.965743589743591 15.134256410256409Q4.455794871794872 15.032717948717949 4.227897435897436 14.816102564102565Q4.000000000000001 14.599487179487179 4.000000000000001 14.213641025641024Q4.000000000000001 13.766871794871793 4.314769230769231 13.509641025641024Q4.629538461538462 13.252410256410256 5.182358974358975 13.252410256410256Q5.419282051282051 13.252410256410256 5.665230769230769 13.29528205128205Q5.911179487179488 13.338153846153846 6.168410256410256 13.423897435897436ZM6.615179487179487 13.313333333333333H9.46502564102564V13.696923076923076H8.269128205128204V16.682153846153845H7.811076923076923V13.696923076923076H6.615179487179487ZM9.905025641025642 13.313333333333333H12.035076923076925V13.696923076923076H10.360820512820514V14.69425641025641H11.965128205128206V15.077846153846153H10.360820512820514V16.2985641025641H12.075692307692309V16.682153846153845H9.905025641025642ZM13.280615384615384 13.687897435897435V14.953743589743588H13.85374358974359Q14.171897435897435 14.953743589743588 14.345641025641026 14.78902564102564Q14.519384615384615 14.624307692307692 14.519384615384615 14.319692307692307Q14.519384615384615 14.017333333333333 14.345641025641026 13.852615384615383Q14.171897435897435 13.687897435897435 13.85374358974359 13.687897435897435ZM12.824820512820512 13.313333333333333H13.85374358974359Q14.420102564102564 13.313333333333333 14.710051282051282 13.569435897435897Q15.0 13.82553846153846 15.0 14.319692307692307Q15.0 14.818358974358974 14.710051282051282 15.073333333333332Q14.420102564102564 15.32830769230769 13.85374358974359 15.32830769230769H13.280615384615384V16.682153846153845H12.824820512820512Z" fill="#949494" stroke="none"/><polygon points="2.72,5.99 7.02,5.99 7.02,4.22 10.82,7.12 7.02,10.01 7.02,8.25 2.72,8.25" style="fill:#009688;stroke:#009688;stroke-width:0.38;stroke-linejoin:round"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3.0 9.0 L16.0 9.0 L16.0 21.0 L3.0 21.0 ZM3.0 9.0 L7.0 5.0 L20.0 5.0 L16.0 9.0M20.0 5.0 L20.0 17.0 L16.0 21.0" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"/><path d="M6.168410256410256 13.423897435897436V13.868410256410256Q5.908923076923077 13.744307692307691 5.678769230769231 13.683384615384615Q5.448615384615385 13.622461538461538 5.23425641025641 13.622461538461538Q4.861948717948718 13.622461538461538 4.66 13.766871794871793Q4.458051282051283 13.91128205128205 4.458051282051283 14.177538461538461Q4.458051282051283 14.400923076923076 4.592307692307693 14.514871794871794Q4.726564102564103 14.628820512820512 5.101128205128205 14.69876923076923L5.3764102564102565 14.755179487179486Q5.886358974358975 14.852205128205128 6.128923076923078 15.09702564102564Q6.37148717948718 15.341846153846152 6.37148717948718 15.75251282051282Q6.37148717948718 16.242153846153844 6.043179487179488 16.49487179487179Q5.7148717948717955 16.747589743589742 5.080820512820513 16.747589743589742Q4.841641025641026 16.747589743589742 4.572000000000001 16.693435897435897Q4.302358974358975 16.639282051282052 4.013538461538462 16.53323076923077V16.063897435897434Q4.291076923076924 16.219589743589744 4.557333333333334 16.2985641025641Q4.823589743589745 16.37753846153846 5.080820512820513 16.37753846153846Q5.471179487179487 16.37753846153846 5.683282051282052 16.224102564102562Q5.895384615384616 16.070666666666664 5.895384615384616 15.786358974358974Q5.895384615384616 15.538153846153845 5.743076923076924 15.398256410256408Q5.590769230769231 15.258358974358973 5.243282051282051 15.188410256410256L4.965743589743591 15.134256410256409Q4.455794871794872 15.032717948717949 4.227897435897436 14.816102564102565Q4.000000000000001 14.599487179487179 4.000000000000001 14.213641025641024Q4.000000000000001 13.766871794871793 4.314769230769231 13.509641025641024Q4.629538461538462 13.252410256410256 5.182358974358975 13.252410256410256Q5.419282051282051 13.252410256410256 5.665230769230769 13.29528205128205Q5.911179487179488 13.338153846153846 6.168410256410256 13.423897435897436ZM6.615179487179487 13.313333333333333H9.46502564102564V13.696923076923076H8.269128205128204V16.682153846153845H7.811076923076923V13.696923076923076H6.615179487179487ZM9.905025641025642 13.313333333333333H12.035076923076925V13.696923076923076H10.360820512820514V14.69425641025641H11.965128205128206V15.077846153846153H10.360820512820514V16.2985641025641H12.075692307692309V16.682153846153845H9.905025641025642ZM13.280615384615384 13.687897435897435V14.953743589743588H13.85374358974359Q14.171897435897435 14.953743589743588 14.345641025641026 14.78902564102564Q14.519384615384615 14.624307692307692 14.519384615384615 14.319692307692307Q14.519384615384615 14.017333333333333 14.345641025641026 13.852615384615383Q14.171897435897435 13.687897435897435 13.85374358974359 13.687897435897435ZM12.824820512820512 13.313333333333333H13.85374358974359Q14.420102564102564 13.313333333333333 14.710051282051282 13.569435897435897Q15.0 13.82553846153846 15.0 14.319692307692307Q15.0 14.818358974358974 14.710051282051282 15.073333333333332Q14.420102564102564 15.32830769230769 13.85374358974359 15.32830769230769H13.280615384615384V16.682153846153845H12.824820512820512Z" fill="#949494" stroke="none"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.3 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#949494" stroke-width="0.85" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"/><path d="M6 10a4 4 0 0 1 4-4M15 15 21.5 21.5"/></svg>
|
||||
|
Before Width: | Height: | Size: 264 B |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Prusa",
|
||||
"version": "02.04.00.16",
|
||||
"version": "02.04.00.15",
|
||||
"force_update": "0",
|
||||
"description": "Prusa configurations",
|
||||
"machine_model_list": [
|
||||
@@ -1573,32 +1573,48 @@
|
||||
],
|
||||
"filament_list": [
|
||||
{
|
||||
"name": "Generic PC @Prusa",
|
||||
"sub_path": "filament/Generic PC @Prusa.json"
|
||||
"name": "Generic ASA @Prusa CORE One",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_common",
|
||||
"sub_path": "filament/fdm_filament_common.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_template_indx",
|
||||
"sub_path": "filament/fdm_filament_template_indx.json"
|
||||
"name": "Generic ASA @Prusa CORE One 0.6",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One 0.6.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_template_nextruder_pet",
|
||||
"sub_path": "filament/fdm_filament_template_nextruder_pet.json"
|
||||
"name": "Generic ASA @Prusa CORE One 0.8",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_template_nextruder_pet_hf",
|
||||
"sub_path": "filament/fdm_filament_template_nextruder_pet_hf.json"
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.4",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.4.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_template_nextruder_pla",
|
||||
"sub_path": "filament/fdm_filament_template_nextruder_pla.json"
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.5",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.5.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_template_nextruder_pla_hf",
|
||||
"sub_path": "filament/fdm_filament_template_nextruder_pla_hf.json"
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.6",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.6.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.8",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One 0.6",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One 0.6.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One 0.8",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_abs",
|
||||
@@ -1648,22 +1664,6 @@
|
||||
"name": "fdm_filament_tpu",
|
||||
"sub_path": "filament/fdm_filament_tpu.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One INDX",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One INDX.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PC @Prusa MK4 MMU3",
|
||||
"sub_path": "filament/Generic PC @Prusa MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ABS @Prusa MK3.5",
|
||||
"sub_path": "filament/Generic ABS @Prusa MK3.5.json"
|
||||
@@ -2160,38 +2160,6 @@
|
||||
"name": "Generic TPU HF @Prusa MK3.5",
|
||||
"sub_path": "filament/Generic TPU HF @Prusa MK3.5.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One 0.6",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One 0.6.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One 0.8",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.4",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.4.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.5",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.5.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.6",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.6.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa CORE One HF 0.8",
|
||||
"sub_path": "filament/Generic ASA @Prusa CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One 0.6",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One 0.6.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One 0.8",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ABS @Prusa MK4S HF0.4",
|
||||
"sub_path": "filament/Generic ABS @Prusa MK4S HF0.4.json"
|
||||
@@ -2244,10 +2212,6 @@
|
||||
"name": "Generic ABS HF @Prusa MINIIS 0.8",
|
||||
"sub_path": "filament/Generic ABS HF @Prusa MINIIS 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa MK4 MMU3",
|
||||
"sub_path": "filament/Generic ASA @Prusa MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa MK4S 0.6",
|
||||
"sub_path": "filament/Generic ASA @Prusa MK4S 0.6.json"
|
||||
@@ -2296,10 +2260,6 @@
|
||||
"name": "Prusament ASA @CORE One HF 0.8",
|
||||
"sub_path": "filament/Prusament ASA @CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament ASA @MK4 MMU3",
|
||||
"sub_path": "filament/Prusament ASA @MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament ASA @MK4S 0.6",
|
||||
"sub_path": "filament/Prusament ASA @MK4S 0.6.json"
|
||||
@@ -2432,10 +2392,6 @@
|
||||
"name": "Prusament PC Blend @CORE One HF 0.8",
|
||||
"sub_path": "filament/Prusament PC Blend @CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament PC Blend @MK4 MMU3",
|
||||
"sub_path": "filament/Prusament PC Blend @MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament PC Blend @MK4S 0.6",
|
||||
"sub_path": "filament/Prusament PC Blend @MK4S 0.6.json"
|
||||
@@ -2576,10 +2532,6 @@
|
||||
"name": "Prusament PETG @CORE One HF 0.8",
|
||||
"sub_path": "filament/Prusament PETG @CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament PETG @MK4 MMU3",
|
||||
"sub_path": "filament/Prusament PETG @MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament PETG @MK4S 0.6",
|
||||
"sub_path": "filament/Prusament PETG @MK4S 0.6.json"
|
||||
@@ -2716,10 +2668,6 @@
|
||||
"name": "Prusament PLA @CORE One HF 0.8",
|
||||
"sub_path": "filament/Prusament PLA @CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament PLA @MK4 MMU3",
|
||||
"sub_path": "filament/Prusament PLA @MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament PLA @MK4S 0.6",
|
||||
"sub_path": "filament/Prusament PLA @MK4S 0.6.json"
|
||||
@@ -2756,10 +2704,6 @@
|
||||
"name": "Prusament rPLA @CORE One 0.8",
|
||||
"sub_path": "filament/Prusament rPLA @CORE One 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament rPLA @MK4 MMU3",
|
||||
"sub_path": "filament/Prusament rPLA @MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Prusament rPLA @MK4S 0.6",
|
||||
"sub_path": "filament/Prusament rPLA @MK4S 0.6.json"
|
||||
@@ -2912,10 +2856,6 @@
|
||||
"name": "Generic ABS @Prusa CORE One HF 0.8",
|
||||
"sub_path": "filament/Generic ABS @Prusa CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ABS @Prusa MK4 MMU3",
|
||||
"sub_path": "filament/Generic ABS @Prusa MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic ASA @Prusa MK4S HF0.5",
|
||||
"sub_path": "filament/Generic ASA @Prusa MK4S HF0.5.json"
|
||||
@@ -2964,10 +2904,6 @@
|
||||
"name": "Generic PETG @Prusa CORE One HF 0.8",
|
||||
"sub_path": "filament/Generic PETG @Prusa CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PETG @Prusa MK4 MMU3",
|
||||
"sub_path": "filament/Generic PETG @Prusa MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA @Prusa MK4S HF0.5",
|
||||
"sub_path": "filament/Generic PLA @Prusa MK4S HF0.5.json"
|
||||
@@ -3012,10 +2948,6 @@
|
||||
"name": "Generic PLA @Prusa CORE One HF 0.8",
|
||||
"sub_path": "filament/Generic PLA @Prusa CORE One HF 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA @Prusa MK4 MMU3",
|
||||
"sub_path": "filament/Generic PLA @Prusa MK4 MMU3.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic TPU @Prusa CORE One 0.6",
|
||||
"sub_path": "filament/Generic TPU @Prusa CORE One 0.6.json"
|
||||
@@ -3023,6 +2955,14 @@
|
||||
{
|
||||
"name": "Generic TPU @Prusa CORE One 0.8",
|
||||
"sub_path": "filament/Generic TPU @Prusa CORE One 0.8.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PC @Prusa",
|
||||
"sub_path": "filament/Generic PC @Prusa.json"
|
||||
},
|
||||
{
|
||||
"name": "Generic PLA Silk @Prusa CORE One INDX",
|
||||
"sub_path": "filament/Generic PLA Silk @Prusa CORE One INDX.json"
|
||||
}
|
||||
],
|
||||
"machine_list": [
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "ASYz8yASE82tQDII",
|
||||
"filament_id": "OFY9muEs",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "mzZCm8XDmAR23YR6",
|
||||
"filament_id": "OFY9muEs",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "gJhX2KBpk4wfXIj0",
|
||||
"filament_id": "OFY9muEs",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "JEatvybG9xIkrPk3",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_indx"
|
||||
],
|
||||
"filament_cost": [
|
||||
"34.65"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "0k31oXq1pLQsHvrj",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"40"
|
||||
],
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Generic ABS @Prusa MK4 MMU3",
|
||||
"inherits": "Generic ABS @Prusa MK4",
|
||||
"from": "system",
|
||||
"setting_id": "uFmixo2FX1yxNsDB",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"35"
|
||||
]
|
||||
}
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "eKDfiVRE59itoppm",
|
||||
"filament_id": "OFLPAxz3",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "ZjHf5Vvtf4ESNnWb",
|
||||
"filament_id": "OFLPAxz3",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "aRDgUgQJWdNDJx5c",
|
||||
"filament_id": "OFLPAxz3",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "Q7fgojkHRZI0floy",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"40"
|
||||
],
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Generic ASA @Prusa MK4 MMU3",
|
||||
"inherits": "Generic ASA @Prusa MK4",
|
||||
"from": "system",
|
||||
"setting_id": "iq9bFkpmAOJ4ae4g",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"35"
|
||||
]
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Generic PC @Prusa MK4 MMU3",
|
||||
"inherits": "Generic PC @Prusa",
|
||||
"from": "system",
|
||||
"setting_id": "qMawlK9QPI7DcF8I",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
]
|
||||
}
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "7oUyjvRHLH4bJyX0",
|
||||
"filament_id": "OFYPdQJh",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "6HiIOGURZWwman1l",
|
||||
"filament_id": "OFYPdQJh",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "KKiug7A9NOQPe1m7",
|
||||
"filament_id": "OFYPdQJh",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "HbevqxqvYHuvRc3v",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_indx"
|
||||
],
|
||||
"filament_cost": [
|
||||
"27.82"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "W71PW5bpf7CV16D4",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"35"
|
||||
],
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Generic PETG @Prusa MK4 MMU3",
|
||||
"inherits": "Generic PETG @Prusa MK4",
|
||||
"from": "system",
|
||||
"setting_id": "lBiZBFpSXZNIp5XG",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"35"
|
||||
]
|
||||
}
|
||||
@@ -8,16 +8,12 @@
|
||||
"filament_id": "OFDSrzZ8",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One 0.6 nozzle",
|
||||
"Prusa CORE One MMU3 0.6 nozzle"
|
||||
"Prusa CORE One 0.6 nozzle"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"210"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"15"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"1.5"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "vniEPaoyABoAfLFa",
|
||||
"filament_id": "OFDSrzZ8",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle",
|
||||
"Prusa CORE One L HF 0.4 nozzle"
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "NPEs4gtBlKWupYZX",
|
||||
"filament_id": "OFDSrzZ8",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "SnfULjrWGCiA7ljq",
|
||||
"filament_id": "OFDSrzZ8",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
@@ -27,8 +24,5 @@
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"1.5"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "4qjcaIf1vk3K1x4Z",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_indx"
|
||||
],
|
||||
"filament_cost": [
|
||||
"25.4"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "r2i4c7DsYXYIMVCX",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"20"
|
||||
],
|
||||
@@ -20,7 +17,8 @@
|
||||
"Prusa CORE One L 0.4 nozzle",
|
||||
"Prusa CORE One MMU3 0.4 nozzle",
|
||||
"Prusa CORE One MMU3 0.25 nozzle",
|
||||
"Prusa CORE One MMU3 0.3 nozzle"
|
||||
"Prusa CORE One MMU3 0.3 nozzle",
|
||||
"Prusa CORE One MMU3 0.6 nozzle"
|
||||
],
|
||||
"fan_cooling_layer_time": [
|
||||
"40"
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Generic PLA @Prusa MK4 MMU3",
|
||||
"inherits": "Generic PLA @Prusa MK4",
|
||||
"from": "system",
|
||||
"setting_id": "kZvIh84niJ487FsY",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
]
|
||||
}
|
||||
@@ -29,8 +29,5 @@
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"15"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"1.5"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "eKla6su22rYaL9iz",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_indx"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"1",
|
||||
"1",
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"from": "system",
|
||||
"setting_id": "F9lNHyhZwZi7aD74",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"20"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "tXktQXr79am1s5UL",
|
||||
"filament_id": "OFmFwUWM",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "YbyojtjXvEtI4Tt3",
|
||||
"filament_id": "OFmFwUWM",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "35H9TLr1p2Jy767g",
|
||||
"filament_id": "OFmFwUWM",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "UUTjJ4Y8St3c87jD",
|
||||
"filament_id": "OFmFwUWM",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"40"
|
||||
],
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Prusament ASA @MK4 MMU3",
|
||||
"inherits": "Prusament ASA @MK4",
|
||||
"from": "system",
|
||||
"setting_id": "IRJ2dtBgjCMfmpOH",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"35"
|
||||
]
|
||||
}
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "sNGgucQjiFXwuFkq",
|
||||
"filament_id": "OF4MZtnE",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"40"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "pEsP537TBR5kozQB",
|
||||
"filament_id": "OFvDbkFq",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "3IfLi1ZVCKKbEBUW",
|
||||
"filament_id": "OFvDbkFq",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "Q8qWw2G7l2UvxGut",
|
||||
"filament_id": "OFvDbkFq",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "x1SkWhSSkVVIPwCF",
|
||||
"filament_id": "OFvDbkFq",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"40"
|
||||
],
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Prusament PC Blend @MK4 MMU3",
|
||||
"inherits": "Prusament PC Blend @MK4",
|
||||
"from": "system",
|
||||
"setting_id": "gmNuCspHHxgP6zH8",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
]
|
||||
}
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "B8Cm9l8i9osp5J2q",
|
||||
"filament_id": "OFdO6vpt",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"40"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "lwT1VxW5OkY36kUX",
|
||||
"filament_id": "OFkR8E2c",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "XAgW7fElXxhaKaBT",
|
||||
"filament_id": "OFkR8E2c",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.5 nozzle"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "6aTGEZj2EmpTR1mu",
|
||||
"filament_id": "OFkR8E2c",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "LSvba9ds3XTwDMCG",
|
||||
"filament_id": "OFkR8E2c",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"35"
|
||||
],
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Prusament PETG @MK4 MMU3",
|
||||
"inherits": "Prusament PETG @MK4",
|
||||
"from": "system",
|
||||
"setting_id": "7DQ6YEKyQKYDTKtE",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pet"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"35"
|
||||
]
|
||||
}
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "2viuOmBvXuQm2FwV",
|
||||
"filament_id": "OFkR8E2c",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_indx"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"1"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "mf4Muog4IcsgkYoA",
|
||||
"filament_id": "OFnO4wnf",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla_hf"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One HF 0.4 nozzle",
|
||||
"Prusa CORE One L HF 0.4 nozzle"
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "PuujUMjNKLZvZNAH",
|
||||
"filament_id": "OFnO4wnf",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"20"
|
||||
],
|
||||
@@ -107,11 +104,5 @@
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"20"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"100"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"100"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Prusament PLA @MK4 MMU3",
|
||||
"inherits": "Prusament PLA @MK4",
|
||||
"from": "system",
|
||||
"setting_id": "MsDcN4npnmLRXOjm",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"100"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"100"
|
||||
]
|
||||
}
|
||||
@@ -6,9 +6,6 @@
|
||||
"setting_id": "B2UB9QUbbjpn12Ka",
|
||||
"filament_id": "OFnO4wnf",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_indx"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"1"
|
||||
],
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "085dGkrnPhatF07x",
|
||||
"filament_id": "OFh7mvPO",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"20"
|
||||
],
|
||||
@@ -108,11 +105,5 @@
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"20"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"60"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"60"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,16 +8,12 @@
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Prusa CORE One 0.6 nozzle",
|
||||
"Prusa CORE One HF 0.6 nozzle",
|
||||
"Prusa CORE One MMU3 0.6 nozzle"
|
||||
"Prusa CORE One HF 0.6 nozzle"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"14"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"15"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"1.5"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"setting_id": "Bw6H4vFnq7YExyLd",
|
||||
"filament_id": "OFWRITFw",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"chamber_temperature": [
|
||||
"20"
|
||||
],
|
||||
@@ -25,7 +22,8 @@
|
||||
"Prusa CORE One HF 0.5 nozzle",
|
||||
"Prusa CORE One MMU3 0.4 nozzle",
|
||||
"Prusa CORE One MMU3 0.25 nozzle",
|
||||
"Prusa CORE One MMU3 0.3 nozzle"
|
||||
"Prusa CORE One MMU3 0.3 nozzle",
|
||||
"Prusa CORE One MMU3 0.6 nozzle"
|
||||
],
|
||||
"fan_cooling_layer_time": [
|
||||
"40"
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Prusament rPLA @MK4 MMU3",
|
||||
"inherits": "Prusament rPLA @MK4",
|
||||
"from": "system",
|
||||
"setting_id": "wKhvyGpgjmW6glLj",
|
||||
"instantiation": "true",
|
||||
"include": [
|
||||
"fdm_filament_template_nextruder_pla"
|
||||
],
|
||||
"compatible_printers": [
|
||||
"Prusa MK4 MMU3 0.4 nozzle",
|
||||
"Prusa MK4 MMU3 0.6 nozzle",
|
||||
"Prusa MK4 MMU3 HF0.4 nozzle"
|
||||
]
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "fdm_filament_template_indx",
|
||||
"from": "system",
|
||||
"instantiation": "false",
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"30"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"18"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"10"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"M572 S{pressure_advance[filament_extruder_id]} ; Pressure advance\nM573 R"
|
||||
]
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "fdm_filament_template_nextruder_pet",
|
||||
"from": "system",
|
||||
"instantiation": "false",
|
||||
"filament_ramming_parameters": [
|
||||
"250 100 42.4194 42.4194 42.4194 42.4194 42.4194| 0.05 42.4387 0.45 42.4387 0.95 42.4387 1.45 42.4387 1.95 42.4387 2.45 42.4387 2.95 42.4387 3.45 42.4387 3.95 42.4387 4.45 42.4387 4.95 42.4387"
|
||||
],
|
||||
"filament_loading_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"60"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"60"
|
||||
],
|
||||
"filament_cooling_moves": [
|
||||
"3"
|
||||
],
|
||||
"filament_cooling_initial_speed": [
|
||||
"5"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"2.5"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
"filament_stamping_loading_speed": [
|
||||
"26.5"
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "fdm_filament_template_nextruder_pet_hf",
|
||||
"from": "system",
|
||||
"instantiation": "false",
|
||||
"filament_ramming_parameters": [
|
||||
"250 100 42.4194 42.4194| 0.05 42.4387 0.45 42.4387 0.95 42.4387 1.45 42.4387 1.95 42.4387 2.45 42.4387 2.95 42.4387 3.45 42.4387 3.95 42.4387 4.45 42.4387 4.95 42.4387"
|
||||
]
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "fdm_filament_template_nextruder_pla",
|
||||
"from": "system",
|
||||
"instantiation": "false",
|
||||
"filament_ramming_parameters": [
|
||||
"250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419"
|
||||
],
|
||||
"filament_loading_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"40"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"30"
|
||||
],
|
||||
"filament_cooling_moves": [
|
||||
"2"
|
||||
],
|
||||
"filament_cooling_initial_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"3.5"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
"filament_stamping_loading_speed": [
|
||||
"29"
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "fdm_filament_template_nextruder_pla_hf",
|
||||
"from": "system",
|
||||
"instantiation": "false",
|
||||
"filament_ramming_parameters": [
|
||||
"250 100 39.871 39.871| 0.05 39.9547 0.45 39.9547 0.95 39.9547 1.45 39.9547 1.95 39.9547 2.45 39.9547 2.95 39.9547 3.45 39.9547 3.95 39.9547 4.45 39.9547 4.95 39.9547"
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Prusa CORE One MMU3",
|
||||
"bed_model": "coreone_bed.stl",
|
||||
"bed_texture": "coreone.svg",
|
||||
"default_materials": "Generic ABS @Prusa CORE One;Generic ASA @Prusa CORE One;Generic PETG @Prusa CORE One;Generic PLA @Prusa CORE One;Generic PLA Silk @Prusa CORE One;Generic TPU @Prusa CORE One;Generic PLA @Prusa CORE One 0.6",
|
||||
"default_materials": "Generic ABS @Prusa CORE One;Generic ASA @Prusa CORE One;Generic PETG @Prusa CORE One;Generic PLA @Prusa CORE One;Generic PLA Silk @Prusa CORE One;Generic TPU @Prusa CORE One",
|
||||
"family": "Prusa",
|
||||
"hotend_model": "",
|
||||
"machine_tech": "FFF",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"printer_model": "Prusa MK4 MMU3",
|
||||
"default_filament_profile": [
|
||||
"Generic PLA @Prusa MK4 MMU3"
|
||||
"Generic PLA @System"
|
||||
],
|
||||
"default_print_profile": "0.20mm SPEED @MK4 MMU3 0.4",
|
||||
"printer_notes": "Don't remove the following keywords! These keywords are used in the \"compatible printer\" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_MODEL_MK4IS\nPRINTER_MODEL_MK4MMU3\nPG"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"printer_model": "Prusa MK4 MMU3",
|
||||
"printer_variant": "0.6",
|
||||
"default_filament_profile": [
|
||||
"Generic PLA @Prusa MK4 MMU3"
|
||||
"Generic PLA @System"
|
||||
],
|
||||
"default_print_profile": "0.25mm SPEED @MK4 MMU3 0.6",
|
||||
"printer_notes": "Don't remove the following keywords! These keywords are used in the \"compatible printer\" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_MODEL_MK4IS\nPRINTER_MODEL_MK4MMU3\nPG"
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "mk4_bed.stl",
|
||||
"bed_texture": "mk4is.svg",
|
||||
"hotend_model": "",
|
||||
"default_materials": "Generic PLA @Prusa MK4 MMU3;Generic PETG @Prusa MK4 MMU3;Generic ABS @Prusa MK4 MMU3"
|
||||
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"printer_model": "Prusa MK4 MMU3 HF",
|
||||
"default_filament_profile": [
|
||||
"Generic PLA @Prusa MK4 MMU3"
|
||||
"Generic PLA @System"
|
||||
],
|
||||
"default_print_profile": "0.20mm SPEED @MK4 MMU3 HF0.4",
|
||||
"printer_notes": "Don't remove the following keywords! These keywords are used in the \"compatible printer\" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_MODEL_MK4IS\nPRINTER_MODEL_MK4MMU3\nPG\nHF_NOZZLE"
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "mk4_bed.stl",
|
||||
"bed_texture": "mk4is.svg",
|
||||
"hotend_model": "",
|
||||
"default_materials": "Generic PLA @Prusa MK4 MMU3;Generic PETG @Prusa MK4 MMU3;Generic ABS @Prusa MK4 MMU3"
|
||||
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ def seed_datadir(datadir):
|
||||
# ~90% case expects. A ladder whose result depends on the developer's own preferences is not
|
||||
# a gate.
|
||||
app["auto_close_sketch_loops"] = True
|
||||
app["design_show_bed"] = True
|
||||
# SILENCE THE NETWORK PLUGIN PROMPT. Without this, GUI_App::post_init() re-raises "Bambu
|
||||
# Network Plug-in Required" from an IDLE event — after any modal sweep this driver does at
|
||||
# startup — and ShowModal() then runs a nested event loop. The app is alive, its window is
|
||||
@@ -481,14 +480,10 @@ def type_into_open_field(value, mark):
|
||||
def enter_sketch(timeout=180):
|
||||
"""Open a real sketch on a real plane, and PROVE it with the socket before drawing anything.
|
||||
|
||||
THE SEQUENCE MATTERS AND IT IS NOT OBVIOUS. The reference planes are hidden until Shift+S,
|
||||
with nothing picked, brings them up to choose from, so the plane is clicked AFTER it. That
|
||||
click opens the session on the plane and pops the tool offer, and a click outside a popup
|
||||
menu only closes it, so the spot is clicked twice, apart: the second click closes the offer,
|
||||
and inside the session it is empty canvas. No Escape — with no offer up, Escape in an empty
|
||||
sketch leaves it. Then a tool letter arms the tool. check-gui-sketching.py does the same
|
||||
steps. This ladder once did two of them — Design tab, then Shift+S — and went straight to
|
||||
the tool letters.
|
||||
THE SEQUENCE MATTERS AND IT IS NOT OBVIOUS. Shift+S enters sketch MODE and pops the plane
|
||||
offer; the offer must be dismissed; and the plane itself is chosen by clicking it in the
|
||||
viewport BEFORE Shift+S. check-gui-sketching.py has always done all four steps. This ladder
|
||||
did two of them — Design tab, then Shift+S — and went straight to the tool letters.
|
||||
|
||||
That intermediate state is the trap. `is_sketching` reads 1, every tool key is accepted and
|
||||
traced, and not one click draws anything, because there is no plane under them. The ladder
|
||||
@@ -504,10 +499,10 @@ def enter_sketch(timeout=180):
|
||||
click(132, 53) # Design tab
|
||||
time.sleep(2.0)
|
||||
dismiss_modals()
|
||||
key("shift+s", 1.0) # nothing picked: the reference planes come up
|
||||
click(*PLANE_PX, pause=0.8) # picks the plane IN THE VIEWPORT: session open, offer up...
|
||||
click(*PLANE_PX) # ...and this closes the offer
|
||||
key("p", 0.6) # arms Point in the session
|
||||
click(*PLANE_PX) # pick the plane IN THE VIEWPORT — before Shift+S
|
||||
key("shift+s", 1.0)
|
||||
key("Escape", 0.5) # entering sketch mode pops the offer; dismiss it
|
||||
key("p", 0.6) # any sketch tool starts the session on that plane
|
||||
if try_call("sketch_describe") is not None:
|
||||
# NO Escape here. Every rung already opens with one to drop whatever tool the last
|
||||
# one left armed, and Escape in the Design tab walks a LIFO: first press drops the
|
||||
@@ -516,15 +511,14 @@ def enter_sketch(timeout=180):
|
||||
# reported all eleven checks failed with "nothing opened" — the tools were arming
|
||||
# into an empty Feature-mode document.
|
||||
return
|
||||
die("no sketch opened after Shift+S + plane click within "
|
||||
die("no sketch opened after plane click + Shift+S within "
|
||||
f"{timeout}s — sketch_describe never answered on {A.sock} (trace {TRACE})")
|
||||
|
||||
|
||||
# tool key, the clicks that draw it, and one distinct value per queued field. The values are
|
||||
# deliberately nothing like the as-drawn size, so a committed prefill cannot coincide with them.
|
||||
# Where the plane label sits in the viewport once Shift+S has brought the planes up. Same
|
||||
# constant the gesture ladder uses; it is a label on the 3D view, not a widget, so it moves only
|
||||
# if the camera does.
|
||||
# Where the plane label sits in the viewport before a sketch is open. Same constant the gesture
|
||||
# ladder uses; it is a label on the 3D view, not a widget, so it moves only if the camera does.
|
||||
PLANE_PX = (913, 359)
|
||||
|
||||
# Every coordinate below stays inside 1000..1400 x 500..760 — the box check-gui-sketching.py's
|
||||
|
||||
@@ -229,20 +229,7 @@ CHROME_DY = int(os.environ.get("ORCA_CAD_CHROME_DY", "26"))
|
||||
|
||||
DESIGN_TAB = (128, 29 + CHROME_DY)
|
||||
|
||||
# The ribbon's document group lost its Bed checkbox and label when the bed toggle moved to the
|
||||
# Feature tree, and every group to its right moved left by their width: wxLEFT 6 + the 18 px
|
||||
# CheckBox + wxLEFT 4 + the "Bed" label (~24 px) + wxRIGHT 4, about 56 px. The x of
|
||||
# CONSTRUCTION_CHECKBOX, CON_BTN and CON_BTN_SKETCH below is the one measured before that, plus
|
||||
# this. DERIVED, NOT MEASURED: re-measure on the rig and fold it in. CONFIRM_BTN sits after the
|
||||
# ribbon's stretch spacer and did not move.
|
||||
RIBBON_DX = -56
|
||||
|
||||
# Feature-tree rows, measured on the rig at 1920x1080: the list's first row is centred at y=215,
|
||||
# then 23 px apart. The first two rows are the Origin and the Bed, unframed on the card above the
|
||||
# features' own framed list, so the first FEATURE row sits two rows and TREE_GAP further down;
|
||||
# reset_document and the reopening double-click both need a feature. TREE_GAP is the list's
|
||||
# 12 px top margin plus its 1 px frame, derived rather than measured -- re-measure on the rig, like
|
||||
# RIBBON_DX.
|
||||
# Feature-tree rows, measured on the rig at 1920x1080: first row centre, then 23 px apart.
|
||||
# x=300, not the label: a second click ON the label opens the inline rename, and Delete then
|
||||
# edits the text instead of removing the feature.
|
||||
#
|
||||
@@ -250,8 +237,7 @@ RIBBON_DX = -56
|
||||
# unshifted click lands 26 px BELOW the first row -- just past its 23 px height -- so the row is
|
||||
# never selected, Delete does nothing, and reset_document spends 40 rounds on it before dying
|
||||
# with "could not empty the feature tree". That names the feature tree, which is not the fault.
|
||||
TREE_GAP = 12 + 1
|
||||
TREE_ROW0 = (300, 215 + 2 * 23 + TREE_GAP + CHROME_DY)
|
||||
TREE_ROW0 = (300, 215 + CHROME_DY)
|
||||
|
||||
|
||||
def go_design():
|
||||
@@ -280,21 +266,18 @@ def reset_document():
|
||||
def enter_sketch(tool_key, plane_px=(913, 359)):
|
||||
"""Enter a sketch the way the design law says: pick the plane in the viewport, then the tool.
|
||||
|
||||
leave_sketch()'s Escapes let go of every pick, so Shift+S finds nothing to sketch on and only
|
||||
brings the reference planes up; the click on one opens the session on it and pops the tool
|
||||
offer. A click outside a popup menu only closes it, so the same spot is clicked again, apart:
|
||||
inside the session it is empty canvas, so it selects nothing if the offer is slow to appear.
|
||||
No Escape: with no offer up, Escape in an empty sketch leaves it. The tool letter then arms
|
||||
the tool. All of it is real input — nothing here goes through the socket.
|
||||
Shift+S enters sketch MODE and pops the offer; Escape dismisses it; the tool letter then
|
||||
starts the session on the plane the click selected. All four steps are real input — nothing
|
||||
here goes through the socket.
|
||||
"""
|
||||
leave_sketch()
|
||||
click(*plane_px)
|
||||
key("shift+s", 0.8)
|
||||
click(*plane_px, pause=0.8) # picks the plane: the session opens and the offer pops...
|
||||
click(*plane_px) # ...and this closes the offer
|
||||
key("Escape", 0.4) # entering sketch mode pops the offer; dismiss it
|
||||
key("p", 0.6)
|
||||
if try_call("sketch_describe") is None:
|
||||
shot("/shots/gl-enter-failed.png")
|
||||
die("no sketch opened after Shift+S + plane click (see /shots/gl-enter-failed.png)")
|
||||
die("no sketch opened after plane click + Shift+S (see /shots/gl-enter-failed.png)")
|
||||
calibrate_here() # THIS sketch's own camera map, on THIS sketch's own plane
|
||||
key(tool_key, 0.6)
|
||||
|
||||
@@ -754,7 +737,7 @@ def corner_pair(ents):
|
||||
die("no adjacent pair in what should be a rectangle")
|
||||
|
||||
|
||||
CONSTRUCTION_CHECKBOX = (419 + RIBBON_DX, 75 + CHROME_DY)
|
||||
CONSTRUCTION_CHECKBOX = (419, 75 + CHROME_DY)
|
||||
|
||||
|
||||
def draw_line(x0, y0, x1, y1, length, angle):
|
||||
@@ -883,7 +866,7 @@ def rung_extend():
|
||||
# because the ladder only ever clicks "perpendicular" (3) and "equal" (5), both of which sit
|
||||
# before the first insertion. The next rung to use "tangent" would have clicked "collinear".
|
||||
CON_BTN_Y = 76 + CHROME_DY
|
||||
CON_BTN = {n: (449 + RIBBON_DX + 42 * i, CON_BTN_Y) for i, n in enumerate(
|
||||
CON_BTN = {n: (449 + 42 * i, CON_BTN_Y) for i, n in enumerate(
|
||||
["horizontal", "vertical", "parallel", "perpendicular", "coincident", "equal",
|
||||
"equal_radius", "collinear", "concentric", "tangent", "midpoint", "symmetric",
|
||||
"sym_v", "sym_h", "angle", "radius", "diameter", "fix", "dist_x", "dist_y"])}
|
||||
@@ -897,7 +880,7 @@ CON_BTN = {n: (449 + RIBBON_DX + 42 * i, CON_BTN_Y) for i, n in enumerate(
|
||||
# which already carries CHROME_DY), but the X start depends on how wide the sketch toolbar to the
|
||||
# left of this group renders, and this fork keeps mainline's top row. Re-measure before trusting
|
||||
# D11 here: screenshot in sketch mode and detect the icon columns, do not derive it by offset.
|
||||
CON_BTN_SKETCH = {n: (677 + RIBBON_DX + 42 * i, CON_BTN_Y) for i, n in enumerate(
|
||||
CON_BTN_SKETCH = {n: (677 + 42 * i, CON_BTN_Y) for i, n in enumerate(
|
||||
["horizontal", "vertical", "parallel", "perpendicular", "coincident", "equal",
|
||||
"equal_radius", "collinear", "concentric", "tangent", "midpoint", "symmetric",
|
||||
"sym_v", "sym_h", "angle", "radius", "diameter", "fix", "dist_x", "dist_y"])}
|
||||
|
||||
@@ -229,11 +229,11 @@
|
||||
"none"
|
||||
],
|
||||
"needs": {},
|
||||
"refusal": "Select a flat face or a reference plane to sketch on",
|
||||
"refusal": "Click a face or a reference plane in the viewport, then a sketch tool",
|
||||
"gui": true,
|
||||
"action": "key:S+S",
|
||||
"icon": "design_sketch",
|
||||
"hint": "Sketch on the selected flat face or plane, or click one next"
|
||||
"hint": "Click a face or a reference plane, then pick a drawing tool"
|
||||
},
|
||||
{
|
||||
"id": "extrude",
|
||||
@@ -1113,32 +1113,6 @@
|
||||
"icon": "color_palette",
|
||||
"hint": "Set the selected body's display color"
|
||||
},
|
||||
{
|
||||
"id": "zoom_to",
|
||||
"name": "Zoom to selection",
|
||||
"slot": "top",
|
||||
"key": null,
|
||||
"feature": null,
|
||||
"mcp": null,
|
||||
"mode": "model",
|
||||
"accepts": [
|
||||
"body_solid",
|
||||
"body_sheet",
|
||||
"face_planar",
|
||||
"face_cyl",
|
||||
"face_other",
|
||||
"edge_str",
|
||||
"edge_circ",
|
||||
"vertex",
|
||||
"sk_loop"
|
||||
],
|
||||
"needs": {},
|
||||
"refusal": null,
|
||||
"gui": true,
|
||||
"action": "btn:zoom_to",
|
||||
"icon": "design_zoom",
|
||||
"hint": "Frame the selection in the view, keeping the view direction"
|
||||
},
|
||||
{
|
||||
"id": "delete",
|
||||
"name": "Delete",
|
||||
|
||||
@@ -8,9 +8,6 @@ include) fails wherever the error is. Headers are compiled on their own, and
|
||||
fail only on errors in their changed lines. Deleting an #include also fails
|
||||
on every use, changed or not, that now lacks the header it provided.
|
||||
|
||||
With -- --fix, clang-tidy adds the missing includes, on those lines only, and
|
||||
each file it changed is checked again so that only what remains is reported.
|
||||
|
||||
The checks come from .clang-tidy at the repository root. The compile database
|
||||
must come from a configure with SLIC3R_PCH=OFF, or the precompiled header hides
|
||||
missing includes.
|
||||
@@ -105,10 +102,9 @@ def is_checked(path):
|
||||
|
||||
def changed_files(merge_base):
|
||||
# Against the working tree, so a local run covers uncommitted edits too.
|
||||
# core.quotePath=false keeps a non-ASCII path unquoted, and the explicit prefixes
|
||||
# override diff.noprefix and diff.mnemonicPrefix, so parse_diff sees its b/ prefix.
|
||||
# core.quotePath=false keeps a non-ASCII path unquoted, so parse_diff sees its b/ prefix.
|
||||
diff = subprocess.run(["git", "-c", "core.quotePath=false", "diff", "-U0", "--no-color", "--no-ext-diff",
|
||||
"--src-prefix=a/", "--dst-prefix=b/", "--diff-filter=AMR", merge_base],
|
||||
"--diff-filter=AMR", merge_base],
|
||||
check=True, capture_output=True, **UTF8).stdout
|
||||
return {path: change for path, change in parse_diff(diff).items() if is_checked(path)}
|
||||
|
||||
@@ -205,19 +201,13 @@ def errors_alone_at(revision, clang_tidy, build_dir, path):
|
||||
|
||||
|
||||
def check_file(clang_tidy, build_dir, merge_base, path, change, extra_args):
|
||||
"""Run clang-tidy on one file and return (failed, output, failing diagnostics, fixed)."""
|
||||
fixing = any(arg.startswith("--fix") for arg in extra_args)
|
||||
if fixing:
|
||||
with open(path, "rb") as f:
|
||||
before = f.read()
|
||||
"""Run clang-tidy on one file and return (failed, output, failing diagnostics)."""
|
||||
# A deleted include can orphan uses on unchanged lines, so such a file is
|
||||
# checked whole and the findings narrowed here. --fix keeps a line filter so
|
||||
# it never rewrites unrelated code, which for such a file means a second,
|
||||
# fixing run limited to the lines the first one found wanting.
|
||||
whole = bool(change.removed_includes)
|
||||
# checked whole and the findings narrowed here. --fix keeps the line filter
|
||||
# so it never rewrites unrelated code.
|
||||
whole = bool(change.removed_includes) and not extra_args
|
||||
returncode, output, diagnostics = run_clang_tidy(clang_tidy, build_dir, path,
|
||||
None if whole else change.lines,
|
||||
[] if whole else extra_args)
|
||||
None if whole else change.lines, extra_args)
|
||||
real = os.path.realpath(path)
|
||||
|
||||
def introduced(d):
|
||||
@@ -233,25 +223,14 @@ def check_file(clang_tidy, build_dir, merge_base, path, change, extra_args):
|
||||
if errors and change.removed_includes:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
text = f.read()
|
||||
before_sites = errors_alone_at(merge_base, clang_tidy, build_dir, path)
|
||||
before = errors_alone_at(merge_base, clang_tidy, build_dir, path)
|
||||
failing += [d for d in errors if d not in failing
|
||||
and (error_sites([d], text) - before_sites)]
|
||||
failed = bool(failing)
|
||||
elif whole:
|
||||
and (error_sites([d], text) - before)]
|
||||
return bool(failing), output, failing
|
||||
if whole:
|
||||
failing = [d for d in diagnostics if d.is_compile_error or introduced(d)]
|
||||
failed = bool(failing)
|
||||
else:
|
||||
failing, failed = diagnostics, returncode != 0
|
||||
if not fixing:
|
||||
return failed, output, failing, False
|
||||
if whole and failing:
|
||||
lines = change.lines + [[d.line, d.line] for d in failing if os.path.realpath(d.file) == real]
|
||||
run_clang_tidy(clang_tidy, build_dir, path, lines, extra_args)
|
||||
with open(path, "rb") as f:
|
||||
if f.read() == before:
|
||||
return failed, output, failing, False
|
||||
# Checked again, so what is reported is what the fixes left.
|
||||
return check_file(clang_tidy, build_dir, merge_base, path, change, [])[:3] + (True,)
|
||||
return bool(failing), output, failing
|
||||
return returncode != 0, output, diagnostics
|
||||
|
||||
|
||||
def main():
|
||||
@@ -284,14 +263,11 @@ def main():
|
||||
annotate = os.environ.get("GITHUB_ACTIONS") == "true"
|
||||
root = os.getcwd() + os.sep
|
||||
failed = []
|
||||
fixed = []
|
||||
with ThreadPoolExecutor(max_workers=args.jobs) as pool:
|
||||
jobs = {path: pool.submit(check_file, args.clang_tidy, args.build_dir, merge_base, path, change, args.extra_args)
|
||||
for path, change in todo}
|
||||
for path, job in jobs.items():
|
||||
file_failed, output, diagnostics, file_fixed = job.result()
|
||||
if file_fixed:
|
||||
fixed.append(path)
|
||||
file_failed, output, diagnostics = job.result()
|
||||
if not file_failed:
|
||||
continue
|
||||
failed.append(path)
|
||||
@@ -306,13 +282,6 @@ def main():
|
||||
if len(diagnostics) > MAX_REPORTED:
|
||||
print(f"... and {len(diagnostics) - MAX_REPORTED} more")
|
||||
|
||||
if fixed:
|
||||
print(f"\nAdded includes to {len(fixed)} file(s):")
|
||||
for path in fixed:
|
||||
print(f" {path}")
|
||||
if failed and fixed:
|
||||
print(f"\nclang-tidy still fails on {len(failed)} file(s); the findings above are what --fix could not add.")
|
||||
return 1
|
||||
if failed:
|
||||
print(f"\nclang-tidy failed on {len(failed)} file(s). Add the includes it names, or apply its "
|
||||
"suggestions locally with scripts/run_clang_tidy.sh --fix (scripts\\run_clang_tidy.ps1 -Fix on Windows).")
|
||||
|
||||
@@ -4,5 +4,10 @@
|
||||
<dict>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
<!-- The Bambu network plug-in's code protector rewrites one of its own signed code pages
|
||||
after loading. Under the hardened runtime macOS kills the process when that page is
|
||||
paged back in; this lets it run, as Bambu Studio's signature does. -->
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
# scripts/run_clang_tidy.sh --fix also add the missing includes it names
|
||||
#
|
||||
# It configures a separate build directory (build-tidy) without the precompiled
|
||||
# header, uses the clang-tidy on your system or installs the pinned one into a
|
||||
# virtual environment inside it, and runs scripts/clang_tidy_diff.py the way CI
|
||||
# does. Uncommitted changes are checked too.
|
||||
# header, installs the pinned clang-tidy into a virtual environment inside it, and
|
||||
# runs scripts/clang_tidy_diff.py the way CI does. Uncommitted changes are checked too.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -24,8 +23,7 @@ Usage: scripts/run_clang_tidy.sh [options]
|
||||
deps/build/<arch> on macOS)
|
||||
-j, --jobs N parallel clang-tidy runs (default: all cores)
|
||||
--fix apply clang-tidy's fixes (adds the missing includes)
|
||||
-y, --yes install missing tools without asking; another clang-tidy
|
||||
version found on the system is then not offered
|
||||
-y, --yes install missing tools without asking
|
||||
-h, --help show this help
|
||||
EOF
|
||||
}
|
||||
@@ -138,38 +136,12 @@ REQUIREMENTS="$ROOT/scripts/clang_tidy_requirements.txt"
|
||||
PINNED=$(sed -n 's/^clang-tidy==//p' "$REQUIREMENTS")
|
||||
VENV="$BUILD_DIR/clang-tidy-venv"
|
||||
|
||||
is_pinned() {
|
||||
[ -x "$1" ] && "$1" --version 2>/dev/null | grep -q "version $PINNED"
|
||||
}
|
||||
|
||||
CLANG_TIDY="${CLANG_TIDY:-}"
|
||||
if [ -n "$CLANG_TIDY" ]; then
|
||||
if [ -n "${CLANG_TIDY:-}" ]; then
|
||||
# Set by the caller: use it as is.
|
||||
is_pinned "$CLANG_TIDY" || echo "Warning: $CLANG_TIDY is not clang-tidy $PINNED, so results may differ from CI." >&2
|
||||
:
|
||||
else
|
||||
# One already on the system comes first: the pinned version outright, another
|
||||
# version if the user accepts the difference. The pinned version is installed
|
||||
# into a virtual environment otherwise.
|
||||
INSTALLED=""
|
||||
for candidate in $(command -v clang-tidy "clang-tidy-${PINNED%%.*}" || true) \
|
||||
"/usr/lib/llvm-${PINNED%%.*}/bin/clang-tidy" \
|
||||
"$(brew --prefix llvm 2>/dev/null || true)/bin/clang-tidy"; do
|
||||
if is_pinned "$candidate"; then
|
||||
CLANG_TIDY="$candidate"
|
||||
break
|
||||
fi
|
||||
[ -z "$INSTALLED" ] && [ -x "$candidate" ] && INSTALLED="$candidate"
|
||||
done
|
||||
if [ -z "$CLANG_TIDY" ] && [ -n "$INSTALLED" ] && [ "$YES" = 0 ] && ! is_pinned "$VENV/bin/clang-tidy"; then
|
||||
echo "Found $INSTALLED, which is $("$INSTALLED" --version | sed -n 's/.*version \([0-9.]*\).*/\1/p' | head -n 1), not the $PINNED CI uses, so results may differ slightly."
|
||||
if ask "Use it anyway?"; then
|
||||
CLANG_TIDY="$INSTALLED"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ -z "$CLANG_TIDY" ]; then
|
||||
CLANG_TIDY="$VENV/bin/clang-tidy"
|
||||
if ! is_pinned "$CLANG_TIDY"; then
|
||||
if [ ! -x "$CLANG_TIDY" ] || ! "$CLANG_TIDY" --version | grep -q "version $PINNED"; then
|
||||
if ask "clang-tidy $PINNED (the version CI uses) is not installed. Install it into $VENV?"; then
|
||||
mkdir -p "$BUILD_DIR"
|
||||
if ! python3 -m venv "$VENV"; then
|
||||
@@ -186,6 +158,9 @@ if [ -z "$CLANG_TIDY" ]; then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if ! "$CLANG_TIDY" --version | grep -q "version $PINNED"; then
|
||||
echo "Warning: $CLANG_TIDY is not clang-tidy $PINNED, so results may differ from CI." >&2
|
||||
fi
|
||||
|
||||
# --- Dependencies -------------------------------------------------------------
|
||||
|
||||
@@ -242,12 +217,7 @@ cmake --build "$BUILD_DIR" --target git_commit_hash_header >/dev/null
|
||||
|
||||
if [ -z "$BASE" ]; then
|
||||
REMOTE=$(git remote -v | awk '/github\.com[:\/]OrcaSlicer\/OrcaSlicer(\.git)? \(fetch\)/ { print $1; exit }')
|
||||
if [ -z "$REMOTE" ]; then
|
||||
# Against a fork's main that already has the commits, nothing is checked.
|
||||
echo "Warning: no remote points at github.com/OrcaSlicer/OrcaSlicer, so this compares against origin/main." >&2
|
||||
echo "If origin is your fork, add the upstream remote (git remote add upstream https://github.com/OrcaSlicer/OrcaSlicer.git) or pass --base." >&2
|
||||
REMOTE=origin
|
||||
fi
|
||||
REMOTE="${REMOTE:-origin}"
|
||||
if [ "$FETCH" = 1 ]; then
|
||||
git fetch --quiet "$REMOTE" main
|
||||
fi
|
||||
|
||||
@@ -155,8 +155,6 @@ class TestSubprocessCalls(unittest.TestCase):
|
||||
diff = "+++ b/src/libslic3r/Über.cpp\n@@ -1,0 +2 @@\n+// 打印\n"
|
||||
files, call, _ = self.run_patched(clang_tidy_diff.changed_files, "base", stdout=diff)
|
||||
self.assertIn("core.quotePath=false", call.args[0])
|
||||
# Whatever diff.noprefix or diff.mnemonicPrefix a user has set.
|
||||
self.assertIn("--dst-prefix=b/", call.args[0])
|
||||
self.assertEqual(call.kwargs["encoding"], "utf-8")
|
||||
self.assertEqual(files["src/libslic3r/Über.cpp"].lines, [[2, 2]])
|
||||
|
||||
@@ -169,60 +167,5 @@ class TestSubprocessCalls(unittest.TestCase):
|
||||
self.assertEqual(call.kwargs["encoding"], "utf-8")
|
||||
|
||||
|
||||
class TestCheckFileFix(unittest.TestCase):
|
||||
"""check_file with -- --fix: what clang-tidy is run on, and what is reported afterwards."""
|
||||
|
||||
def setUp(self):
|
||||
self.dir = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.dir.cleanup)
|
||||
self.path = os.path.join(self.dir.name, "Color.cpp")
|
||||
with open(self.path, "w") as f:
|
||||
f.write("int x;\n")
|
||||
|
||||
def finding(self, line, include=""):
|
||||
return clang_tidy_diff.Diagnostic(self.path, line, 1, "error",
|
||||
'no header providing "x" is directly included [misc-include-cleaner]', include)
|
||||
|
||||
def check(self, change, results, fix_writes=None):
|
||||
"""Run check_file with run_clang_tidy answering from `results` in turn; the --fix run
|
||||
rewrites the file with `fix_writes` when given. Returns (result, calls)."""
|
||||
calls = []
|
||||
|
||||
def run(clang_tidy, build_dir, path, lines, extra_args):
|
||||
calls.append((lines, extra_args))
|
||||
if "--fix" in extra_args and fix_writes is not None:
|
||||
with open(path, "w") as f:
|
||||
f.write(fix_writes)
|
||||
return results[len(calls) - 1]
|
||||
|
||||
with mock.patch.object(clang_tidy_diff, "run_clang_tidy", side_effect=run):
|
||||
result = clang_tidy_diff.check_file("clang-tidy", "build", "base", self.path, change, ["--fix"])
|
||||
return result, calls
|
||||
|
||||
def test_a_deleted_include_is_fixed_on_the_lines_it_orphaned_only(self):
|
||||
change = clang_tidy_diff.FileChange(lines=[[4, 4]], removed_includes={"libslic3r/Point.hpp"})
|
||||
orphaned = self.finding(50, "<libslic3r/Point.hpp>")
|
||||
unrelated = self.finding(60, "<vector>")
|
||||
(failed, _, failing, fixed), calls = self.check(
|
||||
change, [(1, "", [orphaned, unrelated]), (1, "", [orphaned]), (0, "", [])], fix_writes="#include <libslic3r/Point.hpp>\n")
|
||||
self.assertEqual(calls, [(None, []), ([[4, 4], [50, 50]], ["--fix"]), (None, [])])
|
||||
self.assertEqual((failed, failing, fixed), (False, [], True))
|
||||
|
||||
def test_a_file_the_fix_did_not_change_keeps_its_findings(self):
|
||||
change = clang_tidy_diff.FileChange(lines=[[4, 4]])
|
||||
error = clang_tidy_diff.Diagnostic(self.path, 4, 1, "error", "unknown type name 'Foo' [clang-diagnostic-error]")
|
||||
(failed, _, failing, fixed), calls = self.check(change, [(1, "", [error])])
|
||||
self.assertEqual(calls, [([[4, 4]], ["--fix"])])
|
||||
self.assertEqual((failed, failing, fixed), (True, [error], False))
|
||||
|
||||
def test_a_changed_file_is_checked_again_and_reports_what_is_left(self):
|
||||
change = clang_tidy_diff.FileChange(lines=[[4, 4]])
|
||||
error = clang_tidy_diff.Diagnostic(self.path, 4, 1, "error", "unknown type name 'Foo' [clang-diagnostic-error]")
|
||||
(failed, _, failing, fixed), calls = self.check(
|
||||
change, [(1, "", [self.finding(4, "<vector>"), error]), (1, "", [error])], fix_writes="#include <vector>\n")
|
||||
self.assertEqual(calls, [([[4, 4]], ["--fix"]), ([[4, 4]], [])])
|
||||
self.assertEqual((failed, failing, fixed), (True, [error], True))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -5,5 +5,10 @@
|
||||
<!-- for dynamic loading of libraries without signature validation. Used for 3dconnection drivers.-->
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
<!-- The Bambu network plug-in's code protector rewrites one of its own signed code pages
|
||||
after loading. Under the hardened runtime macOS kills the process when that page is
|
||||
paged back in; this lets it run, as Bambu Studio's signature does. -->
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -370,10 +370,6 @@ void AppConfig::set_defaults()
|
||||
// restores the conventional CAD representation for users who expect it (x0kd).
|
||||
if (get("design_connector_face_glyph").empty())
|
||||
set_bool("design_connector_face_glyph", true);
|
||||
|
||||
// Design tab: draw the printer bed and its plate grid (the Feature tree's Bed row).
|
||||
if (get("design_show_bed").empty())
|
||||
set_bool("design_show_bed", true);
|
||||
#endif
|
||||
|
||||
//#ifdef SUPPORT_SHOW_HINTS
|
||||
|
||||
@@ -466,6 +466,8 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
|
||||
edge.from->incident_edge = &edge;
|
||||
}
|
||||
|
||||
using NodeSet = SkeletalTrapezoidation::NodeSet;
|
||||
|
||||
void SkeletalTrapezoidation::separatePointyQuadEndNodes()
|
||||
{
|
||||
NodeSet visited_nodes;
|
||||
|
||||
@@ -93,6 +93,7 @@ using namespace libnest2d;
|
||||
using Item = _Item<ExPolygon>;
|
||||
using Box = _Box<Point>;
|
||||
using Circle = _Circle<Point>;
|
||||
using Segment = _Segment<Point>;
|
||||
using MultiPolygon = ExPolygons;
|
||||
|
||||
// Summon the spatial indexing facilities from boost
|
||||
|
||||
@@ -2851,6 +2851,7 @@ bool is_patch_inside_of_model(const SurfacePatch &patch,
|
||||
/// <returns>shape point index</returns>
|
||||
uint32_t get_shape_point_index(const CutAOI &cut, const CutMesh &model);
|
||||
|
||||
using PatchNumber = CutMesh::Property_map<FI, size_t>;
|
||||
/// <summary>
|
||||
/// Separate triangles singned with number n
|
||||
/// </summary>
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
// #define DEBUG_FUZZY
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
namespace Slic3r::Feature::FuzzySkin {
|
||||
|
||||
// Produces a random value between 0 and 1. Thread-safe.
|
||||
|
||||
@@ -352,16 +352,6 @@ void FillSpiralInset::_fill_surface_single(const FillParams& params,
|
||||
assert(params.use_arachne);
|
||||
assert(this->print_config != nullptr && this->print_object_config != nullptr);
|
||||
|
||||
// Internal solid infill must not add Arachne's standalone thin walls: one of those walls can
|
||||
// become the extra centre point after the spiral has finished. Top and bottom surfaces keep
|
||||
// Arachne, including the centre plug handled by generate_spiral_insets().
|
||||
if (params.extrusion_role == erSolidInfill) {
|
||||
Polylines polylines;
|
||||
this->_fill_surface_single(params, thickness_layers, direction, expolygon, polylines);
|
||||
append(thick_polylines_out, to_thick_polylines(std::move(polylines), scaled<coord_t>(this->spacing)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Only a solid surface is worth the variable width walls; a sparse one falls back to plain loops.
|
||||
if (params.density <= 0.9999f || params.dont_adjust) {
|
||||
Polylines polylines;
|
||||
|
||||
@@ -122,6 +122,8 @@ Polylines get_polylines(const ScalarField& sf, const double tolerance = SCALED_E
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
using namespace std;
|
||||
|
||||
void FillTpmsFK::_fill_surface_single(const FillParams& params,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point>& direction,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@@ -751,50 +751,6 @@ template<typename T>
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Writes G-code to a file in blocks and records in lines_ends the file offset after every '\n'
|
||||
class GCodeFileWriter
|
||||
{
|
||||
public:
|
||||
GCodeFileWriter(FilePtr& out, const std::string& out_path, std::vector<size_t>& lines_ends, const char* error_message)
|
||||
: m_out(out), m_out_path(out_path), m_lines_ends(lines_ends), m_error_message(error_message)
|
||||
{}
|
||||
~GCodeFileWriter() { assert(m_buffer.empty() || std::uncaught_exceptions() > 0); }
|
||||
|
||||
void append(std::string_view text)
|
||||
{
|
||||
const size_t text_pos = m_file_pos + m_buffer.size();
|
||||
for (size_t i = text.find('\n'); i != std::string_view::npos; i = text.find('\n', i + 1))
|
||||
m_lines_ends.emplace_back(text_pos + i + 1);
|
||||
m_buffer += text;
|
||||
if (m_buffer.size() >= GCodeProcessor::Output_Block_Size)
|
||||
flush();
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
if (m_buffer.empty())
|
||||
return;
|
||||
fwrite(m_buffer.data(), 1, m_buffer.size(), m_out.f);
|
||||
if (ferror(m_out.f)) {
|
||||
m_out.close();
|
||||
boost::nowide::remove(m_out_path.c_str());
|
||||
throw Slic3r::RuntimeError(m_error_message);
|
||||
}
|
||||
m_file_pos += m_buffer.size();
|
||||
m_buffer.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
FilePtr& m_out;
|
||||
const std::string& m_out_path;
|
||||
std::vector<size_t>& m_lines_ends;
|
||||
const char* m_error_message;
|
||||
std::string m_buffer;
|
||||
size_t m_file_pos{0};
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// Helper class to modify and export gcode to file
|
||||
class ExportLines
|
||||
{
|
||||
@@ -809,6 +765,16 @@ public:
|
||||
enum class EWriteType { BySize, ByTime };
|
||||
|
||||
private:
|
||||
static void update_lines_ends_and_out_file_pos(const std::string& out_string, std::vector<size_t>& lines_ends, size_t* out_file_pos)
|
||||
{
|
||||
for (size_t i = 0; i < out_string.size(); ++i) {
|
||||
if (out_string[i] == '\n')
|
||||
lines_ends.emplace_back((out_file_pos != nullptr) ? *out_file_pos + i + 1 : i + 1);
|
||||
}
|
||||
if (out_file_pos != nullptr)
|
||||
*out_file_pos += out_string.size();
|
||||
}
|
||||
|
||||
struct LineData
|
||||
{
|
||||
std::string line;
|
||||
@@ -848,14 +814,12 @@ private:
|
||||
EWriteType m_write_type{EWriteType::BySize};
|
||||
// Time machines containing g1 times cache
|
||||
const std::array<GCodeProcessor::TimeMachine, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)>& m_machines;
|
||||
// Output file writer
|
||||
GCodeFileWriter& m_writer;
|
||||
// Current time
|
||||
std::array<float, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> m_times{0.0f, 0.0f};
|
||||
// Current size of the cache in bytes
|
||||
// Current size in bytes
|
||||
size_t m_size{0};
|
||||
|
||||
// gcode lines cache, used only when writing by time
|
||||
// gcode lines cache
|
||||
std::deque<LineData> m_lines;
|
||||
size_t m_added_lines_counter{0};
|
||||
// map of gcode line ids from original to final
|
||||
@@ -863,16 +827,16 @@ private:
|
||||
std::vector<std::pair<size_t, size_t>> m_gcode_lines_map;
|
||||
|
||||
size_t m_times_cache_id{0};
|
||||
size_t m_out_file_pos{0};
|
||||
|
||||
public:
|
||||
ExportLines(EWriteType type, const std::array<GCodeProcessor::TimeMachine, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)>& machines, GCodeFileWriter& writer)
|
||||
ExportLines(EWriteType type, const std::array<GCodeProcessor::TimeMachine, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)>& machines)
|
||||
#ifndef NDEBUG
|
||||
: m_statistics(*this)
|
||||
, m_write_type(type)
|
||||
, m_machines(machines)
|
||||
, m_writer(writer){}
|
||||
, m_machines(machines){}
|
||||
#else
|
||||
: m_write_type(type), m_machines(machines), m_writer(writer)
|
||||
: m_write_type(type), m_machines(machines)
|
||||
{}
|
||||
#endif // NDEBUG
|
||||
|
||||
@@ -926,14 +890,11 @@ public:
|
||||
if (line.empty())
|
||||
return;
|
||||
|
||||
if (m_write_type == EWriteType::ByTime) {
|
||||
m_lines.push_back({line, m_times});
|
||||
m_lines.push_back({line, m_times});
|
||||
#ifndef NDEBUG
|
||||
m_statistics.add_line(line.length());
|
||||
m_statistics.add_line(line.length());
|
||||
#endif // NDEBUG
|
||||
m_size += line.length();
|
||||
} else
|
||||
m_writer.append(line);
|
||||
m_size += line.length();
|
||||
++m_added_lines_counter;
|
||||
if (!ignore_from_move) {
|
||||
assert(!m_gcode_lines_map.empty());
|
||||
@@ -999,35 +960,65 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// when writing by time, pass the cached lines older than m_times[Normal] - backtrace_time to the writer
|
||||
void write(float backtrace_time)
|
||||
// write to file:
|
||||
// m_write_type == EWriteType::ByTime - all lines older than m_time - backtrace_time
|
||||
// m_write_type == EWriteType::BySize - all lines if current size is greater than 65535 bytes
|
||||
void write(FilePtr& out, float backtrace_time, GCodeProcessorResult& result, const std::string& out_path)
|
||||
{
|
||||
if (m_write_type != EWriteType::ByTime)
|
||||
if (m_lines.empty())
|
||||
return;
|
||||
|
||||
while (!m_lines.empty() && m_lines.front().times[Normal] < m_times[Normal] - backtrace_time) {
|
||||
const LineData& data = m_lines.front();
|
||||
m_writer.append(data.line);
|
||||
m_size -= data.line.length();
|
||||
m_lines.pop_front();
|
||||
// collect lines to write into a single string
|
||||
std::string out_string;
|
||||
if (!m_lines.empty()) {
|
||||
if (m_write_type == EWriteType::ByTime) {
|
||||
while (m_lines.front().times[Normal] < m_times[Normal] - backtrace_time) {
|
||||
const LineData& data = m_lines.front();
|
||||
out_string += data.line;
|
||||
m_size -= data.line.length();
|
||||
m_lines.pop_front();
|
||||
#ifndef NDEBUG
|
||||
m_statistics.remove_line();
|
||||
m_statistics.remove_line();
|
||||
#endif // NDEBUG
|
||||
}
|
||||
} else {
|
||||
if (m_size > 65535) {
|
||||
while (!m_lines.empty()) {
|
||||
out_string += m_lines.front().line;
|
||||
m_lines.pop_front();
|
||||
}
|
||||
m_size = 0;
|
||||
#ifndef NDEBUG
|
||||
m_statistics.remove_all_lines();
|
||||
#endif // NDEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
write_to_file(out, out_string, result, out_path);
|
||||
update_lines_ends_and_out_file_pos(out_string, result.lines_ends, &m_out_file_pos);
|
||||
}
|
||||
}
|
||||
|
||||
// flush the current content of the cache and the writer to file
|
||||
void flush()
|
||||
// flush the current content of the cache to file
|
||||
void flush(FilePtr& out, GCodeProcessorResult& result, const std::string& out_path)
|
||||
{
|
||||
// collect lines to flush into a single string
|
||||
std::string out_string;
|
||||
while (!m_lines.empty()) {
|
||||
m_writer.append(m_lines.front().line);
|
||||
out_string += m_lines.front().line;
|
||||
m_lines.pop_front();
|
||||
}
|
||||
m_size = 0;
|
||||
#ifndef NDEBUG
|
||||
m_statistics.remove_all_lines();
|
||||
#endif // NDEBUG
|
||||
m_writer.flush();
|
||||
|
||||
{
|
||||
write_to_file(out, out_string, result, out_path);
|
||||
update_lines_ends_and_out_file_pos(out_string, result.lines_ends, &m_out_file_pos);
|
||||
}
|
||||
}
|
||||
|
||||
void synchronize_moves(GCodeProcessorResult& result) const
|
||||
@@ -1060,7 +1051,20 @@ public:
|
||||
|
||||
size_t get_size() const { return m_size; }
|
||||
|
||||
void reserve(size_t lines_count) { m_gcode_lines_map.reserve(lines_count); }
|
||||
private:
|
||||
void write_to_file(FilePtr& out, const std::string& out_string, GCodeProcessorResult& result, const std::string& out_path)
|
||||
{
|
||||
if (!out_string.empty()) {
|
||||
if (true) {
|
||||
fwrite((const void*) out_string.c_str(), 1, out_string.length(), out.f);
|
||||
if (ferror(out.f)) {
|
||||
out.close();
|
||||
boost::nowide::remove(out_path.c_str());
|
||||
throw Slic3r::RuntimeError("GCode processor post process export failed.\nIs the disk full?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void GCodeProcessor::run_post_process()
|
||||
@@ -1156,13 +1160,8 @@ void GCodeProcessor::run_post_process()
|
||||
last_exported_stop[i] = time_in_minutes(m_time_processor.machines[i].time);
|
||||
}
|
||||
|
||||
m_result.lines_ends.clear();
|
||||
// m_result.lines_ends.emplace_back(std::vector<size_t>());
|
||||
GCodeFileWriter writer(out, out_path, m_result.lines_ends, "GCode processor post process export failed.\nIs the disk full?");
|
||||
ExportLines export_line(m_result.backtrace_enabled ? ExportLines::EWriteType::ByTime : ExportLines::EWriteType::BySize,
|
||||
m_time_processor.machines, writer);
|
||||
// The line map holds an entry for each line of the file, and the first pass counted them
|
||||
export_line.reserve(m_line_id);
|
||||
m_time_processor.machines);
|
||||
|
||||
// replace placeholder lines with the proper final value
|
||||
// gcode_line is in/out parameter, to reduce expensive memory allocation
|
||||
@@ -1536,6 +1535,9 @@ void GCodeProcessor::run_post_process()
|
||||
}
|
||||
};
|
||||
|
||||
m_result.lines_ends.clear();
|
||||
// m_result.lines_ends.emplace_back(std::vector<size_t>());
|
||||
|
||||
// Orca: freshly collect SKIPPABLE ranges each post-process pass. The ranges are stored on the
|
||||
// member (rather than a local) so the injection pass can consume them, hence the clear here to
|
||||
// avoid stale ranges on re-invocation.
|
||||
@@ -1800,7 +1802,7 @@ void GCodeProcessor::run_post_process()
|
||||
|
||||
if (!gcode_line.empty())
|
||||
export_line.append_line(gcode_line);
|
||||
export_line.write(1.1f * max_backtrace_time);
|
||||
export_line.write(out, 1.1f * max_backtrace_time, m_result, out_path);
|
||||
gcode_line.clear();
|
||||
}
|
||||
}
|
||||
@@ -1842,7 +1844,7 @@ void GCodeProcessor::run_post_process()
|
||||
}
|
||||
}
|
||||
|
||||
export_line.flush();
|
||||
export_line.flush(out, m_result, out_path);
|
||||
|
||||
out.close();
|
||||
in.close();
|
||||
@@ -1990,13 +1992,31 @@ void GCodeProcessor::run_second_pass_injection()
|
||||
// The rewrite may shift byte positions (once the injector inserts lines), so rebuild lines_ends from scratch.
|
||||
// With an empty map the scanned '\n' offsets reproduce the current lines_ends exactly.
|
||||
m_result.lines_ends.clear();
|
||||
GCodeFileWriter writer(out, out_path, m_result.lines_ends, "GCode processor pre-heat injection pass failed.\nIs the disk full?\n");
|
||||
size_t out_file_pos = 0;
|
||||
|
||||
auto write_out = [&out, &out_path, this, &out_file_pos](std::string& str) {
|
||||
if (str.empty())
|
||||
return;
|
||||
fwrite((const void*) str.c_str(), 1, str.length(), out.f);
|
||||
if (ferror(out.f)) {
|
||||
out.close();
|
||||
boost::nowide::remove(out_path.c_str());
|
||||
throw Slic3r::RuntimeError(std::string("GCode processor pre-heat injection pass failed.\nIs the disk full?\n"));
|
||||
}
|
||||
for (size_t i = 0; i < str.size(); ++i) {
|
||||
if (str[i] == '\n')
|
||||
m_result.lines_ends.emplace_back(out_file_pos + i + 1);
|
||||
}
|
||||
out_file_pos += str.size();
|
||||
str.clear();
|
||||
};
|
||||
|
||||
// Orca: read/split lines with EOL-preserving semantics (keep the original \r and \n bytes, and
|
||||
// synthesize no trailing newline). This is required for the empty-map identity: normalizing every
|
||||
// line ending to "\n" would not be byte-identical if the finished file used \r\n or lacked a
|
||||
// final newline.
|
||||
std::string gcode_line;
|
||||
std::string export_buffer;
|
||||
unsigned int line_id = 0;
|
||||
auto op_it = inserted_operation_lines.begin();
|
||||
std::vector<char> buffer(65536 * 10, 0);
|
||||
@@ -2038,14 +2058,16 @@ void GCodeProcessor::run_second_pass_injection()
|
||||
}
|
||||
++op_it;
|
||||
}
|
||||
writer.append(gcode_line);
|
||||
export_buffer += gcode_line;
|
||||
gcode_line.clear();
|
||||
if (export_buffer.length() >= 65536)
|
||||
write_out(export_buffer);
|
||||
}
|
||||
}
|
||||
if (eof)
|
||||
break;
|
||||
}
|
||||
writer.flush();
|
||||
write_out(export_buffer);
|
||||
|
||||
out.close();
|
||||
in.close();
|
||||
|
||||
@@ -491,9 +491,6 @@ class Print;
|
||||
static const std::string VFlush_End_Tag;
|
||||
static const std::string External_Purge_Tag;
|
||||
public:
|
||||
// Size of the blocks the post-processing passes write the G-code in
|
||||
static constexpr size_t Output_Block_Size = 65536;
|
||||
|
||||
// Orca: SKIPPABLE region tags, stored as static strings (the FLUSH idiom above) rather than
|
||||
// a CustomETags/CustomTags array. Public so the emission sites (WipeTower / change_filament
|
||||
// path) can reference them single-sourced.
|
||||
|
||||
@@ -1135,6 +1135,7 @@ void SeamPlacer::gather_seam_candidates(const PrintObject *po, const SeamPlacerI
|
||||
|
||||
void SeamPlacer::calculate_candidates_visibility(const PrintObject *po,
|
||||
const SeamPlacerImpl::GlobalModelInfo &global_model_info) {
|
||||
using namespace SeamPlacerImpl;
|
||||
|
||||
std::vector<PrintObjectSeamData::LayerSeams> &layers = m_seam_per_object[po].layers;
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, layers.size()),
|
||||
|
||||
@@ -1482,6 +1482,7 @@ static FilamentGroupContext build_filament_group_context(
|
||||
FilamentMapMode mode,
|
||||
const std::unordered_map<int, int>& nozzle_status)
|
||||
{
|
||||
using namespace MultiNozzleUtils;
|
||||
using namespace FilamentGroupUtils;
|
||||
|
||||
FilamentGroupContext context;
|
||||
@@ -1690,6 +1691,7 @@ static std::vector<int> apply_master_extruder_preference(const FilamentGroupCont
|
||||
// multi-nozzle (H2C/A2L) resolves to a nozzle-granular result.
|
||||
MultiNozzleUtils::LayeredNozzleGroupResult ToolOrdering::get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const Print* print, const FilamentMapMode mode, const std::vector<std::set<int>>& physical_unprintables, const std::vector<std::set<int>>& geometric_unprintables, const std::map<int, std::set<NozzleVolumeType>>& unprintable_volumes, const std::unordered_map<int, int>& nozzle_status)
|
||||
{
|
||||
using namespace FilamentGroupUtils;
|
||||
using namespace MultiNozzleUtils;
|
||||
|
||||
if (!print || layer_filaments.empty())
|
||||
|
||||
@@ -230,6 +230,7 @@ std::vector<Bridge> get_grouped_bridges(
|
||||
{
|
||||
result.reserve(bridge_expansions.size());
|
||||
uint32_t group_id = 0;
|
||||
using std::move_iterator;
|
||||
for (ExPolygon& expolygon : bridge_expolygons)
|
||||
result.push_back({ std::move(expolygon), group_id ++, bridge_expansions.end() });
|
||||
}
|
||||
@@ -431,6 +432,7 @@ Surfaces expand_bridges_detect_orientations(
|
||||
const float closing_radius
|
||||
)
|
||||
{
|
||||
using namespace Slic3r::Algorithm;
|
||||
|
||||
double thickness;
|
||||
ExPolygons bridge_expolygons = fill_surfaces_extract_expolygons(surfaces, {stBottomBridge}, thickness);
|
||||
|
||||
@@ -660,6 +660,7 @@ bool empty(const CGALMesh &mesh)
|
||||
|
||||
bool repair(TriangleMesh& mesh, RepairedMeshErrors* repaired_errors, std::string* error)
|
||||
{
|
||||
using namespace CGAL;
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
if (mesh.empty())
|
||||
|
||||
@@ -263,6 +263,7 @@ size_t get_shapes_count(const NSVGimage &image)
|
||||
} // namespace Slic3r
|
||||
|
||||
namespace {
|
||||
using namespace Slic3r; // Polygon + Vec2f
|
||||
|
||||
Point::coord_type to_coor(float val, double scale) { return static_cast<Point::coord_type>(std::round(val * scale)); }
|
||||
|
||||
|
||||
@@ -61,8 +61,6 @@ public:
|
||||
bool is_smaller_width_perimeter;
|
||||
// Depth in the hierarchy. External perimeter has depth = 0. An external perimeter could be both a contour and a hole.
|
||||
unsigned short depth;
|
||||
// ORCA: an external hole perimeter touching the next outer wall all around, with nothing between them.
|
||||
bool is_thin_wall_hole = false;
|
||||
// Children contour, may be both CCW and CW oriented (outer contours or holes).
|
||||
std::vector<PerimeterGeneratorLoop> children;
|
||||
|
||||
@@ -120,7 +118,7 @@ static bool detect_steep_overhang(const PrintRegionConfig *config,
|
||||
}
|
||||
|
||||
static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perimeter_generator, const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls,
|
||||
bool &steep_overhang_contour, bool &steep_overhang_hole)
|
||||
bool &steep_overhang_contour, bool &steep_overhang_hole, bool reverse_thin_wall_hole)
|
||||
{
|
||||
// loops is an arrayref of ::Loop objects
|
||||
// turn each one into an ExtrusionLoop object
|
||||
@@ -287,17 +285,24 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
||||
} else {
|
||||
const PerimeterGeneratorLoop &loop = loops[idx.first];
|
||||
assert(thin_walls.empty());
|
||||
ExtrusionEntityCollection children = traverse_loops(perimeter_generator, loop.children, thin_walls, steep_overhang_contour, steep_overhang_hole);
|
||||
const bool reverse_children_thin_wall_hole = loops.size() == 1 && loop.is_contour && loop.children.size() == 1 &&
|
||||
(!loop.children.front().is_contour) && loop.children.front().children.empty();
|
||||
ExtrusionEntityCollection children = traverse_loops(perimeter_generator, loop.children, thin_walls, steep_overhang_contour,
|
||||
steep_overhang_hole, reverse_children_thin_wall_hole);
|
||||
out.entities.reserve(out.entities.size() + children.entities.size() + 1);
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop*>(coll.entities[idx.first]);
|
||||
coll.entities[idx.first] = nullptr;
|
||||
|
||||
// Orca: holes run against the contour, except thin wall holes, which run with it.
|
||||
if ((perimeter_generator.config->wall_direction == WallDirection::CounterClockwise) == (loop.is_contour || loop.is_thin_wall_hole))
|
||||
if ((perimeter_generator.config->wall_direction == WallDirection::CounterClockwise) == (loop.is_contour || reverse_thin_wall_hole))
|
||||
eloop->make_counter_clockwise();
|
||||
else
|
||||
eloop->make_clockwise();
|
||||
|
||||
// Orca: Reverse print order for thin wall holes.
|
||||
if (reverse_thin_wall_hole) {
|
||||
std::reverse(out.entities.begin(), out.entities.end());
|
||||
}
|
||||
|
||||
eloop->inset_idx = loop.depth;
|
||||
if (loop.is_contour) {
|
||||
out.append(std::move(children.entities));
|
||||
@@ -754,59 +759,6 @@ static void clip_inner_walls_over_top(std::vector<Arachne::VariableWidthLines> &
|
||||
}
|
||||
}
|
||||
|
||||
// ORCA: only_one_wall_top - widest bead of the given walls.
|
||||
static coord_t widest_bead(const std::vector<Arachne::VariableWidthLines> &walls)
|
||||
{
|
||||
coord_t widest = 0;
|
||||
for (const Arachne::VariableWidthLines &group : walls)
|
||||
for (const Arachne::ExtrusionLine &el : group)
|
||||
for (const Arachne::ExtrusionJunction &j : el.junctions)
|
||||
widest = std::max(widest, j.w);
|
||||
return widest;
|
||||
}
|
||||
|
||||
// ORCA: only_one_wall_top - length of the walls running further than tolerance from the reference walls, outside the
|
||||
// excluded area.
|
||||
static double length_off_reference(const std::vector<Arachne::VariableWidthLines> &walls, const Arachne::VariableWidthLines &reference,
|
||||
const ExPolygons &excluded, coord_t tolerance)
|
||||
{
|
||||
auto append_centerlines = [](const Arachne::VariableWidthLines &lines, Polylines &out) {
|
||||
for (const Arachne::ExtrusionLine &el : lines) {
|
||||
if (el.junctions.size() < 2)
|
||||
continue;
|
||||
Polyline ¢erline = out.emplace_back();
|
||||
centerline.points.reserve(el.junctions.size());
|
||||
for (const Arachne::ExtrusionJunction &j : el.junctions)
|
||||
centerline.points.emplace_back(j.p);
|
||||
}
|
||||
};
|
||||
Polylines wall_centerlines;
|
||||
Polylines reference_centerlines;
|
||||
for (const Arachne::VariableWidthLines &group : walls)
|
||||
append_centerlines(group, wall_centerlines);
|
||||
append_centerlines(reference, reference_centerlines);
|
||||
|
||||
Polylines off_reference = diff_pl(wall_centerlines, offset(reference_centerlines, float(tolerance)));
|
||||
if (! excluded.empty())
|
||||
off_reference = diff_pl(off_reference, excluded);
|
||||
return total_length(off_reference);
|
||||
}
|
||||
|
||||
// ORCA: only_one_wall_top - area covered by the given walls at their local widths.
|
||||
static Polygons walls_footprint(const Arachne::VariableWidthLines &walls)
|
||||
{
|
||||
Polygons footprint;
|
||||
for (const Arachne::ExtrusionLine &el : walls)
|
||||
for (size_t i = 1; i < el.junctions.size(); ++ i) {
|
||||
const Arachne::ExtrusionJunction &a = el.junctions[i - 1];
|
||||
const Arachne::ExtrusionJunction &b = el.junctions[i];
|
||||
const coord_t width = std::max(a.w, b.w);
|
||||
if (width > 0)
|
||||
append(footprint, offset(Polyline(a.p, b.p), float(width) / 2.f));
|
||||
}
|
||||
return union_(footprint);
|
||||
}
|
||||
|
||||
void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExPolygons &top_fills,
|
||||
ExPolygons &non_top_polygons, ExPolygons &fill_clip) const {
|
||||
// other perimeters
|
||||
@@ -1494,8 +1446,6 @@ void PerimeterGenerator::process_classic()
|
||||
coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||
coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||
bool has_gap_fill = this->config->gap_infill_speed.get_at(get_extruder_index(*print_config, this->config->outer_wall_filament_id - 1)) > 0;
|
||||
// ORCA: Use the smaller width as the lower bound to avoid overestimating safe overlap
|
||||
const double gap_fill_min_width = 0.2 * std::min(perimeter_width, ext_perimeter_width) * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
|
||||
// BBS: this flow is for smaller external perimeter for small area
|
||||
coord_t ext_min_spacing_smaller = coord_t(ext_perimeter_spacing * (1 - SMALLER_EXT_INSET_OVERLAP_TOLERANCE));
|
||||
@@ -1690,15 +1640,6 @@ void PerimeterGenerator::process_classic()
|
||||
|
||||
last = std::move(offsets);
|
||||
|
||||
// ORCA: a thin wall hole has no room for gap fill or an inner wall anywhere beside its outer wall.
|
||||
if (i == 0 && ! holes[0].empty()) {
|
||||
const float room = float(0.5 * (ext_perimeter_spacing2 + gap_fill_min_width));
|
||||
const Polygons reach = to_polygons(offset2_ex(last, -room, room + float(SCALED_EPSILON)));
|
||||
for (PerimeterGeneratorLoop &hole : holes[0])
|
||||
hole.is_thin_wall_hole = intersection_pl(Polylines{ hole.polygon.split_at_first_point() },
|
||||
ClipperUtils::clip_clipper_polygons_with_subject_bbox(reach, get_extents(hole.polygon).inflated(SCALED_EPSILON))).empty();
|
||||
}
|
||||
|
||||
//BBS: refer to superslicer
|
||||
//store surface for top infill if only_one_wall_top
|
||||
if (i == 0 && i!=loop_number && only_one_wall_top && !surface.is_bridge() && this->upper_slices != NULL) {
|
||||
@@ -1825,7 +1766,7 @@ void PerimeterGenerator::process_classic()
|
||||
steep_overhang_contour = true;
|
||||
steep_overhang_hole = true;
|
||||
}
|
||||
ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole);
|
||||
ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole, false);
|
||||
// All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
|
||||
if (config->overhang_reverse) {
|
||||
reorient_perimeters(entities, steep_overhang_contour, steep_overhang_hole,
|
||||
@@ -1952,7 +1893,8 @@ void PerimeterGenerator::process_classic()
|
||||
|
||||
// fill gaps
|
||||
if (! gaps.empty()) { // collapse
|
||||
double min = gap_fill_min_width;
|
||||
// ORCA: Use the smaller width as the lower bound to avoid overestimating safe overlap
|
||||
double min = 0.2 * std::min(perimeter_width, ext_perimeter_width) * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
double max = 2. * perimeter_spacing;
|
||||
ExPolygons gaps_ex = diff_ex(
|
||||
//FIXME offset2 would be enough and cheaper.
|
||||
@@ -2604,90 +2546,44 @@ void PerimeterGenerator::process_arachne()
|
||||
if (inner_loop_number >= 0) {
|
||||
assert(upper_slices != nullptr);
|
||||
|
||||
// Infill contour bounding box.
|
||||
BoundingBox infill_contour_bbox = get_extents(infill_contour);
|
||||
infill_contour_bbox.offset(SCALED_EPSILON);
|
||||
|
||||
coord_t perimeter_width = this->perimeter_flow.scaled_width();
|
||||
|
||||
// Filter out areas that are too thin and expand top surface polygons a bit to hide the wall line.
|
||||
// ORCA: skip if the top surface area is smaller than "min_width_top_surface"
|
||||
const float top_surface_min_width = std::max<float>(float(ext_perimeter_spacing) / 4.f + scaled<float>(0.00001), float(scale_(config->min_width_top_surface.get_abs_value(unscale_(perimeter_width)))) / 4.f);
|
||||
// Get top ExPolygons from current infill contour.
|
||||
Polygons upper_slices_clipped;
|
||||
if (object_config->interface_shells) {
|
||||
auto upper_slicer_same_region = to_expolygons(this->upper_slices_same_region->surfaces);
|
||||
upper_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(upper_slicer_same_region, infill_contour_bbox);
|
||||
} else
|
||||
upper_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*upper_slices, infill_contour_bbox);
|
||||
|
||||
// Get top ExPolygons from the given contour. uncovered reports whether the upper layer leaves any of the
|
||||
// contour uncovered, before bridges and too thin areas are filtered out.
|
||||
auto get_top_expolygons = [&](const ExPolygons &contour, bool &uncovered) {
|
||||
// Contour bounding box.
|
||||
BoundingBox contour_bbox = get_extents(contour);
|
||||
contour_bbox.offset(SCALED_EPSILON);
|
||||
|
||||
Polygons upper_slices_clipped;
|
||||
if (object_config->interface_shells) {
|
||||
auto upper_slicer_same_region = to_expolygons(this->upper_slices_same_region->surfaces);
|
||||
upper_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(upper_slicer_same_region, contour_bbox);
|
||||
} else
|
||||
upper_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*upper_slices, contour_bbox);
|
||||
|
||||
ExPolygons top = diff_ex(contour, upper_slices_clipped);
|
||||
uncovered = !top.empty();
|
||||
if (top.empty())
|
||||
return top;
|
||||
top_expolygons = diff_ex(infill_contour, upper_slices_clipped);
|
||||
|
||||
if (!top_expolygons.empty()) {
|
||||
if (lower_slices != nullptr) {
|
||||
const float bridge_offset = float(std::max<coord_t>(ext_perimeter_spacing, perimeter_width));
|
||||
const Polygons lower_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*lower_slices, contour_bbox);
|
||||
const ExPolygons current_slices_bridges = offset_ex(diff_ex(top, lower_slices_clipped), bridge_offset);
|
||||
const Polygons lower_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*lower_slices, infill_contour_bbox);
|
||||
const ExPolygons current_slices_bridges = offset_ex(diff_ex(top_expolygons, lower_slices_clipped), bridge_offset);
|
||||
|
||||
// Remove bridges from top surface polygons.
|
||||
top = diff_ex(top, current_slices_bridges);
|
||||
top_expolygons = diff_ex(top_expolygons, current_slices_bridges);
|
||||
}
|
||||
|
||||
// Filter out areas that are too thin and expand top surface polygons a bit to hide the wall line.
|
||||
// ORCA: skip if the top surface area is smaller than "min_width_top_surface"
|
||||
const float top_surface_min_width = std::max<float>(float(ext_perimeter_spacing) / 4.f + scaled<float>(0.00001), float(scale_(config->min_width_top_surface.get_abs_value(unscale_(perimeter_width)))) / 4.f);
|
||||
// Shrink the polygon to remove the small areas, then expand it back out plus a maragin to hide the wall line a little.
|
||||
// ORCA: Expand the polygon with half the perimeter width in addition to the contracted amount,
|
||||
// not the full perimeter width as PS does, to enable thin lettering to print on the top surface without nozzle collisions
|
||||
// due to thin lines being generated
|
||||
top = offset2_ex(top, -top_surface_min_width, top_surface_min_width + float(perimeter_width * 0.85));
|
||||
top_expolygons = offset2_ex(top_expolygons, -top_surface_min_width, top_surface_min_width + float(perimeter_width * 0.85));
|
||||
|
||||
// Get final top ExPolygons (bridges were excluded above, so they stay walled).
|
||||
return intersection_ex(top, contour);
|
||||
};
|
||||
top_expolygons = intersection_ex(top_expolygons, infill_contour);
|
||||
|
||||
// Walls with the full count, as generated when the single perimeter feature is disabled. Generated on first use.
|
||||
std::vector<Arachne::VariableWidthLines> full_perimeters;
|
||||
Polygons full_inner_contour;
|
||||
bool full_perimeters_generated = false;
|
||||
auto generate_full_perimeters = [&]() {
|
||||
if (full_perimeters_generated)
|
||||
return;
|
||||
Arachne::WallToolPaths full_tool_paths(last_p, bead_width_0, perimeter_spacing, coord_t(inner_loop_number + 2), wall_0_inset, layer_height, input_params_tmp);
|
||||
full_perimeters = full_tool_paths.getToolPaths();
|
||||
full_inner_contour = full_tool_paths.getInnerContour();
|
||||
full_perimeters_generated = true;
|
||||
};
|
||||
|
||||
// ORCA: the single wall pass allows Arachne 2 beads across a wall, so it fills a wall narrower than 3 outer wall
|
||||
// widths by widening both, where the full pass adds a middle bead. Over the top surface that is the intent;
|
||||
// anywhere else it leaves no room for the inner walls. When the single wall pass's outer walls run away from
|
||||
// the full pass's outside the top surface, take the full pass's outer walls and the area inside them instead.
|
||||
// Walls closer than outer_wall_tolerance count as the same wall: a widened bead's centerline moves by half
|
||||
// the width added, and only beads widened by more than twice the tolerance are looked for.
|
||||
const coord_t outer_wall_tolerance = bead_width_0 / 10;
|
||||
if (widest_bead(perimeters) > bead_width_0 + 2 * outer_wall_tolerance) {
|
||||
// The single wall pass's inner contour where it widens no bead: inside nominal width outer walls.
|
||||
const ExPolygons nominal_infill_contour = offset_ex(last, -float(bead_width_0 + wall_0_inset));
|
||||
bool nominal_uncovered = false;
|
||||
// Grown by an outer wall width to take in the outer walls bordering the top surface.
|
||||
const ExPolygons top_zone = offset_ex(get_top_expolygons(nominal_infill_contour, nominal_uncovered), float(bead_width_0));
|
||||
if (nominal_uncovered) {
|
||||
generate_full_perimeters();
|
||||
if (! full_perimeters.empty() && ! full_perimeters.front().empty() &&
|
||||
length_off_reference(perimeters, full_perimeters.front(), top_zone, outer_wall_tolerance) > double(perimeter_width)) {
|
||||
perimeters = { full_perimeters.front() };
|
||||
infill_contour = diff_ex(nominal_infill_contour, walls_footprint(full_perimeters.front()), ApplySafetyOffset::Yes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool uncovered = false;
|
||||
top_expolygons = get_top_expolygons(infill_contour, uncovered);
|
||||
|
||||
if (uncovered) {
|
||||
// ORCA: onion the real region (inside the outer wall) so the remaining walls follow the actual
|
||||
// geometry, then cut away the parts over the top surface. Re-onioning the non-top complement
|
||||
// instead - the fallback when there is no top fill - walls the top/non-top interface and rings
|
||||
@@ -2716,11 +2612,11 @@ void PerimeterGenerator::process_arachne()
|
||||
perimeters.insert(perimeters.end(), inner_perimeters.begin(), inner_perimeters.end());
|
||||
infill_contour = union_ex(top_expolygons, inner_wall_tool_paths.getInnerContour());
|
||||
} else {
|
||||
// There is no top surface ExPolygon, so use the walls generated like when the single perimeter
|
||||
// feature is disabled.
|
||||
generate_full_perimeters();
|
||||
perimeters = std::move(full_perimeters);
|
||||
infill_contour = union_ex(full_inner_contour);
|
||||
// There is no top surface ExPolygon, so we call Arachne again with parameters
|
||||
// like when the single perimeter feature is disabled.
|
||||
Arachne::WallToolPaths no_single_perimeter_tool_paths(last_p, bead_width_0, perimeter_spacing, coord_t(inner_loop_number + 2), wall_0_inset, layer_height, input_params_tmp);
|
||||
perimeters = no_single_perimeter_tool_paths.getToolPaths();
|
||||
infill_contour = union_ex(no_single_perimeter_tool_paths.getInnerContour());
|
||||
}
|
||||
}
|
||||
//PS
|
||||
|
||||