Compare commits

..
Author SHA1 Message Date
SoftFever fd1bfe55f7 Merge branch 'main' into feature/texture_displacement 2026-09-22 14:46:36 +08:00
ExPikaPaka 817d73c0e5 Faster slicing of colour-painted layers, texture panel tools row
A layer split into ~1000 colour fragments (a colour texture baked over a
large top face) made several per-fragment loops redo whole-layer ClipperLib
work, so slicing took ~33 min; it now takes ~3 min with the same output.

- make_fills: clip the layer's no-overlap area to each expolygon's box
  before intersecting
- discover_vertical_shells: small-piece filter compares only against the
  nearby part of the layer
- bridge_over_infill: whole-layer union/diff/intersections restricted to the
  candidate's neighbourhood; fill boundary expanded once per spacing; anchor
  tree built only from lines crossing the scan range; bbox pre-check in the
  collision test; limiting outline taken directly instead of through
  expand(..., 0.3 * flow.spacing()), which offsets by 0.135 scaled units
  (flow.spacing() is in mm) and only cost a whole-layer pass per candidate
- Bake job: include GUI.hpp for show_error()
- Texture panel: select/erase whole model next to the paint tools, brush
  size slider back on the same row
2026-09-21 14:55:39 +02:00
ExPikaPaka 8abd9b44d3 Merge remote-tracking branch 'origin/feature/texture_displacement' into feature/texture_displacement
# Conflicts:
#	src/libslic3r/TextureDisplacement.cpp
2026-09-21 09:00:18 +02:00
ExPikaPaka be6c67758a Texture displacement: per-layer bake, UV pane redesign, unwrap and layer view fixes
- Bake: each layer is sampled only on its own painted area; analytic
  projections used to stack every layer over every painted region, so the
  top layer's texture showed on all of them (colour sampler too)
- Auto resolution follows the texture's texel size and sharpness again
- Unwrap: charts cut by each face's own normal (a cube gives 6 islands, not
  12 triangles); non-disk charts (tubes, closed shells) are split until they
  flatten; connected nets test real triangle overlap, grow from the largest
  chart and are packed side by side
- UV edits are stored per unwrapped copy, so dragging a seam vertex no
  longer moves its copies in neighbouring islands
- UV pane: tool strip with unwrap settings moved in from the panel, sharp
  HiDPI icons, clearer island/edge/selection drawing with hover, texture
  picker from the thumbnail, texture no longer lost on reopen (GL state
  from the 3D view, background upload retries)
- Panel: whole-model select/erase as icons in the tools row; inactive
  layers' paint shown muted; colour textures shown in colour in the picker
- Built-in displacement texture library
- Tests for unwrap segmentation, connected nets, UV edits and per-layer
  sampling
2026-09-21 08:59:26 +02:00
SoftFever 3d7682e292 Fix colour textures loading upside down and crashes on damaged PNGs
Colour height maps now displace the same way up as grayscale ones. A
truncated or corrupt PNG in the texture folder or a project file now
loads as an empty texture instead of aborting the app, and a 16-bit
colour PNG is converted on load rather than displacing as noise.
2026-09-18 20:37:35 +08:00
SoftFever 77bd987979 Merge branch 'main' into feature/texture_displacement 2026-09-18 18:58:44 +08:00
SoftFever 3559fc883b Merge branch 'main' into feature/texture_displacement 2026-09-18 17:25:04 +08:00
SoftFever f296c7c221 Merge branch 'main' into feature/texture_displacement 2026-09-18 16:33:18 +08:00
ExPikaPakaandClaude Opus 5 21a31660d2 Merge remote-tracking branch 'origin/feature/texture_displacement' into feature/texture_displacement
The remote's 3aefae016f is the same tree as local e245f5d069, and every change
in 013ac898ba (continuous smoothing, world-space bake, mirrored/scaled
placements, plate clamp, UV editor framing/HiDPI, layer scrolling) was already
carried forward and reworked by the local commits. Resolved to the local side.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 11:12:02 +02:00
ExPikaPaka db0e14ceab Texture displacement gizmo icons 2026-09-15 08:58:26 +02:00
ExPikaPaka 81b8b01a01 Tests for the step cutter, edge flips, auto resolution and v2 colours 2026-09-15 08:58:26 +02:00
ExPikaPaka 2f4c9ab66d Texture gizmo: one-run pipeline by default, auto resolution, colour fixes, debug view 2026-09-15 08:58:26 +02:00
ExPikaPaka d766854af7 Bump and uvcheck shaders: project in the bake's world frame 2026-09-15 08:58:26 +02:00
ExPikaPaka 2355bb998d Texture displacement: step cutter, v2 colours, auto resolution, anchored bake frame 2026-09-15 08:58:26 +02:00
ExPikaPaka e8b63da1e2 TextureBake: edge flips along the height field, stage recorder, faster displace 2026-09-15 08:58:26 +02:00
ExPikaPaka 013ac898ba Improve texture displacement smoothing and UV editor framing 2026-09-09 15:25:00 +02:00
ExPikaPaka 5c7cb6bed5 add alternative baking algorithm 2026-09-09 08:42:37 +02:00
ExPikaPaka 3aefae016f Add new bake pipeline 2026-09-03 09:13:14 +02:00
ExPikaPaka e245f5d069 Add alternative backe pipeline 2026-09-03 08:48:03 +02:00
ExPikaPaka 96f2c8e698 Merge branch 'feature/texture_displacement' of https://github.com/OrcaSlicer/OrcaSlicer into feature/texture_displacement 2026-08-31 08:45:38 +02:00
ExPikaPaka d855bab19d Add color suport for textures 2026-08-31 07:58:48 +02:00
SoftFever cde889a7c3 Merge branch 'main' into feature/texture_displacement 2026-08-30 13:52:54 +08:00
ExPikaPaka 045504c880 Move computation to background thread & resolve freeze 2026-08-27 09:20:02 +02:00
ExPikaPaka 6166bac17a Improve adaptive subdivision at border & fix some visual bugs 2026-08-26 09:13:50 +02:00
ExPikaPaka 165a1e9f4c Measure post-process smoothing by edge energy instead of height spread 2026-08-20 07:14:21 +02:00
ExPikaPaka c215d0291b Merge branch 'main' into feature/texture_displacement 2026-08-19 09:13:53 +02:00
ExPikaPaka d926f7c490 Add Parallax preview & fix Undo\Redo history 2026-08-12 10:14:38 +02:00
ExPikaPaka 2db770b672 Displace the painted patch border and add post-process smoothing 2026-07-29 08:44:16 +02:00
ExPikaPaka 2a46197322 Rewrite adaptive subdivision to refine worst-first against a triangle budget 2026-07-28 11:42:40 +02:00
ExPikaPaka 15fd3fc97c Add adaptive subdivision 2026-07-24 09:03:06 +02:00
ExPikaPaka 00f778e863 Merge branch 'feature/texture_displacement' of https://github.com/OrcaSlicer/OrcaSlicer into feature/texture_displacement 2026-07-21 14:24:39 +02:00
ExPikaPaka dc1e8b6dc3 Rename reserved GLSL word on AMD GPU 2026-07-21 14:07:51 +02:00
SoftFever 753054974b Merge branch 'main' into feature/texture_displacement 2026-07-21 19:50:35 +08:00
ExPikaPaka eacc236ccb Fix typo again 2026-07-21 12:53:00 +02:00
ExPikaPaka 345369e005 Fix typo after cleanup 2026-07-21 11:28:51 +02:00
ExPikaPaka 18c5d31fb2 Merge branch 'feature/texture_displacement' of https://github.com/OrcaSlicer/OrcaSlicer into feature/texture_displacement 2026-07-21 10:12:16 +02:00
ExPikaPaka 61d2d4355a Cleanup 2026-07-21 10:12:09 +02:00
ExPikaPaka ab023f3f6d Add texture projection frame overlay, fix remeshing and subdivision 2026-07-21 09:44:25 +02:00
Ian Bassi b073aa4d23 Merge branch 'main' into feature/texture_displacement 2026-07-17 09:07:31 -03:00
ExPikaPaka 8247514ae2 Fix cmake config 2026-07-17 09:04:39 +02:00
ExPikaPaka 00f55639d3 Add new icons 2026-07-16 08:52:15 +02:00
ExPikaPaka 68d754d946 Add texture displacement documentation 2026-07-16 08:43:35 +02:00
ExPikaPaka dc5a48bdfd Add texture displacement toolbar icon and textures 2026-07-16 08:43:27 +02:00
ExPikaPaka 05083bb6ab Add texture displacement gizmo and UV editor 2026-07-16 08:43:21 +02:00
ExPikaPaka a393b21642 Add texture displacement bump and UV-check shaders 2026-07-16 08:43:08 +02:00
ExPikaPaka a7c8dcc58d Add texture displacement baking, LSCM unwrap and remesh core 2026-07-16 08:42:55 +02:00
ExPikaPaka 3514249197 Removed files that were accidently added 2026-07-09 08:40:37 +02:00
ExPikaPaka 7f2598d0d6 POC 2026-07-08 08:50:47 +02:00
317 changed files with 31138 additions and 6472 deletions
-4
View File
@@ -58,9 +58,6 @@ Paths below are relative to this skill. Commands run from the repository root.
9. **Run the full profile checks before reporting completion.** A vendor-scoped pass is only a
development loop. Review also covers version bumps, assets, non-default processes and hardware
tuning that CI cannot establish.
10. **One all-printer preset per product; color is a runtime property, never a preset.** Never ship
presets that differ only by color — CI accepts them, so this is a review call. See
[color is a runtime property](references/filament-profiles.md#color-is-a-runtime-property).
## Creating or modifying a profile
@@ -110,7 +107,6 @@ Paths below are relative to this skill. Commands run from the repository root.
| A setting has no effect | Key spelling/type, `handle_legacy`, or a config key placed on a `machine_model` |
| A preset exists but is not selectable | Index registration, `instantiation`, installation and compatibility |
| A filament is missing, duplicated, or matches the wrong spool | [Compatibility and alias shadowing](references/filament-profiles.md#compatible_printers); [ids](references/ids.md) |
| Presets differ only by color, or an all-printer library preset lacks `@System` | [Color is a runtime property](references/filament-profiles.md#color-is-a-runtime-property) |
| A bed temperature is ignored | [Plate-specific temperature keys](references/filament-profiles.md#bed-temperature-is-twelve-keys-not-one) |
| A change is absent from the running app | Version bump and [installed profile location](references/validation.md#testing-in-the-app) |
| A check fails | [Error → remedy](references/validation.md#error--remedy) |
@@ -52,15 +52,6 @@ a brand means adding a folder here; the folder name is a directory label only
collection, so there is no duplicate-name error.
- You may inherit from an instantiated preset as well as from a base; it is common.
## Color is a runtime property
`filament_id` identifies a product, not a color; filament sync/AMS reads the color from the spool at
runtime. A product ships one all-printer preset and the color is chosen at runtime — never a sibling
preset that differs only by color. A material family (PLA vs PLA Matte vs PLA Silk) is a new product; a
color is not. A printer tune keeps the product alias and does not multiply per color either.
CI does not catch this — per-color presets pass `check` — so it is a review call.
## The two most common contributions
**A printer vendor tuning a generic.** Keep the `Generic X` base name so the alias shadows the library
@@ -46,17 +46,12 @@ to the first `@`; the target half is a label except for reserved forms:
- `@base` — a non-instantiated product root. `@base` is convention; a base is really identified by
`instantiation: "false"` and no `setting_id` ([the three-part shape](filament-profiles.md#the-three-part-shape)).
- `@System` — the OrcaFilamentLibrary selectable shim, and the convention for an all-printer product
(`<Product> @System`, empty `compatible_printers`); not enforced, so a deviation is worth a review
comment. The literal `Generic <mat> @System` is load-bearing for 3MF/project recovery, beyond the
alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)).
- `@System` — the OrcaFilamentLibrary selectable shim. The literal `Generic <mat> @System` is
load-bearing for 3MF/project recovery, beyond the alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)).
- `@<Vendor>`, `@<Vendor> <Model>`, `@<Vendor> <Model> <nozzle> nozzle` — printer tunes, BBL's shape.
Other vendors differ (a bare model, a printer serial, Creality's `@<Model>-all`). Specificity is judged
from `compatible_printers`, not the name
([one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)).
- Color is not part of the product name: `<Product> <Color>` presets are not authored; the color is
chosen at runtime
([color is a runtime property](filament-profiles.md#color-is-a-runtime-property)).
## Not the same as the filename
@@ -15,7 +15,6 @@ The table highlights gaps that need human review. What CI *does* run:
| Whether the intended default survived compatibility selection | The sweep can select a different compatible preset |
| A dangling `compatible_printers` inside an `instantiation: "false"` base | A base never becomes a `Preset`, so the reference check never sees it (a bad `inherits` in a base *is* caught) |
| A `renamed_from` whose old name is still a live preset | The redirect is inert while a live preset carries that name |
| A preset differentiated only by color, or an all-printer library preset without `@System` | Per-color presets split one product across ids and the selector fills with near-duplicates; CI stays green |
| Per-extruder vector length on a multi-nozzle printer | Silently padded (with the **first** value) or truncated |
## 1. Was the vendor `version` bumped?
+2 -42
View File
@@ -826,37 +826,6 @@ find_package(OpenSSL REQUIRED)
find_package(CURL REQUIRED)
find_package(Freetype REQUIRED)
if (SLIC3R_GUI)
# LibDataChannel's installed export references its bundled dependencies,
# but does not install their CMake targets. Recreate those targets from
# the same dependency prefix before loading the LibDataChannel config.
if (NOT TARGET Usrsctp::usrsctp)
find_library(_ORCA_USRSCTP_LIBRARY NAMES usrsctp
PATHS "${CMAKE_PREFIX_PATH}/lib" NO_DEFAULT_PATH)
if (_ORCA_USRSCTP_LIBRARY)
add_library(Usrsctp::usrsctp UNKNOWN IMPORTED GLOBAL)
set_target_properties(Usrsctp::usrsctp PROPERTIES
IMPORTED_LOCATION "${_ORCA_USRSCTP_LIBRARY}"
IMPORTED_LINK_INTERFACE_LANGUAGES C
INTERFACE_LINK_LIBRARIES "Threads::Threads")
endif()
endif()
if (NOT TARGET LibJuice::LibJuice)
find_library(_ORCA_LIBJUICE_LIBRARY NAMES juice
PATHS "${CMAKE_PREFIX_PATH}/lib" NO_DEFAULT_PATH)
if (_ORCA_LIBJUICE_LIBRARY)
add_library(LibJuice::LibJuice UNKNOWN IMPORTED GLOBAL)
set_target_properties(LibJuice::LibJuice PROPERTIES
IMPORTED_LOCATION "${_ORCA_LIBJUICE_LIBRARY}"
IMPORTED_LINK_INTERFACE_LANGUAGES C
INTERFACE_LINK_LIBRARIES "Threads::Threads")
endif()
endif()
find_package(LibDataChannel CONFIG REQUIRED)
endif()
add_library(libcurl INTERFACE)
target_link_libraries(libcurl INTERFACE CURL::libcurl)
@@ -1137,7 +1106,6 @@ function(orcaslicer_copy_dlls target config postfix output_dlls)
endif ()
file(COPY ${_occt_dlls}
${CMAKE_PREFIX_PATH}/bin/freetype.dll
${CMAKE_PREFIX_PATH}/bin/avformat-61.dll
${CMAKE_PREFIX_PATH}/bin/avcodec-61.dll
${CMAKE_PREFIX_PATH}/bin/swresample-5.dll
${CMAKE_PREFIX_PATH}/bin/swscale-8.dll
@@ -1150,11 +1118,11 @@ function(orcaslicer_copy_dlls target config postfix output_dlls)
${_out_dir}/WebView2Loader.dll
${_out_dir}/freetype.dll
${_out_dir}/avformat-61.dll
${_out_dir}/avcodec-61.dll
${_out_dir}/swresample-5.dll
${_out_dir}/swscale-8.dll
${_out_dir}/avutil-59.dll
PARENT_SCOPE
)
list(APPEND _dll_list ${_occt_staged})
set(${output_dlls} ${_dll_list} PARENT_SCOPE)
@@ -1174,10 +1142,7 @@ function(orcaslicer_copy_sos target config postfix output_sos)
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
endif ()
file(COPY ${CMAKE_PREFIX_PATH}/lib/libavformat.so
${CMAKE_PREFIX_PATH}/lib/libavformat.so.61
${CMAKE_PREFIX_PATH}/lib/libavformat.so.61.1.100
${CMAKE_PREFIX_PATH}/lib/libavcodec.so
file(COPY ${CMAKE_PREFIX_PATH}/lib/libavcodec.so
${CMAKE_PREFIX_PATH}/lib/libavcodec.so.61
${CMAKE_PREFIX_PATH}/lib/libavcodec.so.61.3.100
${CMAKE_PREFIX_PATH}/lib/libavutil.so
@@ -1192,9 +1157,6 @@ function(orcaslicer_copy_sos target config postfix output_sos)
DESTINATION ${_out_dir})
set(${output_sos}
${_out_dir}/libavformat.so
${_out_dir}/libavformat.so.61
${_out_dir}/libavformat.so.61.1.100
${_out_dir}/libavcodec.so
${_out_dir}/libavcodec.so.61
${_out_dir}/libavcodec.so.61.3.100
@@ -1324,8 +1286,6 @@ endif ()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LIBRARY_FILES
${LIBDIR_BIN}/libavformat.so.61
${LIBDIR_BIN}/libavformat.so.61.1.100
${LIBDIR_BIN}/libavcodec.so.61
${LIBDIR_BIN}/libavcodec.so.61.3.100
${LIBDIR_BIN}/libavutil.so.59
+581
View File
@@ -0,0 +1,581 @@
# Texture Displacement - Technical Notes
Branch: `feature/texture_displacement`. Reference for the feature as it stands: what it does, how the
algorithms work, and where the code lives.
## What it does
A paint-style gizmo (`GLGizmoTextureDisplacement`) that lets you:
- Paint one or more "layers" onto a model's surface, each a height-map texture with its own
depth/tiling/rotation/offset/invert/tile-mode/projection-mode/blend-mode.
- Pick a texture from a shipped library (`resources/textures/displacement/`) or import your own
(saved into `<data_dir>/textures/displacement/`, kept separate so app updates can't clobber it).
- Combine overlapping layers with image-editor-style blend modes (Add/Subtract/Multiply/Divide).
- Preview the true displaced result live, before baking (background job, not on the UI thread).
- Preview via a fast GPU shader instead (no real geometry movement) for a lighter-weight alternative.
- Bake into real mesh geometry on demand, restricted to the painted area only.
- Remesh and subdivide so a low-poly model has enough vertices to show fine detail.
- Unwrap a painted patch with a real CGAL LSCM parameterization and view it in a dedicated,
dockable 2D "UV Editor" pane.
## Standard vs Pro mode
A two-position slider in the panel header, right of the Dock/Undock button.
**Pro** shows every mesh-preparation control; Remesh, Subdivide and Bake are run separately by the user,
in whatever order they like.
**Standard** hides all of it and folds one fixed recipe into the Bake button, because a height map only
ever *moves vertices that already exist* - painting onto an imported 12-triangle box and pressing Bake
would otherwise do nothing visible. Standard's Bake is:
1. `plan_remesh()` + `replace_mesh_keep_all_paint()` - isotropic remesh to 1 mm, sharp edges above 40
degrees protected. Gives the subdivider an even starting density whatever the input looked like.
2. `plan_adaptive_subdivision()` + `apply_adaptive_subdivision()` - feature-adaptive refinement, max
edge 20 mm, detail 0.02 mm, min edge 0.02 mm.
3. `bake()` - the ordinary background displacement job.
Both preparation stages are *planned* before the undo snapshot and *applied* after it, so a stage with
nothing to do is skipped without leaving an empty undo step. The standalone Pro buttons share the same
plan/apply split.
**All three stages sit under one undo step.** `Plater::take_snapshot()` records the state *before* the
change, so a single snapshot taken at the top of `bake_standard()` means one Undo returns the mesh to
exactly what was imported. `TextureDisplacementBakeInput::take_snapshot` lets the caller say who owns
the undo step - true for the Pro-mode button, false for the pipeline, whose background job commits long
after that snapshot's scope has closed.
The presets live in one place (`STD_*` constants) and `apply_standard_mode_presets()` pins the hidden
controls to them every frame while Standard is active, so the live preview cannot disagree with what
Bake will do. Switching to Standard also closes the subdivision preview, whose controls have just gone.
One control survives into Standard: **"Added triangles (k)"**, the subdivision budget. It is deliberately
*not* pinned - pinning would fight the user's own slider every frame - because unlike the rest of the
recipe its right value depends on the part rather than on the method (a big model, or a fine texture,
simply needs more triangles). Default 1500. The widget is one lambda shared by both layouts.
Standard remeshes *after* painting, so the remesh has to preserve paint: `ModelVolume::restore_painting()`
only remaps the four standard channels, so `replace_mesh_keep_all_paint()` additionally runs
`TriangleSelector::remap_painting()` over the eight texture-displacement masks. The Pro Remesh button
goes through the same helper. If the remap comes back empty the pipeline stops with a message rather
than baking a flat mesh.
## Architecture
### Data model (per `ModelVolume`)
Each of up to `TEXTURE_DISPLACEMENT_MAX_LAYERS` (8) layers gets its **own independent
`FacetsAnnotation`** paint mask - the same `TriangleSelector`/`FacetsAnnotation` machinery every other
paint gizmo (FdmSupports, Seam, MMU, FuzzySkin) already uses, just one full instance per layer slot
instead of one per volume. This is what makes layered/blended painting work for free: the same triangle
can be `ENFORCER` in layer 2's mask and layer 5's mask simultaneously, and at bake/preview time each
layer displaces the surface left by the previous one (image-editor-layer semantics).
Whole-stack settings (border handling, post-process smoothing) live beside the layers in
`texture_displacement_options` (`TextureDisplacementOptions`), since they belong to no single layer.
### Bake algorithm (`libslic3r/TextureDisplacement.cpp`)
`build_texture_displacement(base_mesh, layers, facets_data, options)` is **accumulate-then-displace,
and topology-preserving**: the returned mesh has exactly the input's vertices and triangles, in the
same order - only the positions of displaced vertices differ.
1. `its_compactify_vertices()` on a copy of the input. In practice a no-op (it only drops
*unreferenced* vertices, and preserves the order and indices of the rest). It is there to
guarantee the index alignment step 3 depends on.
2. Area-weighted vertex normals of the **undisplaced** mesh, computed once. Every layer both projects
and displaces along these, so a vertex covered by several layers moves along one single well-defined
direction. Where the paint does *not* cover every triangle around a vertex, the normal is recomputed
from the painted triangles alone (the union over all layers, so it stays one direction per vertex):
on the rim of a fully painted top face the whole-mesh normal is the 45-degree bisector it shares with
the side wall, and displacing along that flares the rim outwards instead of raising it. Interior
vertices are unaffected - all their triangles are painted, so the two normals coincide. Paint
coverage per original triangle comes straight off `TriangleSplittingData::triangles_to_split`.
3. For each layer in slot order: deserialize its stored paint mask into a `TriangleSelector` against
the **base mesh** (never against a previous layer's output), then
`selector.get_facets_strict(ENFORCER)` → the painted patch. Two facts are exploited:
- `get_facets_strict()` returns the mesh's **entire** referenced vertex array regardless of which
state was asked for - only `.indices` is filtered by state. So `get_facets_strict(ENFORCER)`
and `get_facets_strict(NONE)` share identical vertex indexing, which is what lets boundary
detection be a plain index check instead of a position-hash lookup.
- The selector's vertex array *starts with* the mesh's own vertices (extra ones created where a
brush stroke split a triangle are appended after them), and `get_facets_strict()` emits the
referenced ones in order. Combined with step 1, **selector vertex index `i` is our vertex `i`**.
Split vertices live past the end of our array and are simply skipped - they sit on the paint
boundary anyway (splitting only happens at partial coverage).
4. A vertex used by at least one **unpainted** triangle is a border vertex. Whether it moves is
`TextureDisplacementOptions::displace_border`, and it does by default. Nothing can tear: the bake is
topology-preserving, so a border vertex is *one* vertex shared by both regions and moving it simply
tilts the unpainted triangles that use it. Pinning it instead clamps the outermost ring of relief to
zero, which on a fully painted face collapses the pattern into a ring of steep ramps at the edge; it
is kept as an option for when the relief must not spill past the paint at all. Either way the border
drives the `edge_smoothing` falloff.
5. Per interior vertex: sample the height texture (`sample_layer_height()`, see Projection methods)
and fold `height * depth_mm * (invert ? -1 : 1)` into that vertex's running total via the layer's
`TextureBlendMode` (see Blend modes). A `visited` set makes each layer fold in exactly **once**
per vertex, no matter how many of the patch's triangles share it - otherwise a Multiply/Subtract
layer would apply two or three times over depending on local triangle fan-out.
6. Move each touched vertex along its (step 2) normal by its accumulated total.
7. Optionally (`TextureDisplacementOptions::smooth_*`) relax the result - see Post-process smoothing.
### Post-process smoothing
`smooth_mesh_vertices(mesh, movable, strength, iterations)` - Laplacian relaxation, run after all layers
have been folded in, restricted to the vertices flagged in `movable`. Each pass moves a movable vertex a
`strength` fraction of the way to the average of its one-ring, read from a **snapshot** of the previous
pass so the result does not depend on vertex order (a Gauss-Seidel sweep would smooth several times as
hard at the end of the array as at the start). Neighbours come from a CSR-style adjacency built once per
call. Topology-preserving, like the bake.
Its job is to round off the hard steps a bitmap height map leaves behind - a different knob from
`TextureDisplacementLayer::smoothing`, which blurs the *height map* before it is ever sampled.
Two ways in, sharing one set of settings on the volume:
- The **"Smooth result"** checkbox + "Smoothing (%)" / "Passes" ride along with Preview and Bake.
`movable` is exactly the set of vertices the displacement moved, so the untouched part of the model
keeps its exact geometry and the ring just outside the displaced set anchors the relaxation (the
relief cannot creep outward).
- **"Smooth baked mesh now"** (`GLGizmoTextureDisplacement::smooth_model()`) applies the same settings to
the volume's *committed* geometry, for relief that is already baked in. `movable` there is the painted
triangles' vertices. Because smoothing never touches the triangle list, this is the one geometry
operation in the gizmo that keeps **every** paint channel verbatim - it saves and restores the eight
texture-displacement masks around `set_mesh()` rather than remapping or dropping them.
**"Ignore outer ring"** (`smooth_skip_border`, on by default) drops the patch's own outermost ring of
vertices from `movable`. That ring's neighbours *outside* the paint never move, so relaxing it drags the
rim of the relief down toward the flat surface and the pattern comes out half-melted where it meets the
edge. Held out, the border keeps the full depth the texture asked for and only the interior relaxes.
Turning it off softens the outer edge deliberately (a blunter version of the per-layer edge-smoothing
falloff). This is the *smoothing* rim, independent of whether that rim is displaced at all
(`displace_border`, step 4 above); both default to keeping the border sharp.
### Blend modes
`TextureBlendMode` {Add, Subtract, Multiply, Divide}, per layer, applied per vertex against the
total accumulated by the layers **below** it (lower slots). The quantity blended is a signed
displacement in **mm**, not a pixel value.
Add/Subtract are self-explanatory. Multiply/Divide are *scaling* operations and so need a unit
convention: they treat the layer's own value as a **factor relative to 1 mm**. That makes `depth_mm`
a gain, and - the property that makes a Multiply layer usable as a mask - a layer with depth 1 mm
sampling a white (1.0) texel multiplies by exactly 1, i.e. leaves the layers below unchanged.
Divide floors its divisor's magnitude at 0.05: a black texel samples to *exactly* zero, so the divisor
really does hit zero in ordinary use, and an unbounded `1/0` would fling vertices thousands of mm away
and poison the mesh's bounding box (and every plate/print-volume check downstream). The floor doubles as
a cap on how far Divide can amplify the relief beneath it: at most 20×.
The **lowest painted layer ignores its blend mode**: it has nothing beneath it, and Multiply/Divide
against an implicit zero base would annihilate (or blow up) it. Enforced in
`build_texture_displacement()` (the first layer to reach a given vertex always folds in additively) and
surfaced in the UI, which labels that layer "Base layer" instead of offering a control that does nothing.
### Projection methods
Five choices per layer (`TextureProjectionMethod`), all funneling through `apply_uv_transform()`
(scale by `1/tiling_scale`, rotate by `rotation_deg`, add `offset`). They are dispatched by
`sample_layer_height()`, which returns a **height**, not a UV - because Triplanar takes three
texture samples per vertex and so has no single UV that represents it.
- **Triplanar** (default) - samples the texture on all three world planes (`(y,z)`, `(x,z)`, `(x,y)`)
and blends the three by the vertex's own normal raised to `TRIPLANAR_BLEND_SHARPNESS` (4). Hard-picking
the single axis most aligned with the normal instead is discontinuous wherever that dominant axis
flips: on a +X face the planar coordinate is `(y, z)`, on a Y face it is `(x, z)`, so at the shared
edge `u` jumps. A weighted blend is continuous across the transition by construction, since the weight
of the axis being left behind falls smoothly to zero. This removes the hard *seam*; some cross-fade
blurring in the band right at a 90° edge is inherent to triplanar mapping. A genuinely seam-free wrap
around a box needs a real unwrap - that is what the LSCM mode is for.
- **Cylindrical** - wraps around an axis through the patch centroid, axis auto-picked as the world
axis *least* aligned with the average normal (perpendicular to the outward radial normal, as a
cylinder's own axis would be). `u = angle * local_radius` (arc length in mm), `v = distance along
axis`. An approximation, not an exact fit for arbitrary geometry, and the axis/centre are not
user-overridable.
- **Spherical** - longitude/latitude around the centroid, scaled by local radius. Same caveat.
- **LSCM** - real UV unwrap via `MeshBoolean::cgal::parameterize_lscm()` (CGAL's
`Surface_mesh_parameterization` package, LSCM algorithm). Computed **once per patch** (not
per-vertex like the others - it's a single global least-squares solve), then each vertex looks up
its precomputed UV. Requires the patch to be a single topological disk (one connected component,
one boundary loop) - `compute_lscm_uvs()` returns empty and the layer falls back to Triplanar if not
(e.g. multiple disconnected painted islands, or a fully closed patch). CGAL's parameterizer needs a
mesh with no isolated/unreferenced vertices, but `get_facets_strict()` returns the *whole* mesh's
vertex array - so `compact_patch_with_map()` builds a clean sub-mesh plus an index map back to the
original vertex numbering, purely local to this file.
- **ViewProjected** ("From view") - a flat projection along a fixed direction captured from the 3D
camera, like a slide projector. `capture_view_projection()` takes the camera's right/up axes,
transforms them into the volume's *local* frame (so the projection rides along if the part is later
moved), and stores them as `TextureDisplacementLayer::view_project_right/up` (unit vectors, so the
projected coordinate stays in mm and `tiling_scale` keeps meaning mm). `sample_layer_height()`
projects `Vec2f(dot(pos, right), dot(pos, up))`. Single-valued per point, so - like LSCM but unlike
blended Triplanar - the fast preview and UV-check overlay precompute it per vertex
(`compute_layer_vertex_uvs()`) and drive the shader's `use_vertex_uv` path. Faces angled away from
the projector smear; that is inherent to view projection.
Two companions to this mode:
- **Projection frame overlay** (`TextureProjectorFrame`, see below) - a semi-transparent window
dragged over the 3D view whose border becomes the projection's edge. Applying it stores an exact
**projective** map in `view_project_matrix`, which supersedes the affine `right`/`up` axes above
for that layer (`view_project_projective`).
- **"Project only on visible"** (`select_visible_faces()`) - repaints the layer with exactly the
facets the camera can see, so the projected area matches the viewpoint the projector was captured
from. Two tests: a facing test (normal vs. view direction, per triangle - under perspective the
view direction varies across the model, so it is taken from the eye to each centroid), then
`MeshRaycaster::get_unobscured_idxs()` on the survivors to drop facets hidden behind other
geometry, so a concave part's far inner wall is correctly excluded. One ray query per front-facing
facet, hence click-driven (on the checkbox and on each "Capture current view"), never per frame.
It **replaces** the layer's paint rather than adding to it - "project onto what I can see" would
otherwise accumulate every angle the user had ever looked from.
### Manual seams and island cutting
`TextureDisplacementLayer::lscm_seam_edges` - undirected mesh-vertex-index edge pairs the unwrap is
forced to cut along, on top of the dihedral-angle seams. `segment_into_charts()` takes a set of these
(translated from mesh → compacted-patch numbering inside `compute_patch_unwrap()`) and refuses to
union two triangles across a marked edge whatever their angle. Both the unwrap cache key and the
gizmo's `UVEditorState` include the seam list, so marking a seam (which leaves the paint mask
untouched) still forces a re-solve. Like the paint masks, seams are mesh-index-space and so dropped on
any topology change.
Two ways to write to it:
- **Mark seam (manual)** - a "Mark seams" click mode (`m_seam_edit_mode`) that suppresses painting. A
click raycasts the volume (`m_c->raycaster()->raycasters()[idx]->unproject_on_mesh()`, `idx` = the
volume's slot among model-part volumes), finds the facet's edge nearest the hit point, and toggles it.
Marked edges render as a red overlay (`render_seam_overlay()`), pulled toward the camera so they read
on top. This is the Blender mark-seam workflow.
- **Cut island (auto)** - `cut_island()` takes the selected chart's triangles (back-mapped from the
unwrap via `source_vertex`), finds their 3D bounding box, and marks every edge that straddles the
mid-plane perpendicular to the longest axis. The re-unwrap then splits the chart across its narrow
waist. Exposed as the UV pane's **Cut** button.
### UV-check overlays (checker / distortion)
`resources/shaders/{110,140}/texture_displacement_uvcheck.{vs,fs}`, one shader with a `mode` uniform,
drawn over the painted patch (`rebuild_uvcheck_mesh()`/`render_uvcheck_mesh()`, P3N3T2: `normal.x` =
distortion, `tex_coord` = uv), pulled forward with a polygon offset. **Checker** samples a procedural
checkerboard at the layer's uv (per-vertex for LSCM/ViewProjected, in-shader triplanar otherwise) -
squares that stay square mean low distortion. **Distortion** colours each triangle blue→green→red by
`log2(uv_area / surface_area)` centred on the patch's *median* stretch (so a globally-scaled unwrap
reads as uniformly ideal and only relative stretch shows), averaged to vertices. A separate **Show mesh
wireframe** toggle draws the whole volume's triangle edges, rebuilt only when the vertex count changes
(not per stroke).
### Tiling
`DecodedHeightTexture::sample(uv, tile_enabled, tile_method)`. Two tile methods when enabled
(Repeat, MirroredRepeat). **When `tile_enabled` is false, sampling outside `[0,1)` returns `0`
directly** rather than clamping the *coordinate* into range, which would smear the border row/column of
pixels outward to infinity in every direction (streaky lines radiating out from the painted patch).
### Subdivision — two modes
**Uniform (`subdivide_mesh_uniform()`)** — whole-mesh, 1-to-4 split. Recursive edge-midpoint split with
a shared per-pass midpoint cache (keyed by sorted vertex-index pair) so triangles sharing an edge get
the *same* new vertex - capped at `max_iterations` (default 6). Whole-mesh so it never leaves a
T-junction, at the cost of densifying everywhere. Wired as a "Subdivide steps" slider (**05**, 0 =
no subdivision), Apply snaps back to 0. Drops texture-displacement paint (no remap) via the standard
`save_painting()`/`set_mesh()`/`restore_painting()` dance; the other four channels are remapped.
**Adaptive (`subdivide_mesh_adaptive()`)** — refine **only the painted area**, by **Rivara longest-edge
bisection**, which is *conformal by construction*. Only **terminal** edges are ever bisected - an edge
that is the longest edge of *every* triangle sharing it - which splits both those triangles along one
shared midpoint at once, so a hanging node is never created. The edge to split for a triangle that wants
refining is found by **longest-edge propagation (LEPP)**: walk to the longest edge of ever-longer-edged
neighbours until a terminal one is reached, and bisect that. Edge length strictly increases along the
path (ties broken by mesh-vertex key, which both sides of an edge compute identically), so the walk
cannot cycle, and Rivara's result is that repeating it refines the original triangle in a bounded number
of bisections. The transition triangles it pulls in just outside the painted patch are the graded band
that makes the size change conformal.
The win: a small decal on a big model no longer quadruples the *whole* model's triangle count.
**Run to completion, worst-first, against a triangle budget.** The refinement loop is not a fixed number
of sweeps: it holds every triangle that is over its criteria in a max-heap keyed by *how many times over*
it is, pops the worst, walks its LEPP, bisects, and re-scores. Edge adjacency (`nb[e]`, the triangle
across each edge) is built **once** and maintained incrementally through each bisection, so the cost
scales with the refined region rather than with the whole model. `max_triangles` is the only bound;
stopping on it leaves a perfectly valid, still-conformal mesh that spent its budget on the largest
errors. A fixed sweep count instead spends itself grading the *coarse surroundings* - whose edges are
the longest, so they win every terminal-edge contest - and never reaches the painted patch.
**It carries the paint forward**, which is what makes it usable (uniform subdivide drops paint). Because
the refinement is *driven by* the paint, the remap is trivial: `subdivide_mesh_adaptive()` fills an
`out_source[new_tri] = input_tri` map (children inherit their parent), and the gizmo rebuilds each
layer's mask on the new mesh - a new triangle is painted iff its source was fully painted in that
layer. `collect_paint_region()` derives both:
- the union refine-region: **exactly** the original triangles the brush touched, read straight off
`TriangleSplittingData::triangles_to_split` (`serialize()` records an entry per original triangle that
is either split - i.e. partially painted, the patch boundary - or carries a non-default state). No
dilation: marking every triangle that shares a *vertex* with the patch drags in a whole fan of huge
unpainted neighbours and refines *those* down to the resolution floor, since the height field the
detail test samples is not restricted to the painted area. The conformal closure already grades the
size change outward on its own.
- the per-layer fully-painted-triangle sets (a `get_facets_strict(ENFORCER)` sub-triangle with all three
*original* vertex indices == a whole, fully-painted original triangle; a partial stroke's sub-triangles
always carry a split vertex).
The other four channels ride the normal `restore_painting()` remap.
Both modes share the gizmo's Preview/Apply/Done flow; the **"Only painted area (adaptive)"** checkbox
picks the mode, and the adaptive preview follows the paint live (`rebuild_preview()` refreshes the
wireframe while the subdivide preview is open in adaptive mode). The panel shows the previewed triangle
count.
**Feature-adaptive (follow texture detail).** A sub-mode of adaptive (the **"Follow texture detail"**
checkbox) that puts triangles where the *displaced surface actually bends*, not evenly. A flat region or
a linear **ramp** needs no extra vertices (linear interpolation is exact for a ramp); what needs them is
**curvature** - the *second* derivative, not the gradient. So the extra predicate is a **chord-error**
test: sample the combined displacement at the triangle's three edge midpoints *and its centroid*
(sampling the interior is what catches a bump sitting inside a triangle, the blind spot of an edge-only
test) and take the largest departure from the flat triangle's barycentric interpolation. Refine while
that exceeds `chord_tolerance_mm` ("Detail (mm)"). Zero chord error on a ramp ⇒ untouched; high on a
bump/ridge/noise ⇒ refined until captured. Same conformal machinery, so still crack-free. The
per-triangle error is cached and recomputed only for the children of a split.
Four knobs bracket it, and all four matter:
- **"Max edge (mm)"** (`target_edge_length_mm`) is a **baseline that applies in feature mode too**.
Without it the chord test aliases: a big triangle over a fine pattern can sample four points that all
land at similar heights, report no error, and stall before refinement ever starts. The baseline
guarantees a sampling density fine enough for the curvature test to see the texture at all.
- **"Detail (mm)"** is the chord tolerance above.
- **"Min edge (mm)"** is a hard floor under both, and is what guarantees termination across a sharp
texture *step*, where the error never falls however fine the mesh gets.
- **"Added triangles (k)"** is the budget, passed as `max_triangles` (the model's own triangle count plus
the slider, so the control still means something on an already-dense model).
The height field is `make_combined_displacement_sampler()` - it mirrors `build_texture_displacement()`'s
per-layer setup (decode, patch centroid, cylinder axis, blend order, "lowest layer folds additively")
but evaluated per point. Two deliberate simplifications, both erring toward *more* detail (safe -
over-refinement is never a crack): every sampleable layer is sampled at every point (no per-point paint
test), and edge-smoothing falloff is ignored. The first is *why* the refine region must not be dilated -
outside the paint the sampler still reports full relief. **LSCM layers are skipped** (no per-point UV); a
purely LSCM stack yields a null sampler and the code falls back to the length baseline alone. Per-vertex
heights are sampled lazily, so a small patch on a huge model never pays for the rest of it.
### Fast preview (GPU-only, no CPU meshing)
`resources/shaders/{110,140}/texture_displacement_bump.{vs,fs}`, registered as
`"texture_displacement_bump"`. Shades the *displaced* surface without moving geometry - active-layer
only, selected from the View row, and the default when the gizmo opens (`m_use_bump_preview = true`).
Vertex format is `GLModel::Geometry::EVertexLayout::P3N3T2`: `normal.x` carries the per-vertex paint
weight (0/1), `normal.y` flags the UV island currently being dragged, and `tex_coord` carries a
precomputed texture UV, so it can use `GLModel` normally instead of a hand-rolled VBO/VAO manager.
The mesh is **flat** (vertices not shared between triangles): every corner of a painted triangle gets
weight 1, every corner of an unpainted one weight 0. A coarse mesh needs that - one painted face of a raw
cube has no strictly-interior vertex, so per-vertex weighting would either bleed onto the neighbours or
vanish outright. Duplicating vertices costs no shading quality here because the shader takes its surface
normal from screen-space derivatives of position, not from a per-vertex normal.
**Both preview meshes work in the patch's vertex space, not the mesh's.** Those agree only until a
*brush* stroke splits a triangle: `get_facets_strict()` then appends the split vertices, so the patch
array is longer. `rebuild_bump_preview_mesh()` and `rebuild_uvcheck_mesh()` therefore index
`patch.vertices` throughout. The weight buffer is rebuilt at the same cadence as the true-displacement
preview (stroke-end/slider-release) but from the **live** `TriangleSelector` state, not the flushed model
facets, so it does not lag by a full model round-trip.
The perturbed normal is the analytic one for a height field `H = ±depth_mm · h(uv)` displaced along
`N` over any orthonormal surface tangent pair `T`/`B`:
N' = normalize(N (dH/da)·T (dH/db)·B), a = dot(p,T), b = dot(p,B)
The two slopes have to be genuine **mm-per-mm** derivatives for the preview's apparent depth to match
the bake's.
**Two projection paths (`use_vertex_uv` uniform):**
- **Triplanar (`use_vertex_uv = 0`)** - `uv` and the `T`/`B` axes are both derived in-shader from
the dominant normal component, mirroring `project_planar()`/`apply_uv_transform()`, and the slope is
formed analytically. `T`/`B` are the projection's axis-aligned pair, exact only when the face is
axis-aligned; the shader drops the along-normal component to keep the gradient in the surface. Here
one `uv` unit is exactly `tiling_scale` mm, so the `1/tiling_scale` gradient factor is right.
- **Precomputed UV (`use_vertex_uv = 1`, used for LSCM and ViewProjected)** - `uv` comes per-vertex from
the CPU (`compute_layer_vertex_uvs()`, so island placement + tiling/rotation/offset are already folded
in), and the perturbed normal is built with **Mikkelsen's method** ("Bump Mapping Unparametrized
Surfaces on the GPU"): the surface gradient taken directly from the screen-space derivatives of the
*sampled height* and position. **This makes no uv→mm scale assumption**, which is essential, because an
LSCM map is **conformal, not isometric**: it is globally area-scaled but the *local* mm-per-uv varies
across the chart, so a single global `1/tiling_scale` factor gets the apparent depth wrong. `dFdx(h)`
captures the true on-screen rate of change however the chart is stretched. This path is also what makes
the fast preview follow the UV editor: move an island and its uv - hence its shading - moves with it
(the mesh rebuilds on drag-end, `on_island_edited(finished)``rebuild_preview()`
`rebuild_bump_preview_mesh()`). The branch is uniform and the paint weight gates by multiply, so the
texture derivatives stay well defined. A triangle straddling a seam has a discontinuous uv → the
`det≈0` guard skips it (a localised preview-only artifact, never in the bake).
**Parallax (triplanar path).** Perturbing the shading normal alone welds the pattern to the base surface:
it does not slide as the camera orbits, and does not get deeper as `depth_mm` grows. The triplanar path
therefore shades at the point the *displaced* surface would show at this pixel, found by **ray marching**
(parallax occlusion mapping). A point at ray parameter `s`, i.e. `P + V·s` (`P` the base point, `V` the
unit direction to the eye), sits at height `s·dot(V,n)` above the undisplaced surface. The displaced
surface lives in a shell between the extreme values of `amp·(h midlevel)` - taken from both ends of
`h ∈ [0,1]`, so it holds for an inverted layer and a raised midlevel too, where the surface sits *below*
the undisplaced one. The march starts at the top of that shell, where the ray is outside the surface by
construction, and steps inward until the ray height drops below the sampled height. That crossing *is*
the visible point.
Solving `Q = P + V·(H(Q)/dot(V,n))` by fixed-point iteration instead is geometrically exact but the
divisor goes to zero edge-on; the sample then lands a large fraction of a tile away and the iteration
oscillates, which reads as a second, flat copy of the pattern ghosted over the real one. Clamping the
step to one tile does not help - a tile-sized shift lands on the neighbouring tile, the same pattern
again. Offset limiting (stepping along the tangential part of `V`) is stable but understates parallax
enough that the relief still flattens as soon as the camera tilts. Marching has neither problem.
The hit is interpolated between the last two samples, which keeps `PARALLAX_STEPS` (24) affordable, and
the whole march is skipped when sweeping the shell would move the sample point less than half a texel -
the head-on case, so the common view pays almost nothing. The 140 variant samples with
`textureLod(…, 0.0)` inside the loop, since implicit derivatives are undefined in non-uniform control
flow. Two uniforms exist for this: `midlevel` (parallax needs the real height, not just its derivative)
and `eye_model_pos` (the camera in the volume's local frame).
Parallax cannot change the model's silhouette or cast shadows; the View row's Normal mode is one click
away for that. The LSCM path stays plain Mikkelsen bump - it has no closed-form uv, so there is no cheap
way to re-project a marched position. One further approximation: the GPU sampler's wrap mode stands in
for `tile_enabled`/`tile_method`, so with tiling *off* the GPU repeats where the CPU returns 0 outside
`[0,1)`.
### On-canvas "Adjust Texture" gizmo
A per-active-layer toggle ("Adjust placement") that disables painting and shows a flat pan panel (free
2D drag on both axes) plus two arrows along the patch's own U/V axes (constrained single-axis drag).
Anchored to the painted patch's centroid/average-normal (`compute_layer_paint_anchor()`). Hit-testing is
screen-space distance/point-to-segment, not real 3D ray intersection against the handle geometry - simple
and good enough at this handle size.
### Projection frame overlay (ViewProjected)
`src/slic3r/GUI/TextureProjectorFrame.hpp/.cpp` - a semi-transparent, resizable `wxFrame` the user
drags **over the 3D view**, like a slide projector's gate. Whatever the model shows through it is what
the texture is projected onto, and the window's border becomes the hard edge of the displacement.
Press **Apply projection frame** and the gizmo reads the window's rectangle and commits it.
The window is deliberately **dumb**: it owns no placement state and reports nothing continuously. Its
position and size *are* the placement, read on demand at Apply - which is also when the expensive
visible-facet raycast runs. So dragging it is free and nothing recomputes until asked.
Plain 2D (`wxPaintDC`), not a `wxGLCanvas`: a second GL canvas would have to share the app's one real
`wxGLContext`. It only ever draws a bitmap and a border.
**The projective mapping (`apply_projection_frame()`)**. The frame defines a **screen-space** rectangle,
but the bake samples from a **local-space** position, so the two have to be reconciled.
`view_project_right/up` can only express an *affine* projection - exact under an orthographic camera, but
wrong under perspective, where the near end of a part projects larger than the far end and no pair of
axes reproduces that. So the layer instead stores a full projective map (`view_project_matrix`, row-major
3×4, `uv = (row0·p̃/row2·p̃, row1·p̃/row2·p̃)`), built like this:
- `K = projection · view · (instance · volume)`, i.e. local → clip, the same product the renderer uses.
Note `Camera::get_projection_matrix()` is typed `Transform3d` (nominally affine) but its perspective
form explicitly writes a `(0, 0, 1, 0)` bottom row into the underlying 4×4, so `clip.w = z_eye` is
genuinely carried. The build therefore multiplies **`.matrix()` products** (plain `Matrix4d`), never
`Transform3d` products, which would not compose that row correctly.
- Window coordinates follow `igl::project`'s convention (as `CameraUtils::project` does), with y
measured downward. Writing `uv = (win rect_origin) / rect_size` makes u and v affine in
`ndc = clip.xyz / clip.w`; multiplying through by `clip.w` leaves a plain linear combination of `K`'s
rows, which is exactly the 3×4 matrix - the perspective divide survives intact.
- `w > 0` is checked rather than divided blindly. A point behind the projector has `w < 0` and divides
to a plausible-looking but **mirrored** uv - the classic way a projected decal reappears on the back
of a model. `project_uv_projective()` returns false there and the caller treats it as no height.
The map already includes placement, so `apply_uv_transform()` is **not** applied on top of it - the
window's own position and size are the placement, and the tiling/rotation/offset sliders would shove
the result off the frame the user just aligned. A "Clear" button drops back to the affine path where
those controls mean something again.
Apply also sets `tile_enabled = false`, so `DecodedHeightTexture::sample()` returns 0 outside `[0,1)`
and the border is a hard edge rather than the first seam of an endless repeat, and repaints the layer
via `select_visible_faces(&matrix)` - the frame's uv square clips the selection, which both matches the
paint to the border and keeps the ray queries proportional to the framed area instead of the model.
Owned by the gizmo and **destroyed** (not just hidden) in `on_shutdown()`. Closing it only hides it, so
reopening keeps it where it was left.
### UV Editor pane
`UVEditorCanvas` (`src/slic3r/GUI/UVEditorCanvas.hpp/.cpp`) - a standalone `wxGLCanvas` rendering the
flattened LSCM islands (per-island wireframe + outline + fill) over the height texture (background
quad tiled across the whole unwrap), with mouse pan/zoom. It is wrapped in a **`UVEditorPanel`**
(same file) that adds a button row (Frame / Snap / Avg scale / Cut / Join / Unjoin) and a status line
along the bottom naming the current gesture and the shortcuts in play. The *panel* is what is
registered as a `wxAuiPaneInfo` pane on `Plater`'s `m_aui_mgr`; `Plater::show_uv_editor(bool)`
shows/hides it (deferred via `CallAfter`, since the gizmo calls it mid-3D-frame), and
`get_uv_editor_canvas()` returns the inner canvas the gizmo talks to.
Deliberately **shares the app's one real `wxGLContext`** (`wxGetApp().init_glcontext(*this)`, the
same call `View3D`/`Preview`/`AssembleView` make) rather than creating an independent context like
`SkipPartCanvas` does elsewhere in this codebase - this is what lets it reuse the already-registered
`"flat"`/`"flat_texture"` shaders and `GLModel` as-is, instead of needing its own shader
compilation/VBO management.
**Geometry is uploaded once, in the unwrap's own (raw, mm) coordinates**, one `GLModel` set per island;
each island is then drawn through its own 2x3 affine (`island_transform_matrix()` composed with the
layer's tiling/rotation/offset) passed as the `flat` shader's `view_model_matrix`. A drag updates one
matrix per island and touches no vertex buffer - `on_island_edited(!finished)` calls only
`set_island_transforms()`, and the full `set_islands()` rebuild happens solely when the unwrap itself
changes (`unwrap_changed` in `update_uv_editor()`).
**Gestures** (canvas-owned, reported to the gizmo as incremental deltas via `IslandEditFn`): left-drag
= move, right-drag or **R** = rotate (hold **Shift** to snap to 15° steps - quantised on the
*cumulative* rotation, not each delta, so it doesn't judder, and accumulated incrementally so it
survives crossing ±180°), **S** = scale (R/S modal, click/Enter to confirm, Esc to cancel), wheel =
zoom about the cursor, middle-drag = pan, **Home**/**F** = frame all. Scale writes
`TextureIsland::scale`; "Avg scale" (`average_island_scales()`) sets every island to the mean, so
one island scaled by hand can be matched back to its neighbours' texel density. **Snap** (canvas-owned
`m_snap_enabled`, toggled from the toolbar) sticks a dragged island's nearest boundary vertex onto a
neighbouring island's at drag-*end* only - a magnet that re-applies mid-drag is very hard to pull out
of. Toolbar commands the canvas can't service itself (Avg scale, Cut, Join, Unjoin) are forwarded to the
gizmo via `CommandFn`; view-only ones (Frame, Snap) it handles directly.
## File map
**libslic3r (core, no GUI dependency):**
- `src/libslic3r/TextureDisplacement.hpp/.cpp` - data model, bake algorithm, projection methods,
tiling, subdivision (uniform + adaptive longest-edge bisection), post-process smoothing
(`smooth_mesh_vertices()`), and `TextureDisplacementOptions` (the whole-stack settings). See doc
comments throughout, they're kept accurate and up to date.
- `src/libslic3r/MeshBoolean.hpp/.cpp` - `parameterize_lscm()` and `remesh_isotropic()` in the `cgal`
sub-namespace, reusing the existing `CGALMesh`/`_EpicMesh`/conversion-helper infrastructure already
there for mesh boolean ops. CGAL includes: `Polygon_mesh_processing/border.h`,
`Polygon_mesh_processing/connected_components.h`, `Surface_mesh_parameterization/{Error_code,
LSCM_parameterizer_3, parameterize}.h`. No new dependency - CGAL 5.6.3 is already vendored and the
`Surface_mesh_parameterization` package headers were already present.
- `src/libslic3r/Model.hpp/.cpp` - the 8 named `FacetsAnnotation` fields + accessor,
`texture_displacement_layers`, `texture_displacement_options`, and all the mirrored touch points
(see Data model above).
**GUI:**
- `src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp/.cpp` - the gizmo and its whole panel.
- `src/slic3r/GUI/TextureLibrary.hpp/.cpp` - scans the shipped + user texture folders, imports an
arbitrary image into the user folder (converting it to the 8-bit grayscale PNG libslic3r decodes),
and loads a library file's bytes for a layer. The image→grayscale-PNG conversion lives here, on the
GUI side, because libslic3r has no image toolkit; both the import path and the "pick a shipped
texture" path go through the same one function.
- `resources/textures/displacement/*.png` - the 10 shipped height maps (Bricks, Grid, Hexagons,
Knurl, Noise, Quilt, Studs, Waves, Weave, Wood Grain). All 512×512 8-bit grayscale and **seamless**
(each is periodic over the full image in both axes, so tiling shows no seam). Generated
procedurally; the whole `resources/` tree is installed recursively by CMake, so a new folder under
it ships with no build-system change.
- `src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp/.cpp` - background bake commit.
- `src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp/.cpp` - background preview compute
(mirrors the bake job's shape but commits nothing to the Model).
- `src/slic3r/GUI/TextureProjectorFrame.hpp/.cpp` - the semi-transparent projection-frame overlay for
ViewProjected layers (plain 2D `wxPaintDC`, no GL context - see its section above).
- `src/slic3r/GUI/UVEditorCanvas.hpp/.cpp` - the 2D UV unwrap viewer widget.
- `src/slic3r/GUI/Plater.hpp/.cpp` - `uv_editor_canvas` member, AUI pane registration,
`get_uv_editor_canvas()`/`show_uv_editor()`.
- `src/slic3r/GUI/GLShadersManager.cpp` - registers `"texture_displacement_bump"`.
- `resources/shaders/{110,140}/texture_displacement_bump.{vs,fs}` - the fast-preview shader.
- `src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp` - `PainterGizmoType::TEXTURE_DISPLACEMENT`.
- `src/slic3r/GUI/Gizmos/GLGizmosManager.hpp/.cpp` - `EType::TextureDisplacement` registration.
## Tests
`tests/libslic3r/test_texture_displacement.cpp`. Covers `decode_height_texture` round-trip, empty-layer
no-op, full-cube uniform displacement, a second layer over the same area contributing, all four blend
modes (table-driven), the lowest layer ignoring its blend mode, border displace/pin, post-process
smoothing and its mask guarantees, and adaptive subdivision: conformality (`every_edge_used_twice` on a
partially-refined cube - an exact crack detector for a closed mesh), the target edge length actually
being reached, the triangle budget capping the result without opening a crack, curvature-driven
refinement (a Gaussian bump refines at its centre, a linear ramp adds nothing), and the max-edge
baseline.
`BUILD_TESTS` is `OFF` in the checked-in build cache; flip it on to run them:
cmake -S . -B build -DBUILD_TESTS=ON
cmake --build build --config Release --target libslic3r_tests -- -m
./build/tests/libslic3r/Release/libslic3r_tests.exe "[TextureDisplacement]" --order rand
+326
View File
@@ -0,0 +1,326 @@
# Texture Displacement — Feature & Controls Guide
Texture Displacement is a paint-style gizmo that stamps height-map textures onto a model's surface
and turns them into real relief — engraved or embossed detail — either as a live preview or baked
into actual mesh geometry. You paint where the texture applies, stack multiple textures as blended
layers, choose how each is projected onto the surface, and (for the unwrap projection) lay the result
out by hand in a dedicated 2D **UV Editor** pane.
This document describes every feature and control. For the internal architecture and algorithms, see
`TEXTURE_DISPLACEMENT.md`.
---
## Table of contents
1. [Quick start](#quick-start)
2. [Entering the tool](#entering-the-tool)
3. [Selection modes](#selection-modes)
4. [View modes](#view-modes)
5. [Auto update](#auto-update)
6. [Texture layers](#texture-layers)
7. [Per-layer settings](#per-layer-settings)
8. [Projection methods](#projection-methods)
9. [The UV Editor](#the-uv-editor)
10. [Seams](#seams)
11. [Adjust placement (on-model)](#adjust-placement-on-model)
12. [Preparing the mesh: Subdivide & Remesh](#preparing-the-mesh-subdivide--remesh)
13. [Baking & resetting](#baking--resetting)
14. [Controls reference](#controls-reference)
15. [Tips & limitations](#tips--limitations)
---
## Quick start
1. Select an object and open the **Texture displacement** gizmo from the left toolbar.
2. A texture layer is added automatically. Pick a texture from the layer's picker, or import your own.
3. **Paint** the area you want the texture to affect (or press **Select whole model**).
4. The relief appears live on the model. Tune **Depth**, **Tile size**, **Rotation**, etc.
5. If the model is low-poly, use **Subdivide** or **Remesh** so there are enough vertices for detail.
6. Press **Bake** to convert the preview into real geometry, or leave it as a live preview.
> The tool only ever affects the **painted** area. Everything you don't paint keeps its original
> surface, and bake blends the relief seamlessly into it.
---
## Entering the tool
The gizmo lives on the left gizmo toolbar (icon: `toolbar_texture_displacement.svg`). Its settings
panel opens beside the toolbar. You can **Dock panel / Undock panel** (top of the panel) to pin it or
float it freely over the 3D view, and **Close** at the bottom exits the gizmo.
When you first open the tool on a never-textured object it starts with **one texture layer already
added**, so you can paint straight away.
---
## Selection modes
Choose *how* you paint. All three write into the **active layer's** mask.
| Mode | What it does |
|------|--------------|
| **Brush** | Free-hand painting with a round brush. Shows a **Brush size** slider and a **Circle / Sphere** choice (circle = surface disc, sphere = 3D ball that also paints around curves). |
| **Face** | Click a single triangle to paint it. |
| **Connected area** | Click to flood-fill a region; the **Angle threshold** slider limits how far the fill spreads across changes in surface angle. |
- **Select whole model** — marks the entire model as painted for the active layer, instead of
brushing it by hand.
---
## View modes
A row of icon buttons labelled **View** controls how the painted area is shown. The first four are a
radio group; **Wireframe** is an independent toggle. Hover any icon for its tooltip.
| View | Meaning |
|------|---------|
| **Normal** | The true displaced geometry — exactly what **Bake** produces. Rebuilt in the background. |
| **Fast** | A GPU bump-shaded approximation of the *active layer only*. No real geometry movement — quick to update, not exact. Best while tuning or dragging islands. |
| **Checker** | A test grid painted over the unwrap so you can see stretching (squares stay square where the map isn't distorted). |
| **Distortion** | A blue→green→red heatmap of how much each area is compressed or stretched in UV space. Needs the **Unwrap (LSCM)** projection. |
| **Wireframe** | Overlays the mesh edges (white). Independent of the view above; in **Normal** view it sits on the displaced surface. |
---
## Auto update
**Auto update** (on by default) rebuilds the true displaced geometry as soon as *anything* changes —
painting, swapping textures, moving sliders. Turn it off on very heavy models to only rebuild when you
release a slider (painting still updates on stroke end).
---
## Texture layers
You can stack up to **8** texture layers. Each has its own independent paint mask, its own texture,
and its own parameters, and they combine in slot order like layers in an image editor.
- **Add a layer** — the ** icon** to the right of the *Texture layers* heading (reuses the tool icon
for now).
- **Remove** — the button on each layer's header row.
- **Active layer** — click a layer's header (or anywhere in its block) to make it active. The active
layer is the one you paint into and the one whose block is tinted. Only one layer is active at a time.
- **Erase all** — clears the active layer's paint.
Each layer shows a texture **picker** (large preview + name). Open it to choose from the shipped
library or import your own image (any png/jpg/bmp; it's converted to an 8-bit grayscale height map and
copied into your user texture folder so app updates can't overwrite it).
---
## Per-layer settings
| Control | Range / options | What it does |
|---------|-----------------|--------------|
| **Depth (mm)** | 0.0110 (log) | Maximum displacement along the surface normal. |
| **Tile size (mm)** | 0.2200 (log) | Physical size of one texture tile on the surface. |
| **Rotation** | 0360° | Rotates the texture on the surface. |
| **Midlevel** | 010 | The grey level that means "don't move". At 0 the texture only pushes outward; raise it and darker texels cut *inward* (one map both embosses and engraves). 0.5 makes mid-grey neutral. |
| **Smoothing** | 01 | Blurs the height texture before it displaces — rounds hard edges and removes speckle without needing a softer source image. |
| **Edge smoothing** | checkbox + **Edge amount** 01 | Fades the relief to flat toward the *edge of the painted area*, so it blends into the surrounding surface. A small amount softens only a thin band at the very edge; the maximum flattens the whole painted face. |
| **Invert** | checkbox | Flips the height map (peaks become valleys). |
| **Blend** | Add / Subtract / Multiply / Divide | How this layer combines with the layers **below** it where they overlap. Add/Subtract pile relief on or carve it away; Multiply/Divide scale the relief underneath (a mask). The lowest painted layer is the **Base** and always behaves additively. |
| **Tile** | checkbox + **Repeat / Mirrored repeat** | When off, the texture is placed once (a decal) instead of repeating. Mirrored repeat flips every other tile to hide seams. |
| **Projection** | see below | How the texture is mapped onto the painted surface. |
> **Midlevel warning:** cutting inward can fold the surface through itself in sharp concave corners or
> thin walls. Keep Depth small relative to the feature you're cutting into; the panel warns when a deep
> inward setting is risky.
---
## Projection methods
How the 2D texture is wrapped onto the 3D painted area.
| Method | Best for | Notes |
|--------|----------|-------|
| **Triplanar (blended)** | Patches wrapping around edges | Projects from all three axes at once and blends, so there's no seam across a sharp edge. |
| **Cylindrical** | Round, tube-like selections | Wraps the texture around the patch's own centre/axis. |
| **Spherical** | Ball-like selections | Longitude/latitude wrap around the patch centre. |
| **Unwrap (LSCM)** | Flat, controlled layout | A real conformal unwrap. Cuts the area into pieces at sharp edges (see **Seam angle**), flattens each, and lets you lay them out by hand in the **UV Editor**. Unlocks Checker/Distortion, seams, and island editing. |
| **From view** | Decals / slide-projector look | Projects straight onto the surface from the current camera direction. Use **Capture current view** to re-lay it from wherever you're looking. |
### LSCM-only controls
These appear when a layer uses **Unwrap (LSCM)**:
- **Seam angle** (590°) — edges sharper than this are cut so each piece lies flat. Lower cuts more
(less stretching, more seams); raise to keep more in one piece. A box's 90° corners are cut by
default. *Ignored once you've marked any seam by hand* (your seams then define the pieces).
- **Connect islands** (on by default) — lays the unwrap out as a **connected net**: pieces that share
an edge are unfolded next to each other (a cube becomes a joined net instead of six loose squares).
They stay separate islands, so you can still move any of them by hand. Turn off for the classic
packed-grid layout.
- **Open UV editor** — shows the flattened unwrap in a side pane (see below). Opens *only* when you
turn this on — it never pops up on its own.
- **Mark seams** / **Path** / **Clear seams** — see [Seams](#seams).
- An **Unwrap: N islands, F faces, V verts** read-out tells you what the unwrap actually produced.
---
## The UV Editor
A dockable 2D pane (enable **Open UV editor** on an LSCM layer) showing the flattened unwrap over the
height texture. Islands are the flattened pieces; you can rearrange them freely — nothing re-packs them
behind your back. Moving an island updates the model **live** (in Fast view it tracks the cursor
smoothly, via a shader uniform — no rebuild until you release).
### Navigation
| Action | Control |
|--------|---------|
| Pan | Middle-drag |
| Zoom | Mouse wheel (zooms about the cursor) |
| Frame everything | **Home** or **F**, or the **Frame** toolbar button |
### Editing an island
| Action | Control |
|--------|---------|
| Select | Left-click an island |
| Move | Left-drag |
| Rotate | Right-drag, or press **R** then move the mouse (click/Enter to confirm, Esc to cancel) |
| Rotate snapped | Hold **Shift** while rotating — snaps to **global** 15° marks (0/15/30…). A protractor dial with tick marks and the current angle is shown. |
| Scale | Press **S** then move the mouse (click/Enter to confirm, Esc to cancel) |
| Undo / Redo | **Ctrl+Z** / **Ctrl+Shift+Z** or **Ctrl+Y** |
The **selected** island gets a bold light-green outline and a brighter wireframe; unselected islands
are a translucent light-green wash. The texture underneath repeats exactly as it will when baked.
A **status line** along the bottom always names the current gesture and the shortcuts in play.
### Toolbar
| Button | Action |
|--------|--------|
| **Frame** | Frame all islands (same as Home). |
| **Snap** | Toggle magnetic snapping — a dragged island sticks its boundary to a neighbour's when they come close. |
| **Avg scale** | Give every island the same texel density (Blender's "Average Islands Scale"). |
| **Cut** | Split the selected island across its long axis (useful for very long islands). |
| **Join** | Unfold the selected island onto its nearest neighbour along their shared edge — keeps both as separate islands with their own borders. |
| **Unjoin** | Send the selected island back to its own packed position. |
> **Checker / Distortion in the UV editor:** selecting those View modes also colours the UV pane — a
> checker background, or a per-island distortion heatmap — so you can judge stretch in 2D as well as
> on the model.
---
## Seams
Seams are edges the unwrap is forced to cut along, on top of whatever the Seam angle cuts — the
Blender "mark seam" workflow. They let you control exactly where the unwrap splits.
Enable **Mark seams** on an active LSCM layer, then:
- **Click an edge** on the model to mark it (it turns **red**); click a red edge again to unmark it.
The edge under the cursor is highlighted **yellow** so you can see what a click will toggle.
- **Path mode** (the **Path** checkbox) — for dense meshes where clicking each edge is tedious: click a
start point, then an end point, and the whole **shortest path** between them is seamed at once. It
chains (each click extends from the last point); the start vertex is shown in **green**.
- **Ctrl+drag** rotates/pans the camera while in seam mode.
- **Clear seams** removes them all.
Once any seam is marked, the automatic Seam-angle cutting is disabled so *your* seams define the
islands — pieces you leave un-seamed merge together.
---
## Adjust placement (on-model)
**Adjust placement** (on an active layer) lets you position the texture by dragging a handle on the
model instead of nudging the Rotation/offset numbers. The handle is a flat panel in the patch's
tangent plane (drag anywhere on it to move freely) plus U/V arrows for single-axis nudges. It's
anchored to the painted patch, so paint something first.
---
## Preparing the mesh: Subdivide & Remesh
Displacement can only move vertices that exist, so a coarse model needs more of them first.
### Subdivide
Splits every triangle into four, **15 times** (each step roughly quadruples the triangle count).
- **Subdivide steps** (15) — how many times to split.
- **Preview subdivision** — shows the result as a **cyan wireframe** without changing the model.
- **Apply** — commits the subdivision to the geometry.
- **Done** — ends the preview and leaves the model as it is.
### Remesh
Rebuilds the whole model with triangles close to a target edge length — evens out a mesh with wildly
varying triangle sizes (CGAL isotropic remeshing).
- **Target edge (mm)** — desired triangle edge length (seeded to the model's current average).
- **Remesh** — splits the big triangles and merges the small ones to that size.
> Both Subdivide-Apply and Remesh **replace the geometry** and clear any *not-yet-baked* paint on it
> (already-baked relief is kept). If you had the mesh **Wireframe** on before, it stays on afterward.
---
## Baking & resetting
- **Bake** — converts the current preview into real, permanent mesh geometry, restricted to the
painted area. Runs in the background; the button shows *Baking…* while it works.
- **Erase all** — clears the active layer's paint.
Baking is the exact same algorithm as the **Normal** preview, so what you see is what you get.
---
## Controls reference
### Mouse — 3D view (while painting)
| Input | Action |
|-------|--------|
| Left-drag | Paint the active layer |
| Ctrl + drag | Rotate / pan the camera (works in seam mode too) |
| Wheel | Zoom |
### Mouse & keys — UV Editor
| Input | Action |
|-------|--------|
| Left-click | Select island |
| Left-drag | Move island |
| Right-drag | Rotate island |
| **R** / **S** | Modal rotate / scale (mouse drives it, click or Enter confirms, Esc cancels) |
| **Shift** (while rotating) | Snap to global 15° marks |
| Middle-drag | Pan |
| Wheel | Zoom about cursor |
| **Home** / **F** | Frame all islands |
| **Ctrl+Z** / **Ctrl+Shift+Z** / **Ctrl+Y** | Undo / redo |
### Seam mode
| Input | Action |
|-------|--------|
| Click edge | Mark / unmark a seam (yellow = hover, red = marked) |
| Click (Path mode) | Set start, then seam the shortest path to the next click |
| Ctrl + drag | Rotate / pan camera |
---
## Tips & limitations
- **Paint first, then bake.** The preview is free to explore; only Bake changes the real mesh.
- **Not enough detail?** Subdivide or Remesh before painting fine textures.
- **Inward cuts** (high Midlevel + big Depth) can self-intersect on thin walls or sharp concave
corners — keep Depth modest there.
- **Fast vs Normal:** Fast preview shades a bump and shows only the active layer; use it for quick
tuning and smooth UV dragging, but trust **Normal**/**Bake** for the exact result.
- **Topology changes drop unbaked paint.** Subdivide-Apply, Remesh, and Simplify replace the mesh, and
texture-displacement paint isn't remapped across that change (already-baked relief is unaffected).
- **Island placements** are tied to the current unwrap. Re-painting or changing the Seam angle can
re-segment the charts and renumber them, so a re-unwrap re-lays the connected net and discards
hand placements made before it.
- **Connect islands** is on by default; turn it off (per layer) for the classic packed-grid layout, or
if an unfold looks wrong on an unusual mesh.
+11 -23
View File
@@ -156,7 +156,7 @@ if (NOT _is_multi AND NOT CMAKE_BUILD_TYPE)
endif ()
function(orcaslicer_add_cmake_project projectname)
cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND;SOURCE_DIR" "CMAKE_ARGS" ${ARGN})
cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
# MSVC is true for clang-cl as well, so the sub-build toolchain has to key on the
# generator. A non-Visual-Studio superbuild passes its own generator down, and with
@@ -202,18 +202,12 @@ function(orcaslicer_add_cmake_project projectname)
set(_build_j "-j${NPROC}")
endif ()
set(_source_dir_arg "")
if (P_ARGS_SOURCE_DIR)
set(_source_dir_arg SOURCE_DIR ${P_ARGS_SOURCE_DIR})
endif ()
if (NOT IS_CROSS_COMPILE OR NOT APPLE)
ExternalProject_Add(
dep_${projectname}
EXCLUDE_FROM_ALL ON
INSTALL_DIR ${DESTDIR}
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
${_source_dir_arg}
${_gen}
CMAKE_ARGS
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
@@ -246,14 +240,12 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
# note for future devs: shared libs may actually create a size reduction
# but orcaslicer_deps tends to get really funny regarding linking after that (notably boost)
# so, as much as I would like to use that, it's not happening
if (NOT P_ARGS_SOURCE_DIR)
ExternalProject_Add_Step(dep_${projectname} free_download_space
DEPENDEES download # do after download
COMMENT "Freeing Space: Removing source archive"
WORKING_DIRECTORY ${DEP_DOWNLOAD_DIR}
COMMAND ${CMAKE_COMMAND} -E rm -rf ${projectname}
)
endif ()
ExternalProject_Add_Step(dep_${projectname} free_download_space
DEPENDEES download # do after download
COMMENT "Freeing Space: Removing source archive"
WORKING_DIRECTORY ${DEP_DOWNLOAD_DIR}
COMMAND ${CMAKE_COMMAND} -E rm -r ${projectname}
)
ExternalProject_Add_Step(dep_${projectname} free_build_space
DEPENDEES install # do after install
COMMENT "Freeing Space: Removing source and build files"
@@ -267,7 +259,6 @@ else()
EXCLUDE_FROM_ALL ON
INSTALL_DIR ${DESTDIR}
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
${_source_dir_arg}
${_gen}
CMAKE_ARGS
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
@@ -395,6 +386,10 @@ include(libnoise/libnoise.cmake)
include(Draco/Draco.cmake)
include(FFMPEG/FFMPEG.cmake)
include(Assimp/Assimp.cmake)
# I *think* 1.1 is used for *just* md5 hashing?
# 3.1 has everything in the right place, but the md5 funcs used are deprecated
# a grep across the repo shows it is used for other things
@@ -405,12 +400,6 @@ if(NOT OPENSSL_FOUND)
set(OPENSSL_PKG dep_OpenSSL)
endif()
include(FFMPEG/FFMPEG.cmake)
include(Assimp/Assimp.cmake)
include(DataChannel/DataChannel.cmake)
set(DATACHANNEL_PKG dep_DataChannel)
# we don't want to load a "wrong" openssl when loading curl
# so, just don't even bother
# ...i think this is how it works? change if wrong
@@ -484,7 +473,6 @@ set(_dep_list
dep_wxInspector
dep_FFMPEG
dep_Assimp
${DATACHANNEL_PKG}
)
if (MSVC)
-37
View File
@@ -1,37 +0,0 @@
# libdatachannel is the native ICE/DTLS/SCTP implementation used by the
# GUI WebRTC camera controller. Keep the source revision fixed: the signaling
# protocol is evolving independently of this transport dependency.
#
# It vendors plog, usrsctp and libjuice as git submodules, which a plain
# GitHub tag tarball does not include. The flatpak sandbox has no network
# access during the build, so there the manifest itself clones the repo
# (submodules and all) into the dependency download directory before the
# sandbox closes. ExternalProject_Add is pointed at that existing checkout
# instead of being given its own network-dependent download method.
if (FLATPAK)
set(_datachannel_source
SOURCE_DIR ${DEP_DOWNLOAD_DIR}/DataChannel
)
else()
set(_datachannel_source
GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git
GIT_TAG v0.24.5
GIT_SHALLOW ON
GIT_SUBMODULES_RECURSE ON
)
endif()
orcaslicer_add_cmake_project(DataChannel
DEPENDS ${OPENSSL_PKG}
CMAKE_ARGS
-DNO_EXAMPLES=ON
-DNO_TESTS=ON
-DNO_WEBSOCKET=ON
-DNO_MEDIA=ON
-DUSE_NICE=OFF
-DUSE_SYSTEM_JUICE=OFF
-DUSE_SYSTEM_USRSCTP=OFF
-DOPENSSL_ROOT_DIR:PATH=${DESTDIR}
-DOPENSSL_USE_STATIC_LIBS=ON
${_datachannel_source}
)
+7 -23
View File
@@ -1,26 +1,14 @@
set(_conf_cmd ./configure)
set(_ffmpeg_depends)
set(_ffmpeg_configure_command ${_conf_cmd})
if (TARGET dep_OpenSSL)
set(_ffmpeg_depends DEPENDS dep_OpenSSL)
set(_ffmpeg_configure_command
${CMAKE_COMMAND} -E env
"PKG_CONFIG_PATH=${DESTDIR}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}"
${_conf_cmd}
)
endif()
if (MSVC)
set(_source_dir "${CMAKE_BINARY_DIR}/dep_FFMPEG-prefix/src/dep_FFMPEG")
set(PREBUILD_URL_arm64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-09-18-16-50/ffmpeg-n7.0.3-33-g887d4b4919-winarm64-orca-shared-7.0.zip")
set(PREBUILD_HASH_arm64 "da480cbb39680056de824c57ec4dc3bd577b479ebbc310ff1f9dc55cf014b4c1")
set(PREBUILD_URL_x64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-09-18-16-50/ffmpeg-n7.0.3-33-g887d4b4919-win64-orca-shared-7.0.zip")
set(PREBUILD_HASH_x64 "85da19daf198f5548259d8aabb349db84997a3f6e6886d8d7764114add9c6dae")
set(PREBUILD_URL_arm64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-07-17-14-28/ffmpeg-n7.0.3-31-g9b6ffd74b5-winarm64-orca-shared-7.0.zip")
set(PREBUILD_HASH_arm64 "12f4140279f2f8469885e1b5b2e8be9d788882914c21523cacd56989f3548054")
set(PREBUILD_URL_x64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-07-17-14-28/ffmpeg-n7.0.3-31-g9b6ffd74b5-win64-orca-shared-7.0.zip")
set(PREBUILD_HASH_x64 "e65916020ddb9ef84b2666dfbcbfc9b1d67f69d15b4a66db53754637bf2d498c")
ExternalProject_Add(dep_FFMPEG
${_ffmpeg_depends}
URL ${PREBUILD_URL_${DEPS_ARCH}}
URL_HASH SHA256=${PREBUILD_HASH_${DEPS_ARCH}}
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/FFMPEG
@@ -33,8 +21,6 @@ if (MSVC)
)
else ()
set(_openssl_cmd --enable-openssl)
if (APPLE)
set(_minos_cmd
"--extra-cflags=-mmacosx-version-min=${DEP_OSX_TARGET}"
@@ -66,11 +52,10 @@ else ()
endif()
ExternalProject_Add(dep_FFMPEG
${_ffmpeg_depends}
URL https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.0.3.tar.gz
URL_HASH SHA256=DEEDCABE339165214A3637DF4C86A507AEF0D793CF8774FF68735F4737E8DDBC
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/FFMPEG
CONFIGURE_COMMAND ${_ffmpeg_configure_command}
CONFIGURE_COMMAND ${_conf_cmd}
${_cross_cmd}
${_pic_cmd}
${_arch_cmd}
@@ -78,21 +63,20 @@ else ()
"--prefix=${DESTDIR}"
${_link_cmd}
${_minos_cmd}
${_openssl_cmd}
--disable-doc
--enable-small
--disable-outdevs
--disable-filters
--enable-filter=*null*,afade,*fifo,*format,*resample,aeval,allrgb,allyuv,atempo,pan,*bars,color,*key,crop,draw*,eq*,framerate,*_qsv,*_vaapi,*v4l2*,hw*,scale,volume,test*
--disable-protocols
--enable-protocol=file,fd,pipe,http,https,rtp,tcp,udp
--enable-protocol=file,fd,pipe,rtp,udp
--disable-muxers
--enable-muxer=rtp
--disable-encoders
--disable-decoders
--enable-decoder=*aac*,h264*,mp3*,mjpeg,rv*
--disable-demuxers
--enable-demuxer=h264,mp3,mov,mpjpeg,rtsp,sdp
--enable-demuxer=h264,mp3,mov
--disable-zlib
--disable-avdevice
BUILD_IN_SOURCE ON
-240
View File
@@ -1,240 +0,0 @@
# Printer agents
Printer agents isolate printer-specific communication from the rest of OrcaSlicer. The GUI and
`DeviceManager` operate on a shared set of printer operations and device state; a selected printer
agent implements those operations for a particular printer ecosystem. The agent boundary allows
Bambu, Moonraker-based printers, built-in integrations, and Python-provided integrations to use the
same application workflow without making the GUI understand every printer protocol.
The current boundary is an adapter boundary around the existing application contract. In particular,
some request fields and message payloads still use the Bambu-shaped representation that existing
`MachineObject` and `DeviceManager` code consumes. The printer agent is responsible for translating
that representation into the protocol spoken by its printer. This is an intentional compatibility
constraint of the current design; the interface is not yet a neutral printer protocol.
The v1 dialect migration path is deliberately narrow. `DeviceManager` currently speaks the Bambu JSON
dialect because that is the payload shape already used throughout the command and state workflow. The
v1 `OrcaPrinterAgent` also accepts that Bambu dialect. Its transport path places the small translation
needed for the target printer at `deliver_to_sink`, keeping the compatibility code at the edge rather
than spreading it through `DeviceManager` or the agent interface.
The eventual direction is for `DeviceManager` to produce an Orca JSON dialect. The Bambu agent will then
own the translation from Orca JSON to Bambu's protocol, while `OrcaPrinterAgent` can forward the Orca
payload directly to its sink. The v1 translation at `deliver_to_sink` can then be removed without
changing `DeviceManager`, the command callers, or the rest of the agent workflow.
## Components
The system has four relevant layers:
```text
GUI / DeviceManager / MachineObject
|
NetworkAgent
/ \
IPrinterAgent ICloudServiceAgent
| |
printer protocol authentication and cloud services
```
### `DeviceManager` and `MachineObject`
`DeviceManager` owns the application-facing printer workflow. It maintains `MachineObject` instances,
updates their state, filters devices for the active printer agent, and initiates operations such as
homing, temperature changes, printing, subscriptions, and camera playback.
`MachineObject` remains the shared state model used by the GUI. It does not contain the implementation
of a printer protocol. When a device is discovered or returned by a cloud query, the device is tagged
with the active `printer_agent_id`. Device lists and selected-machine operations use that tag to avoid
sending an operation through an agent that does not own the device.
### `NetworkAgent`
`NetworkAgent` is the façade used by the GUI and `DeviceManager`. It owns:
- the currently selected `IPrinterAgent`;
- the registered cloud-service instances, indexed by provider;
- callbacks shared by the active printer agent and the application;
- the forwarding methods for printer commands and cloud operations.
There is one active printer agent for the currently selected printer preset. Switching the preset
increments the machine-list generation, disconnects the old printer agent, removes its callbacks, and
installs the newly selected agent. The façade then forwards printer operations to that agent.
Cloud operations are selected separately using a provider key. `NetworkAgent` forwards a cloud request
to the matching `ICloudServiceAgent`, and forwards cloud camera operations with a device ID. The
printer agent receives a cloud-agent pointer through `set_cloud_agent()` when it is created, allowing
printer communication to obtain cloud tokens without depending on a concrete cloud implementation.
### `IPrinterAgent`
`IPrinterAgent` is the printer-facing contract. It covers:
- cloud-relay and direct-LAN message delivery;
- LAN connection, discovery, binding, and certificates;
- printer subscriptions and callbacks;
- print operations;
- filament synchronization;
- camera capability and local camera URL reporting;
- printer command methods.
Concrete built-in implementations include the Bambu wrapper, the native Orca/Moonraker path, and
other printer-agent implementations registered by the application. A printer agent may use either
the cloud agent, a direct LAN connection, or both.
### `ICloudServiceAgent`
`ICloudServiceAgent` owns authentication and services provided by a cloud backend. It covers login
state, tokens, user and printer lists, settings synchronization, model services, cloud messages, and
cloud camera operations.
Cloud camera operations are device-scoped:
- `get_camera_url(dev_id, callback)` obtains a stream URL for one device;
- `create_camera_signaling_channel(dev_id)` creates signaling for one device where the provider
supports it.
This is separate from the local camera URL exposed by `IPrinterAgent`, which is currently scoped to
the active printer agent because a normal LAN agent represents one physical printer connection.
## Agent registration and selection
`NetworkAgentFactory` maintains the printer-agent registry. Each registry entry contains an agent ID,
a display name, and a factory function. Built-in agents register during application initialization.
Python printer-agent capabilities register dynamically and contribute an agent ID and factory entry.
The selected printer preset contains the printer-agent choice. If no explicit choice is stored, the
application preserves the existing default behavior: Bambu presets select the Bambu agent and other
presets select the native Orca agent. When a preset is changed, `GUI_App` resolves the effective agent
ID, obtains the corresponding cloud agent, creates the printer agent through the registry, and installs
it in `NetworkAgent`.
The registry rejects conflicting agent IDs. This matters for Python plugins because an agent ID is the
stable identity used by presets and device ownership; two enabled plugin capabilities must not claim
the same ID.
## Message and command flow
There are two low-level message paths:
- `send_message()` publishes a command through the printer's cloud relay;
- `send_message_to_printer()` sends a command directly to the printer over the LAN path.
Both paths accept a JSON string, quality-of-service and flag values, and return the existing network
status code domain. The agent owns the conversion from that JSON contract to its native transport.
The typed `command_*` methods are the application-facing convenience layer. The five generic defaults
currently implemented by `IPrinterAgent` construct the existing JSON dialect and route through the
same message path:
| Method | Default operation |
| --- | --- |
| `command_xyz_abs()` | Send `G90` for absolute positioning |
| `command_auto_leveling()` | Send `G29` for bed leveling |
| `command_go_home()` | Use the supported homing operation or send `G28` |
| `command_set_bed()` | Use the supported bed control or send `M140` |
| `command_set_nozzle()` | Send `M104` for nozzle temperature |
These are compatibility defaults for common printer workflows, not a guarantee that every firmware
implements every command identically. An agent can override a method when its protocol needs another
operation. For example, a Klipper configuration may use `BED_MESH_CALIBRATE` instead of `G29`.
The remaining common command methods default to `ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED` because their
existing behavior is vendor-specific or has no portable implementation:
- AMS RFID refresh;
- AMS calibration;
- AMS tray selection;
- camera start;
- axis control.
The methods remain on the common interface so an agent that supports them can override them explicitly.
`sequence_id` remains part of the command contract because `DeviceManager` creates and tracks it as
the command ID.
## Device ownership and stale responses
Printer-agent ownership is represented by `printer_agent_id` on device records and `MachineObject`
instances. The active agent ID is attached when a device is discovered, returned by a cloud list, or
reused after a preset switch. Local-machine configuration also persists the agent ID so a saved LAN
device is not silently reused by an unrelated agent.
Cloud printer-list responses carry three pieces of request context added by `NetworkAgent`:
```text
provider cloud provider used for the request
agent_id active printer agent when the request was made
generation machine-list generation when the request was made
```
`DeviceManager` accepts the response only when those values still match the current provider, active
agent, and generation. This prevents a slow response from the previous preset or provider from
repopulating the current device list.
The provider mapping is currently selected by `GUI_App`: the Bambu agent maps to the Bambu cloud
provider and other agents map to the Orca cloud provider. The generation check protects that existing
selection from races; it does not make cloud-provider ownership intrinsic to an agent. Cloud-printer
ownership and the broader Orca cloud services are therefore still separate architectural concerns.
## Python printer agents
`PrinterAgentPluginCapability` implements `IPrinterAgent` directly. The live capability object is
registered with `NetworkAgentFactory` and handed out as the printer agent when its agent ID is selected.
The plugin receives the selected `ICloudServiceAgent` through `set_cloud_agent()` just like a built-in
printer agent.
Python plugins must implement the core communication and lifecycle methods required by the interface,
including agent metadata, printer connection, discovery callbacks, and the two message-send methods.
Methods that are meaningful only to a particular printer are optional overrides where the C++ base
class provides a default.
All ten `command_*` methods are available in the Python binding and in the trampoline. Their override
status is intentionally optional:
- the five generic commands use the C++ default when Python does not override them;
- the five vendor-specific commands return `NOT_SUPPORTED` unless Python supplies an implementation;
- a Python implementation can replace either behavior for its own protocol.
The Python camera binding exposes HTTP, HTTPS, RTSP, and HTTP-snapshot modes. WebRTC remains a
built-in C++ camera mode, but is not exposed as a Python mode because the current Python capability
does not provide the corresponding cloud signaling-channel contract.
## Camera playback boundary
The camera stream mode describes how a stream is obtained; it does not by itself define ownership of
the wxWidgets view that renders it. `MediaPlayCtrl` selects and tears down the active backend, while
the wx parent owns the child window or renderer. This is important because a web view, native media
control, and frame-based/WebRTC renderer have different wx window-lifetime requirements.
Cloud URL and signaling requests are routed through `NetworkAgent` to the cloud provider selected for
the device. Local URL requests are routed to the active printer agent. The distinction keeps cloud
account services device-scoped while preserving the current one-LAN-agent/one-printer model.
## Compatibility constraints
The printer-agent boundary intentionally preserves several existing application contracts:
- Bambu-shaped JSON is still the shared command representation;
- existing network status codes are reused, with Orca-specific unsupported/capability errors added
in the Orca-reserved range;
- `MachineObject` remains the shared device-state model;
- preset and local-machine data retain compatibility with the existing agent-selection behavior;
- Python plugins use the existing capability and pybind11 registration system.
The agent abstraction is therefore responsible for containing vendor differences, not for pretending
that all vendor protocols are identical. The planned Orca JSON dialect is the protocol-neutral command
model for the `DeviceManager`/agent boundary. Once it is introduced, Bambu-specific translation remains
inside the Bambu agent and the Orca agent's v1 sink adapter can be removed as a self-contained cleanup.
## Main implementation locations
- [`IPrinterAgent`](../../src/slic3r/Utils/IPrinterAgent.hpp) — printer-agent contract and generic command defaults
- [`ICloudServiceAgent`](../../src/slic3r/Utils/ICloudServiceAgent.hpp) — cloud service and per-device
cloud camera contract
- [`NetworkAgent`](../../src/slic3r/Utils/NetworkAgent.hpp) — façade and dispatch between active agents
- [`NetworkAgentFactory`](../../src/slic3r/Utils/NetworkAgentFactory.hpp) — built-in and Python agent registry
- [`DeviceManager`](../../src/slic3r/GUI/DeviceCore/DevManager.cpp) — device ownership, filtering, and
stale-response checks
- [`PrinterAgentPluginCapability`](../../src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.cpp)
— Python bindings
- [`MediaPlayCtrl`](../../src/slic3r/GUI/MediaPlayCtrl.cpp) — camera backend selection and playback lifecycle
+4 -4
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -6161,6 +6161,9 @@ msgstr ""
msgid "Preferences"
msgstr ""
msgid "Open speed dial"
msgstr ""
msgctxt "Menu"
msgid "Edit"
msgstr ""
@@ -6168,9 +6171,6 @@ msgstr ""
msgid "View"
msgstr ""
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr ""
+4 -4
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2025-03-15 10:55+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -6637,6 +6637,9 @@ msgstr "Mostrar el contorn al voltant de l'objecte seleccionat a l'escena 3D"
msgid "Preferences"
msgstr "Preferències"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6645,9 +6648,6 @@ msgstr "Edita"
msgid "View"
msgstr "Vista"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "Paquet de perfils"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: Jakub Hencl\n"
"Language-Team: \n"
@@ -6602,6 +6602,9 @@ msgstr "Zobrazit obrys kolem vybraného objektu ve 3D scéně."
msgid "Preferences"
msgstr "Předvolby"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6610,9 +6613,6 @@ msgstr "Upravit"
msgid "View"
msgstr "Zobrazit"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Balík předvoleb"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: Heiko Liebscher <hliebschergmail.com>\n"
"Language-Team: \n"
@@ -6490,6 +6490,9 @@ msgstr "Kontur um das ausgewählte Objekt in der 3D-Szene anzeigen."
msgid "Preferences"
msgstr "Einstellungen"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6498,9 +6501,6 @@ msgstr "Bearbeiten"
msgid "View"
msgstr "Ansicht"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Vorlagen-Bundle"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-06-17 15:44-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: \n"
@@ -6157,6 +6157,9 @@ msgstr ""
msgid "Preferences"
msgstr ""
msgid "Open speed dial"
msgstr ""
msgctxt "Menu"
msgid "Edit"
msgstr ""
@@ -6164,9 +6167,6 @@ msgstr ""
msgid "View"
msgstr ""
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr ""
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: Ian A. Bassi <>\n"
"Language-Team: \n"
@@ -6346,6 +6346,9 @@ msgstr "Mostrar el contorno alrededor del objeto seleccionado en la escena 3D."
msgid "Preferences"
msgstr "Preferencias"
msgid "Open speed dial"
msgstr ""
msgctxt "Menu"
msgid "Edit"
msgstr "Edición"
@@ -6353,9 +6356,6 @@ msgstr "Edición"
msgid "View"
msgstr "Vista"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Paquete de perfiles"
+4 -4
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-07-20 13:33+0200\n"
"Last-Translator: Manu Goiogana <mgoiogana@gmail.com>\n"
"Language-Team: \n"
@@ -6392,6 +6392,9 @@ msgstr "Erakutsi hautatutako objektuaren inguruko ingerada 3D eszenan."
msgid "Preferences"
msgstr "Hobespenak"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6400,9 +6403,6 @@ msgstr "Editatu"
msgid "View"
msgstr "Bista"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Aurrezarpen-paketea"
+4 -4
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: Guislain Cyril, Thomas Lété\n"
@@ -6439,6 +6439,9 @@ msgstr "Afficher le tracé contour de lobjet sélectionné dans la scène 3D.
msgid "Preferences"
msgstr "Préférences"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6447,9 +6450,6 @@ msgstr "Édition"
msgid "View"
msgstr "Affichage"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Paquet de préréglages"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -6541,6 +6541,9 @@ msgstr "Körvonal megjelenítése a kijelölt objektum körül a 3D nézetben."
msgid "Preferences"
msgstr "Beállítások"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6549,9 +6552,6 @@ msgstr "Szerkesztés"
msgid "View"
msgstr "Nézet"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Beállításcsomag"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -6543,6 +6543,9 @@ msgstr "Mostra il contorno attorno all'oggetto selezionato nella scena 3D."
msgid "Preferences"
msgstr "Preferenze"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6551,9 +6554,6 @@ msgstr "Modifica"
msgid "View"
msgstr "Vista"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Pacchetto profili"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -6553,6 +6553,9 @@ msgstr "3Dシーンで選択したオブジェクトの周りにアウトライ
msgid "Preferences"
msgstr "設定"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6561,9 +6564,6 @@ msgstr "編集"
msgid "View"
msgstr "表示"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "プリセットバンドル"
+4 -4
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2025-06-02 17:12+0900\n"
"Last-Translator: crwusiz <crwusiz@gmail.com>\n"
"Language-Team: \n"
@@ -6566,6 +6566,9 @@ msgstr "3D 장면에서 선택한 객체 주변에 윤곽선 표시"
msgid "Preferences"
msgstr "기본 설정"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6574,9 +6577,6 @@ msgstr "편집"
msgid "View"
msgstr "시점"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "사전 설정 번들"
+4 -4
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-07-02 14:13+0300\n"
"Last-Translator: Gintaras Kučinskas <sharanchius@gmail.com>\n"
"Language-Team: \n"
@@ -6528,6 +6528,9 @@ msgstr "Rodyti kontūrą aplink pasirinktą objektą 3D scenoje."
msgid "Preferences"
msgstr "Parinktys"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6536,9 +6539,6 @@ msgstr "Redaguoti"
msgid "View"
msgstr "Vaizdas"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Profilių rinkinys"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -7122,6 +7122,9 @@ msgstr "Toon een omtrek rond het geselecteerde object in de 3D-scène."
msgid "Preferences"
msgstr "Voorkeuren"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -7130,9 +7133,6 @@ msgstr "Bewerken"
msgid "View"
msgstr "Weergave"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "Voorinstellingenbundel"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OrcaSlicer 2.3.0-rc\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: \n"
"Last-Translator: Krzysztof Morga <<tlumaczeniebs@gmail.com>>\n"
"Language-Team: \n"
@@ -6689,6 +6689,9 @@ msgstr "Przełącza wyświetlanie konturu wokół zaznaczonego obiektu w scenie
msgid "Preferences"
msgstr "Preferencje"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6697,9 +6700,6 @@ msgstr "Edycja"
msgid "View"
msgstr "Widok"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "Pakiet profili"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-07-26 11:14-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: Portuguese, Brazilian\n"
@@ -6363,6 +6363,9 @@ msgstr "Mostrar contorno ao redor do objeto selecionado na cena 3D."
msgid "Preferences"
msgstr "Preferências"
msgid "Open speed dial"
msgstr ""
msgctxt "Menu"
msgid "Edit"
msgstr "Editar"
@@ -6370,9 +6373,6 @@ msgstr "Editar"
msgid "View"
msgstr "Visualizar"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Pacote de Predefinições"
+4 -4
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OrcaSlicer V2.5.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-02-25 13:38+0300\n"
"Last-Translator: Felix14_v2\n"
"Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg <andylg@yandex.ru>\n"
@@ -6597,6 +6597,9 @@ msgstr "Отображение контура вокруг выбранных м
msgid "Preferences"
msgstr "Настройки"
msgid "Open speed dial"
msgstr ""
msgctxt "Menu"
msgid "Edit"
msgstr "Правка"
@@ -6604,9 +6607,6 @@ msgstr "Правка"
msgid "View"
msgstr "Вид"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Пакет профилей"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -7205,6 +7205,9 @@ msgstr "Visa en kontur runt det markerade objektet i 3D-scenen."
msgid "Preferences"
msgstr "Inställningar"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -7213,9 +7216,6 @@ msgstr "Redigera"
msgid "View"
msgstr "Vy"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "Förinställningspaket"
+4 -4
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-06-19 13:40+0700\n"
"Last-Translator: Icezaza\n"
"Language-Team: Thai\n"
@@ -6520,6 +6520,9 @@ msgstr "แสดงเค้าร่างรอบๆ วัตถุที
msgid "Preferences"
msgstr "การตั้งค่า"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6528,9 +6531,6 @@ msgstr "แก้ไข"
msgid "View"
msgstr "มุมมอง"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "ชุดที่ตั้งไว้ล่วงหน้า"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-08-21 23:18+0300\n"
"Last-Translator: GlauTech\n"
"Language-Team: \n"
@@ -6588,6 +6588,9 @@ msgstr "3D sahnede seçilen nesnenin etrafındaki ana hatları göster."
msgid "Preferences"
msgstr "Tercihler"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6596,9 +6599,6 @@ msgstr "Düzen"
msgid "View"
msgstr "Görünüm"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Ön ayar paketi"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: orcaslicerua\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-07-17 16:25+0300\n"
"Last-Translator: Andrij Mizyk <andm1zyk@proton.me>\n"
"Language-Team: Ukrainian\n"
@@ -6557,6 +6557,9 @@ msgstr "Показувати контур навколо виділеного о
msgid "Preferences"
msgstr "Налаштування"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6565,9 +6568,6 @@ msgstr "Редагування"
msgid "View"
msgstr "Вигляд"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "Набір пресетів"
+4 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2025-10-02 17:43+0700\n"
"Last-Translator: \n"
"Language-Team: hainguyen.ts13@gmail.com\n"
@@ -6907,6 +6907,9 @@ msgstr "Hiện đường viền xung quanh vật thể đã chọn trong cảnh
msgid "Preferences"
msgstr "Tùy chọn"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6915,9 +6918,6 @@ msgstr "Chỉnh sửa"
msgid "View"
msgstr "Xem"
msgid "Open Speed Dial"
msgstr ""
# AI Translated
msgid "Preset Bundle"
msgstr "Gói cài đặt sẵn"
+4 -4
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Slic3rPE\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2026-06-11 12:37-0300\n"
"Last-Translator: Handle <mail@bysb.net>\n"
"Language-Team: \n"
@@ -6375,6 +6375,9 @@ msgstr "在3D场景中显示选中对象的轮廓"
msgid "Preferences"
msgstr "偏好设置"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6383,9 +6386,6 @@ msgstr "编辑"
msgid "View"
msgstr "视图"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "预设包"
+4 -4
View File
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
"PO-Revision-Date: 2025-11-28 13:48-0600\n"
"Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n"
"Language-Team: \n"
@@ -6505,6 +6505,9 @@ msgstr "在 3D 場景中顯示選定物件的輪廓"
msgid "Preferences"
msgstr "偏好設定"
msgid "Open speed dial"
msgstr ""
# AI Translated
msgctxt "Menu"
msgid "Edit"
@@ -6513,9 +6516,6 @@ msgstr "編輯"
msgid "View"
msgstr "視角"
msgid "Open Speed Dial"
msgstr ""
msgid "Preset Bundle"
msgstr "設定檔組"
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="7.5" cy="7.5" r="7" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="4" x2="7.5" y2="11" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/><line x1="4" y1="7.5" x2="11" y2="7.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 431 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="7.5" cy="7.5" r="7" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="4" y1="7.5" x2="11" y2="7.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 315 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="5.5" y="5.5" width="4" height="4" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/><path d="M7.5 0.5v4M7.5 10.5v4M0.5 7.5h4M10.5 7.5h4M5.5 2.5l2-2 2 2M5.5 12.5l2 2 2-2M2.5 5.5l-2 2 2 2M12.5 5.5l2 2-2 2" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 407 B

@@ -0,0 +1,330 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="texture_displacement_group.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs17"><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect30"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.2615305,0,1 @ F,0,0,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect29"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect27"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect25"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect24"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect23"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect21"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect19"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect17"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect15"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><linearGradient
id="swatch7"
inkscape:swatch="solid"><stop
style="stop-color:#77eaa3;stop-opacity:1;"
offset="0"
id="stop7" /></linearGradient><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect3"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.49883385,0,1 @ F,0,0,1,0,0.48672135,0,1 @ F,0,0,1,0,0.5261776,0,1 @ F,0,0,1,0,0.50001454,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect2"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9-1"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /></defs><sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="25.28125"
inkscape:cy="18.359375"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" /><path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" /><path
d="m 35.473026,33.999994 v -0.999987 a 0.500013,0.500013 0 0 0 -1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 1 -0.499993,0.499994 h -5.000013 a 0.5000126,0.5000126 0 0 0 0,1.000025 h 5.000013 a 1.5,1.5 0 0 0 1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7" /><path
d="m 5.9730079,35.500013 h 0.999987 a 0.500013,0.500013 0 0 0 0,-1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 1 -0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 0 -1.000025,0 v 5.000013 a 1.5,1.5 0 0 0 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3" /><path
d="m 4.4729879,33.999994 v -0.999987 a 0.500013,0.500013 0 0 1 1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 0 0.499993,0.499994 H 10.97302 a 0.5000126,0.5000126 0 0 1 0,1.000025 H 5.9730069 a 1.5,1.5 0 0 1 -1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5" /><path
d="m 5.9730079,4.499987 h 0.999987 a 0.50001302,0.50001302 0 0 1 0,1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 0 -0.499994,0.499993 v 5.000013 a 0.5000126,0.5000126 0 0 1 -1.0000251,0 V 6.000006 A 1.5,1.5 0 0 1 5.9730079,4.499987 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9" /><path
d="m 4.4729878,6.000006 v 0.999987 a 0.50001302,0.50001302 0 0 0 1.0000261,0 V 6.000006 A 0.49999998,0.49999998 0 0 1 5.9730068,5.500012 H 10.97302 a 0.5000126,0.5000126 0 0 0 0,-1.000025 H 5.9730068 a 1.5,1.5 0 0 0 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8" /><path
d="m 33.973006,4.499986 h -0.999987 a 0.50001302,0.50001302 0 0 0 0,1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 1 34.473,6.000005 v 5.000013 a 0.5000126,0.5000126 0 0 0 1.000025,0 V 6.000005 A 1.5,1.5 0 0 0 33.973006,4.499986 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9-8" /><path
d="m 35.473026,6.000005 v 0.999987 a 0.50001305,0.50001305 0 0 1 -1.000026,0 V 6.000005 A 0.49999998,0.49999998 0 0 0 33.973007,5.500011 h -5.000013 a 0.5000126,0.5000126 0 0 1 0,-1.000025 h 5.000013 a 1.5,1.5 0 0 1 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8-2" /><g
id="g5"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5" /></g><g
id="g31"
transform="translate(-1.2926181,-1.328125)"><path
d="m 11.472656,12.726388 v 6.047224 A 1.2263883,1.2263883 45 0 0 12.699044,20 h 6.074568 A 1.2263883,1.2263883 135 0 0 20,18.773612 V 12.726388 A 1.2263883,1.2263883 45 0 0 18.773612,11.5 h -6.074568 a 1.2263883,1.2263883 135 0 0 -1.226388,1.226388 z m 1.730947,-0.0096 h 5.065451 a 0.47508735,0.47508735 45 0 1 0.475087,0.475087 v 5.303732 a 0.47508735,0.47508735 135 0 1 -0.475087,0.475087 h -5.065451 a 0.47508735,0.47508735 45 0 1 -0.475087,-0.475087 l 0,-5.303732 a 0.47508735,0.47508735 135 0 1 0.475087,-0.475087 z"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
id="path30"
inkscape:path-effect="#path-effect31"
inkscape:original-d="M 11.472656,11.5 V 20 H 20 v -8.5 z m 1.25586,1.216797 h 6.015625 v 6.253906 h -6.015625 z" /><path
d="m 11.472656,12.726388 v 6.047224 A 1.2263883,1.2263883 45 0 0 12.699044,20 h 6.074568 A 1.2263883,1.2263883 135 0 0 20,18.773612 V 12.726388 A 1.2263883,1.2263883 45 0 0 18.773612,11.5 h -6.074568 a 1.2263883,1.2263883 135 0 0 -1.226388,1.226388 z m 1.730947,-0.0096 h 5.065451 a 0.47508735,0.47508735 45 0 1 0.475087,0.475087 v 5.303732 a 0.47508735,0.47508735 135 0 1 -0.475087,0.475087 h -5.065451 a 0.47508735,0.47508735 45 0 1 -0.475087,-0.475087 l 0,-5.303732 a 0.47508735,0.47508735 135 0 1 0.475087,-0.475087 z"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
id="path30-4"
inkscape:path-effect="#path-effect31-9"
inkscape:original-d="M 11.472656,11.5 V 20 H 20 v -8.5 z m 1.25586,1.216797 h 6.015625 v 6.253906 h -6.015625 z"
transform="translate(11.058594)" /><path
d="m 11.472656,12.726388 v 6.047224 A 1.2263883,1.2263883 45 0 0 12.699044,20 h 6.074568 A 1.2263883,1.2263883 135 0 0 20,18.773612 V 12.726388 A 1.2263883,1.2263883 45 0 0 18.773612,11.5 h -6.074568 a 1.2263883,1.2263883 135 0 0 -1.226388,1.226388 z m 1.730947,-0.0096 h 5.065451 a 0.47508735,0.47508735 45 0 1 0.475087,0.475087 v 5.303732 a 0.47508735,0.47508735 135 0 1 -0.475087,0.475087 h -5.065451 a 0.47508735,0.47508735 45 0 1 -0.475087,-0.475087 l 0,-5.303732 a 0.47508735,0.47508735 135 0 1 0.475087,-0.475087 z"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
id="path30-4-3"
inkscape:path-effect="#path-effect31-9-1"
inkscape:original-d="M 11.472656,11.5 V 20 H 20 v -8.5 z m 1.25586,1.216797 h 6.015625 v 6.253906 h -6.015625 z"
transform="translate(0,11.15625)" /></g></svg>

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="12.5 0.5 15.5 3.5 10 9 7 6" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><path d="M6.5 7C4.7 6.8 3.2 8 2.9 9.9c-.2 1.3-.8 2.2-2.4 3 2.8 1.5 6.6 1 7.5-1.6.5-1.5.3-3.1-1.5-4.3Z" style="fill:#009688"/></svg>

After

Width:  |  Height:  |  Size: 337 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="0.5" y="0.5" width="7" height="7" style="fill:#009688"/><rect x="7.5" y="7.5" width="7" height="7" style="fill:#009688"/><rect x="0.5" y="0.5" width="14" height="14" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="0.5" x2="7.5" y2="14.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="0.5" y1="7.5" x2="14.5" y2="7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 582 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M7.5 7.5 L14.5 7.5 L11 13.5 Z" style="fill:#009688"/><path d="M7.5 7.5 L11 13.5 L4 13.5 Z" style="fill:#009688"/><path d="M7.5 7.5 L4 13.5 L0.5 7.5 Z" style="fill:#009688"/><polygon points="14.5 7.5 11 13.5 4 13.5 0.5 7.5 4 1.5 11 1.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="7.5" x2="14.5" y2="7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="7.5" x2="11" y2="13.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="7.5" x2="4" y2="13.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="7.5" x2="0.5" y2="7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="7.5" x2="4" y2="1.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="7.5" x2="11" y2="1.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><line x1="2.5" y1="2.5" x2="12.5" y2="12.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="12.5" y1="2.5" x2="2.5" y2="12.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 332 B

@@ -0,0 +1,359 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="texture_displacement_cut.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs17"><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect34"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 | F,0,0,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect33"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect30"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.2615305,0,1 @ F,0,0,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect29"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect27"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect25"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect24"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect23"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect21"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect19"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect17"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect15"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><linearGradient
id="swatch7"
inkscape:swatch="solid"><stop
style="stop-color:#77eaa3;stop-opacity:1;"
offset="0"
id="stop7" /></linearGradient><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect3"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.49883385,0,1 @ F,0,0,1,0,0.48672135,0,1 @ F,0,0,1,0,0.5261776,0,1 @ F,0,0,1,0,0.50001454,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect2"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9-1"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /></defs><sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="15.375"
inkscape:cy="16.140625"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" /><path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" /><path
d="m 35.473026,33.999994 v -0.999987 a 0.500013,0.500013 0 0 0 -1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 1 -0.499993,0.499994 h -5.000013 a 0.5000126,0.5000126 0 0 0 0,1.000025 h 5.000013 a 1.5,1.5 0 0 0 1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7" /><path
d="m 5.9730079,35.500013 h 0.999987 a 0.500013,0.500013 0 0 0 0,-1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 1 -0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 0 -1.000025,0 v 5.000013 a 1.5,1.5 0 0 0 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3" /><path
d="m 4.4729879,33.999994 v -0.999987 a 0.500013,0.500013 0 0 1 1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 0 0.499993,0.499994 H 10.97302 a 0.5000126,0.5000126 0 0 1 0,1.000025 H 5.9730069 a 1.5,1.5 0 0 1 -1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5" /><path
d="m 5.9730079,4.499987 h 0.999987 a 0.50001302,0.50001302 0 0 1 0,1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 0 -0.499994,0.499993 v 5.000013 a 0.5000126,0.5000126 0 0 1 -1.0000251,0 V 6.000006 A 1.5,1.5 0 0 1 5.9730079,4.499987 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9" /><path
d="m 4.4729878,6.000006 v 0.999987 a 0.50001302,0.50001302 0 0 0 1.0000261,0 V 6.000006 A 0.49999998,0.49999998 0 0 1 5.9730068,5.500012 H 10.97302 a 0.5000126,0.5000126 0 0 0 0,-1.000025 H 5.9730068 a 1.5,1.5 0 0 0 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8" /><path
d="m 33.973006,4.499986 h -0.999987 a 0.50001302,0.50001302 0 0 0 0,1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 1 34.473,6.000005 v 5.000013 a 0.5000126,0.5000126 0 0 0 1.000025,0 V 6.000005 A 1.5,1.5 0 0 0 33.973006,4.499986 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9-8" /><path
d="m 35.473026,6.000005 v 0.999987 a 0.50001305,0.50001305 0 0 1 -1.000026,0 V 6.000005 A 0.49999998,0.49999998 0 0 0 33.973007,5.500011 h -5.000013 a 0.5000126,0.5000126 0 0 1 0,-1.000025 h 5.000013 a 1.5,1.5 0 0 1 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8-2" /><g
id="g5"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5" /></g><path
d="m 16.082031,8.7625 v 22.475 a 0.965625,0.965625 45 0 0 0.965625,0.965625 h 5.85 A 0.965625,0.965625 135 0 0 23.863281,31.2375 V 8.7625 A 0.965625,0.965625 45 0 0 22.897656,7.796875 h -5.85 A 0.965625,0.965625 135 0 0 16.082031,8.7625 Z m 1.325781,-0.032031 h 5.184376 a 0.3257813,0.3257813 45 0 1 0.325781,0.3257813 V 30.94375 a 0.3257813,0.3257813 135 0 1 -0.325781,0.325781 H 17.407812 A 0.3257813,0.3257813 45 0 1 17.082031,30.94375 V 9.0562501 a 0.3257813,0.3257813 135 0 1 0.325781,-0.3257813 z"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
id="path33"
inkscape:path-effect="#path-effect34"
inkscape:original-d="m 16.082031,7.796875 v 24.40625 h 7.78125 V 7.796875 Z m 1,0.9335938 h 5.835938 V 31.269531 h -5.835938 z" /><path
style="fill:#009688;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect32"
width="1.0000267"
height="22.719467"
x="27.527292"
y="-12.430544"
transform="rotate(47.337307)"
inkscape:path-effect="#path-effect33"
sodipodi:type="rect"
d="m 28.027306,-12.430544 c 0.277007,0 0.500013,0.223006 0.500013,0.500013 V 9.7889099 c 0,0.2770071 -0.223006,0.5000131 -0.500013,0.5000131 -0.277008,0 -0.500014,-0.223006 -0.500014,-0.5000131 V -11.930531 c 0,-0.277007 0.223006,-0.500013 0.500014,-0.500013 z"
ry="0.50001335" /></svg>

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="0.5" y="0.5" width="14" height="14" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="0.5" y1="7.5" x2="14.5" y2="7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="2.5" y1="0.5" x2="2.5" y2="14.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/><line x1="5" y1="0.5" x2="5" y2="14.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/><line x1="8.5" y1="0.5" x2="8.5" y2="14.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 688 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="5.5" cy="3.5" r="1.25" style="fill:#949494"/><circle cx="9.5" cy="3.5" r="1.25" style="fill:#949494"/><circle cx="5.5" cy="7.5" r="1.25" style="fill:#949494"/><circle cx="9.5" cy="7.5" r="1.25" style="fill:#949494"/><circle cx="5.5" cy="11.5" r="1.25" style="fill:#949494"/><circle cx="9.5" cy="11.5" r="1.25" style="fill:#949494"/></svg>

After

Width:  |  Height:  |  Size: 434 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="0.5 3 6 5.5 11.5 3 6 0.5 0.5 3" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polyline points="0.5 3 0.5 9.5 6 12 8 11.1" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polyline points="11.5 3 11.5 8" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="6" y1="5.5" x2="6" y2="12" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="10" y1="10" x2="15" y2="15" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/><line x1="15" y1="10" x2="10" y2="15" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 792 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="0.5 13.5 7.5 1.5 14.5 13.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polygon points="4 7.5 11 7.5 7.5 13.5" style="fill:#009688;stroke:#009688;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 311 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="0.5" y="10.5" width="14" height="4" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polygon points="9 0.5 4.5 5.5 7.5 5.5 6 9 10.5 4 7.5 4" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 346 B

@@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="texture_displacement_frame.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs17"><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect21"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect19"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect17"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect15"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><linearGradient
id="swatch7"
inkscape:swatch="solid"><stop
style="stop-color:#77eaa3;stop-opacity:1;"
offset="0"
id="stop7" /></linearGradient><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect3"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.49883385,0,1 @ F,0,0,1,0,0.48672135,0,1 @ F,0,0,1,0,0.5261776,0,1 @ F,0,0,1,0,0.50001454,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect2"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /></defs><sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="16"
inkscape:cx="11.6875"
inkscape:cy="6.28125"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" /><path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" /><path
d="m 35.473026,33.999994 v -0.999987 a 0.500013,0.500013 0 0 0 -1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 1 -0.499993,0.499994 h -5.000013 a 0.5000126,0.5000126 0 0 0 0,1.000025 h 5.000013 a 1.5,1.5 0 0 0 1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7" /><path
d="m 5.9730079,35.500013 h 0.999987 a 0.500013,0.500013 0 0 0 0,-1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 1 -0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 0 -1.000025,0 v 5.000013 a 1.5,1.5 0 0 0 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3" /><path
d="m 4.4729879,33.999994 v -0.999987 a 0.500013,0.500013 0 0 1 1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 0 0.499993,0.499994 H 10.97302 a 0.5000126,0.5000126 0 0 1 0,1.000025 H 5.9730069 a 1.5,1.5 0 0 1 -1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5" /><path
d="m 5.9730079,4.499987 h 0.999987 a 0.50001302,0.50001302 0 0 1 0,1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 0 -0.499994,0.499993 v 5.000013 a 0.5000126,0.5000126 0 0 1 -1.0000251,0 V 6.000006 A 1.5,1.5 0 0 1 5.9730079,4.499987 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9" /><path
d="m 4.4729878,6.000006 v 0.999987 a 0.50001302,0.50001302 0 0 0 1.0000261,0 V 6.000006 A 0.49999998,0.49999998 0 0 1 5.9730068,5.500012 H 10.97302 a 0.5000126,0.5000126 0 0 0 0,-1.000025 H 5.9730068 a 1.5,1.5 0 0 0 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8" /><path
d="m 33.973006,4.499986 h -0.999987 a 0.50001302,0.50001302 0 0 0 0,1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 1 34.473,6.000005 v 5.000013 a 0.5000126,0.5000126 0 0 0 1.000025,0 V 6.000005 A 1.5,1.5 0 0 0 33.973006,4.499986 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9-8" /><path
d="m 35.473026,6.000005 v 0.999987 a 0.50001305,0.50001305 0 0 1 -1.000026,0 V 6.000005 A 0.49999998,0.49999998 0 0 0 33.973007,5.500011 h -5.000013 a 0.5000126,0.5000126 0 0 1 0,-1.000025 h 5.000013 a 1.5,1.5 0 0 1 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8-2" /><g
id="g5"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5" /></g><g
id="g5-0"
transform="translate(6.4998844,6.0000382)"
style="fill:#ff2323;fill-opacity:1"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4-1"
style="fill:#ff2323;fill-opacity:1" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5-2"
style="fill:#4e2ca6;fill-opacity:1;fill-rule:nonzero" /></g><g
id="g5-0-8"
transform="matrix(-1,0,0,1,33.44613,6.0000382)"
style="fill:#ff2323;fill-opacity:1"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4-1-3"
style="fill:#ff2323;fill-opacity:1" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5-2-5"
style="fill:#ff2323;fill-opacity:1" /></g><g
id="g5-0-8-2"
transform="rotate(180,16.723064,16.999981)"
style="fill:#ff2323;fill-opacity:1"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4-1-3-0"
style="fill:#ff2323;fill-opacity:1" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5-2-5-1"
style="fill:#ff2323;fill-opacity:1" /></g><g
id="g5-0-8-2-4"
transform="matrix(1,0,0,-1,6.4998854,33.999963)"
style="fill:#ff2323;fill-opacity:1"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4-1-3-0-0"
style="fill:#ff2323;fill-opacity:1" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5-2-5-1-6"
style="fill:#ff2323;fill-opacity:1" /></g><path
id="path13"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
d="m 10.972656,11.5 v 4.101562 1.407813 A 0.490625,0.490625 45 0 0 11.463281,17.5 h 0.0094 a 0.4999428,0.4999428 135 0 0 0.499943,-0.499943 V 15.601562 12.000236 A 0.5002363,0.5002363 135 0 1 12.472892,11.5 h 0.241952 0.503906 4.255468 a 0.4984375,0.4984375 135 0 0 0.498438,-0.498437 v -0.0018 A 0.4997516,0.4997516 45 0 0 17.472904,10.5 H 13.21875 12.714844 11.972656 a 1,1 135 0 0 -1,1 z"
inkscape:original-d="m 10.972656,10.5 v 1 4.101562 V 17.5 h 1 V 15.601562 11.5 h 0.742188 0.503906 4.753906 v -1 H 13.21875 12.714844 11.972656 Z"
inkscape:path-effect="#path-effect15" /><path
id="path16"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
d="m 10.972656,11.5 v 4.101562 1.439063 A 0.459375,0.459375 45 0 0 11.432031,17.5 h 0.04066 a 0.499968,0.499968 135 0 0 0.499968,-0.499968 l 0,-1.39847 V 12.000236 A 0.5002363,0.5002363 135 0 1 12.472892,11.5 h 0.241952 0.503906 4.271094 a 0.4828125,0.4828125 135 0 0 0.482812,-0.482812 V 11.00584 A 0.50584,0.50584 45 0 0 17.466816,10.5 H 13.21875 12.714844 11.972656 a 1,1 135 0 0 -1,1 z"
inkscape:original-d="m 10.972656,10.5 v 1 4.101562 V 17.5 h 1 V 15.601562 11.5 h 0.742188 0.503906 4.753906 v -1 H 13.21875 12.714844 11.972656 Z"
inkscape:path-effect="#path-effect17"
transform="matrix(-1,0,0,1,39.939926,2.52e-5)" /><path
id="path17"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
d="m 10.972656,11.5 v 4.101562 1.439063 A 0.459375,0.459375 45 0 0 11.432031,17.5 h 0.04066 a 0.499968,0.499968 135 0 0 0.499968,-0.499968 l 0,-1.39847 V 12.000236 A 0.5002363,0.5002363 135 0 1 12.472892,11.5 h 0.241952 0.503906 4.271094 a 0.4828125,0.4828125 135 0 0 0.482812,-0.482812 V 11.00584 A 0.50584,0.50584 45 0 0 17.466816,10.5 H 13.21875 12.714844 11.972656 a 1,1 135 0 0 -1,1 z"
inkscape:original-d="m 10.972656,10.5 v 1 4.101562 V 17.5 h 1 V 15.601562 11.5 h 0.742188 0.503906 4.753906 v -1 H 13.21875 12.714844 11.972656 Z"
inkscape:path-effect="#path-effect19"
transform="rotate(180,19.972885,20.000096)" /><path
id="path19"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
d="m 10.972656,11.5 v 4.101562 1.439063 A 0.459375,0.459375 45 0 0 11.432031,17.5 h 0.04066 a 0.499968,0.499968 135 0 0 0.499968,-0.499968 l 0,-1.39847 V 12.000236 A 0.5002363,0.5002363 135 0 1 12.472892,11.5 h 0.241952 0.503906 4.271094 a 0.4828125,0.4828125 135 0 0 0.482812,-0.482812 V 11.00584 A 0.50584,0.50584 45 0 0 17.466816,10.5 H 13.21875 12.714844 11.972656 a 1,1 135 0 0 -1,1 z"
inkscape:original-d="m 10.972656,10.5 v 1 4.101562 V 17.5 h 1 V 15.601562 11.5 h 0.742188 0.503906 4.753906 v -1 H 13.21875 12.714844 11.972656 Z"
inkscape:path-effect="#path-effect21"
transform="matrix(1,0,0,-1,0.0060898,39.99995)" /></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,387 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="texture_displacement_join.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs17"><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect35"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,0,1,0,0.24375,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect34"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 | F,0,0,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect33"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect30"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.2615305,0,1 @ F,0,0,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect29"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect27"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect25"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect24"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect23"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect21"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect19"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect17"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect15"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><linearGradient
id="swatch7"
inkscape:swatch="solid"><stop
style="stop-color:#77eaa3;stop-opacity:1;"
offset="0"
id="stop7" /></linearGradient><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect3"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.49883385,0,1 @ F,0,0,1,0,0.48672135,0,1 @ F,0,0,1,0,0.5261776,0,1 @ F,0,0,1,0,0.50001454,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect2"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9-1"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect35-7"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,0,1,0,0.24375,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /></defs><sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="18.3125"
inkscape:cy="22.328125"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" /><path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" /><path
d="m 35.473026,33.999994 v -0.999987 a 0.500013,0.500013 0 0 0 -1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 1 -0.499993,0.499994 h -5.000013 a 0.5000126,0.5000126 0 0 0 0,1.000025 h 5.000013 a 1.5,1.5 0 0 0 1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7" /><path
d="m 5.9730079,35.500013 h 0.999987 a 0.500013,0.500013 0 0 0 0,-1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 1 -0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 0 -1.000025,0 v 5.000013 a 1.5,1.5 0 0 0 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3" /><path
d="m 4.4729879,33.999994 v -0.999987 a 0.500013,0.500013 0 0 1 1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 0 0.499993,0.499994 H 10.97302 a 0.5000126,0.5000126 0 0 1 0,1.000025 H 5.9730069 a 1.5,1.5 0 0 1 -1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5" /><path
d="m 5.9730079,4.499987 h 0.999987 a 0.50001302,0.50001302 0 0 1 0,1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 0 -0.499994,0.499993 v 5.000013 a 0.5000126,0.5000126 0 0 1 -1.0000251,0 V 6.000006 A 1.5,1.5 0 0 1 5.9730079,4.499987 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9" /><path
d="m 4.4729878,6.000006 v 0.999987 a 0.50001302,0.50001302 0 0 0 1.0000261,0 V 6.000006 A 0.49999998,0.49999998 0 0 1 5.9730068,5.500012 H 10.97302 a 0.5000126,0.5000126 0 0 0 0,-1.000025 H 5.9730068 a 1.5,1.5 0 0 0 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8" /><path
d="m 33.973006,4.499986 h -0.999987 a 0.50001302,0.50001302 0 0 0 0,1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 1 34.473,6.000005 v 5.000013 a 0.5000126,0.5000126 0 0 0 1.000025,0 V 6.000005 A 1.5,1.5 0 0 0 33.973006,4.499986 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9-8" /><path
d="m 35.473026,6.000005 v 0.999987 a 0.50001305,0.50001305 0 0 1 -1.000026,0 V 6.000005 A 0.49999998,0.49999998 0 0 0 33.973007,5.500011 h -5.000013 a 0.5000126,0.5000126 0 0 1 0,-1.000025 h 5.000013 a 1.5,1.5 0 0 1 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8-2" /><g
id="g5"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5" /></g><path
id="rect35"
style="fill:#009688;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.74375,1 h 7.563281 a 0.24375,0.24375 45 0 1 0.24375,0.24375 v 7.575 a 0.24375,0.24375 135 0 1 -0.24375,0.24375 h -7.563281 a 0.24375,0.24375 45 0 1 -0.24375,-0.24375 v -7.575 a 0.24375,0.24375 135 0 1 0.24375,-0.24375 z"
inkscape:path-effect="#path-effect35"
inkscape:original-d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.5,1 h 8.050781 v 8.0625 h -8.050781 z"
transform="translate(0.294922,2.953125)" /><path
id="rect35-3"
style="fill:#009688;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.74375,1 h 7.563281 a 0.24375,0.24375 45 0 1 0.24375,0.24375 v 7.575 a 0.24375,0.24375 135 0 1 -0.24375,0.24375 h -7.563281 a 0.24375,0.24375 45 0 1 -0.24375,-0.24375 v -7.575 a 0.24375,0.24375 135 0 1 0.24375,-0.24375 z"
inkscape:path-effect="#path-effect35-7"
inkscape:original-d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.5,1 h 8.050781 v 8.0625 h -8.050781 z"
transform="translate(9.345703,2.953125)" /></svg>

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="5.5" y="5.5" width="4" height="4" style="fill:#009688"/><rect x="5.5" y="1.5" width="4" height="4" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><rect x="1.5" y="5.5" width="4" height="4" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><rect x="5.5" y="5.5" width="4" height="4" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><rect x="9.5" y="5.5" width="4" height="4" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><rect x="5.5" y="9.5" width="4" height="4" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 755 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="2.5" cy="7.5" r="2" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="4.3" y1="6.5" x2="11.5" y2="1.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="4.3" y1="8.5" x2="11.5" y2="13.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><rect x="11.5" y="1.5" width="3" height="12" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 562 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><line x1="7.5" y1="1.5" x2="7.5" y2="12" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polyline points="3.5 8.5 7.5 12.5 11.5 8.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 330 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><line x1="7.5" y1="3" x2="7.5" y2="13.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polyline points="3.5 6.5 7.5 2.5 11.5 6.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 329 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polyline points="0.5 7.5 0.5 14.5 14.5 14.5 14.5 7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><path d="M0.5 7.5c1.2-3 2.3-3 3.5 0s2.3 3 3.5 0 2.3-3 3.5 0 2.3 3 3.5 0" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 372 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="0.5 3.5 7.5 6.5 7.5 14.5 0.5 11.5 0.5 3.5" style="fill:#009688;fill-opacity:0.55"/><polygon points="7.5 6.5 14.5 3.5 14.5 11.5 7.5 14.5 7.5 6.5" style="fill:#009688;fill-opacity:0.3"/><polygon points="0.5 3.5 7.5 6.5 14.5 3.5 7.5 0.5 0.5 3.5" style="fill:#009688"/><polygon points="0.5 3.5 7.5 6.5 14.5 3.5 7.5 0.5 0.5 3.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polyline points="0.5 3.5 0.5 11.5 7.5 14.5 14.5 11.5 14.5 3.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="7.5" y1="6.5" x2="7.5" y2="14.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 769 B

@@ -0,0 +1,260 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="texture_displacement_snap.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs17"><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect29"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect27"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect25"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect24"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect23"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect21"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect19"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect17"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect15"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><linearGradient
id="swatch7"
inkscape:swatch="solid"><stop
style="stop-color:#77eaa3;stop-opacity:1;"
offset="0"
id="stop7" /></linearGradient><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect3"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.49883385,0,1 @ F,0,0,1,0,0.48672135,0,1 @ F,0,0,1,0,0.5261776,0,1 @ F,0,0,1,0,0.50001454,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect2"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /></defs><sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="45.254834"
inkscape:cx="14.363106"
inkscape:cy="12.827359"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" /><path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" /><path
d="m 35.473026,33.999994 v -0.999987 a 0.500013,0.500013 0 0 0 -1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 1 -0.499993,0.499994 h -5.000013 a 0.5000126,0.5000126 0 0 0 0,1.000025 h 5.000013 a 1.5,1.5 0 0 0 1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7" /><path
d="m 5.9730079,35.500013 h 0.999987 a 0.500013,0.500013 0 0 0 0,-1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 1 -0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 0 -1.000025,0 v 5.000013 a 1.5,1.5 0 0 0 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3" /><path
d="m 4.4729879,33.999994 v -0.999987 a 0.500013,0.500013 0 0 1 1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 0 0.499993,0.499994 H 10.97302 a 0.5000126,0.5000126 0 0 1 0,1.000025 H 5.9730069 a 1.5,1.5 0 0 1 -1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5" /><path
d="m 5.9730079,4.499987 h 0.999987 a 0.50001302,0.50001302 0 0 1 0,1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 0 -0.499994,0.499993 v 5.000013 a 0.5000126,0.5000126 0 0 1 -1.0000251,0 V 6.000006 A 1.5,1.5 0 0 1 5.9730079,4.499987 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9" /><path
d="m 4.4729878,6.000006 v 0.999987 a 0.50001302,0.50001302 0 0 0 1.0000261,0 V 6.000006 A 0.49999998,0.49999998 0 0 1 5.9730068,5.500012 H 10.97302 a 0.5000126,0.5000126 0 0 0 0,-1.000025 H 5.9730068 a 1.5,1.5 0 0 0 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8" /><path
d="m 33.973006,4.499986 h -0.999987 a 0.50001302,0.50001302 0 0 0 0,1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 1 34.473,6.000005 v 5.000013 a 0.5000126,0.5000126 0 0 0 1.000025,0 V 6.000005 A 1.5,1.5 0 0 0 33.973006,4.499986 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9-8" /><path
d="m 35.473026,6.000005 v 0.999987 a 0.50001305,0.50001305 0 0 1 -1.000026,0 V 6.000005 A 0.49999998,0.49999998 0 0 0 33.973007,5.500011 h -5.000013 a 0.5000126,0.5000126 0 0 1 0,-1.000025 h 5.000013 a 1.5,1.5 0 0 1 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8-2" /><g
id="g5"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5" /></g><path
d="M 20.422985,9.2501548 V 29.968905 H 28.78236 A 1.015625,1.015625 135 0 0 29.797985,28.95328 V 9.2501548 A 1.015625,1.015625 45 0 0 28.78236,8.2345298 h -7.34375 a 1.015625,1.015625 135 0 0 -1.015625,1.015625 z m 1.015625,-0.015625 h 7.34375 V 28.968905 h -7.34375 z"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
id="path23"
inkscape:path-effect="#path-effect24"
inkscape:original-d="M 20.422985,8.2345298 V 29.968905 h 9.375 V 8.2345298 Z m 1.015625,1 h 7.34375 V 28.968905 h -7.34375 z" /><path
d="m 11.047985,11.324808 v 19.616307 a 1.059034,1.059034 45 0 0 1.059034,1.059034 h 7.256932 a 1.059034,1.059034 135 0 0 1.059034,-1.059034 V 10.265774 h -8.315966 a 1.059034,1.059034 135 0 0 -1.059034,1.059034 z m 1.015625,-0.05903 h 7.34375 v 19.734375 h -7.34375 z"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
id="path23-8"
inkscape:path-effect="#path-effect25"
inkscape:original-d="m 11.047985,10.265774 v 21.734375 h 9.375 V 10.265774 Z m 1.015625,1 h 7.34375 v 19.734375 h -7.34375 z" /><path
id="use25"
style="fill:#009688;stroke-width:0.1;paint-order:stroke fill markers"
d="M 21.439453 8.234375 A 1.015625 1.015625 0 0 0 20.423828 9.25 L 20.423828 10.265625 L 12.107422 10.265625 A 1.059034 1.059034 0 0 0 11.048828 11.324219 L 11.048828 30.941406 A 1.059034 1.059034 0 0 0 12.107422 32 L 19.363281 32 A 1.059034 1.059034 0 0 0 20.423828 30.941406 L 20.423828 29.96875 L 28.783203 29.96875 A 1.015625 1.015625 0 0 0 29.798828 28.953125 L 29.798828 9.25 A 1.015625 1.015625 0 0 0 28.783203 8.234375 L 21.439453 8.234375 z M 21.439453 9.234375 L 28.783203 9.234375 L 28.783203 28.96875 L 21.439453 28.96875 L 21.439453 9.234375 z M 12.064453 11.265625 L 19.408203 11.265625 L 19.408203 31 L 12.064453 31 L 12.064453 11.265625 z " /></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="0.5 14.5 1.5 14.5 5.5 7.5 1.5 0.5 0.5 0.5 0.5 14.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><rect x="7" width="1" height="3" style="fill:#009688"/><rect x="7" y="4" width="1" height="1" style="fill:#009688"/><rect x="7" y="6" width="1" height="3" style="fill:#009688"/><rect x="7" y="10" width="1" height="1" style="fill:#009688"/><rect x="7" y="12" width="1" height="3" style="fill:#009688"/><polygon points="9.5 14.5 10.5 14.5 14.5 7.5 10.5 0.5 9.5 0.5 9.5 14.5" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 686 B

@@ -0,0 +1,387 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="texture_displacement_unjoin.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs17"><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect35"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,0,1,0,0.24375,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect34"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 @ F,0,0,1,0,0.965625,0,1 | F,0,0,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1 @ F,0,1,1,0,0.3257813,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect33"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect30"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.2615305,0,1 @ F,0,0,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 @ F,0,1,1,0,1.2615305,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect29"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect27"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect25"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,1.059034,0,1 @ F,0,1,1,0,1.059034,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect24"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,1.015625,0,1 @ F,0,0,1,0,1.015625,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect23"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect21"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect19"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect17"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.459375,0,1 @ F,0,0,1,0,0.499968,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.4828125,0,1 @ F,0,0,1,0,0.50584,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect15"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.5002363,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><linearGradient
id="swatch7"
inkscape:swatch="solid"><stop
style="stop-color:#77eaa3;stop-opacity:1;"
offset="0"
id="stop7" /></linearGradient><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect3"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0.49883385,0,1 @ F,0,0,1,0,0.48672135,0,1 @ F,0,0,1,0,0.5261776,0,1 @ F,0,0,1,0,0.50001454,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect2"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect31-9-1"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 @ F,0,0,1,0,1.2263883,0,1 | F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1 @ F,0,1,1,0,0.47508735,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /><inkscape:path-effect
effect="fillet_chamfer"
id="path-effect35-7"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,1,1,0,0.24375,0,1 @ F,0,0,1,0,0.24375,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" /></defs><sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="18.3125"
inkscape:cy="22.328125"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" /><path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" /><path
d="m 35.473026,33.999994 v -0.999987 a 0.500013,0.500013 0 0 0 -1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 1 -0.499993,0.499994 h -5.000013 a 0.5000126,0.5000126 0 0 0 0,1.000025 h 5.000013 a 1.5,1.5 0 0 0 1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7" /><path
d="m 5.9730079,35.500013 h 0.999987 a 0.500013,0.500013 0 0 0 0,-1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 1 -0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 0 -1.000025,0 v 5.000013 a 1.5,1.5 0 0 0 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3" /><path
d="m 4.4729879,33.999994 v -0.999987 a 0.500013,0.500013 0 0 1 1.000026,0 v 0.999987 a 0.49999998,0.49999998 0 0 0 0.499993,0.499994 H 10.97302 a 0.5000126,0.5000126 0 0 1 0,1.000025 H 5.9730069 a 1.5,1.5 0 0 1 -1.500019,-1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5" /><path
d="m 5.9730079,4.499987 h 0.999987 a 0.50001302,0.50001302 0 0 1 0,1.000026 h -0.999987 a 0.49999998,0.49999998 0 0 0 -0.499994,0.499993 v 5.000013 a 0.5000126,0.5000126 0 0 1 -1.0000251,0 V 6.000006 A 1.5,1.5 0 0 1 5.9730079,4.499987 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9" /><path
d="m 4.4729878,6.000006 v 0.999987 a 0.50001302,0.50001302 0 0 0 1.0000261,0 V 6.000006 A 0.49999998,0.49999998 0 0 1 5.9730068,5.500012 H 10.97302 a 0.5000126,0.5000126 0 0 0 0,-1.000025 H 5.9730068 a 1.5,1.5 0 0 0 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8" /><path
d="m 33.973006,4.499986 h -0.999987 a 0.50001302,0.50001302 0 0 0 0,1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 1 34.473,6.000005 v 5.000013 a 0.5000126,0.5000126 0 0 0 1.000025,0 V 6.000005 A 1.5,1.5 0 0 0 33.973006,4.499986 Z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-3-9-8" /><path
d="m 35.473026,6.000005 v 0.999987 a 0.50001305,0.50001305 0 0 1 -1.000026,0 V 6.000005 A 0.49999998,0.49999998 0 0 0 33.973007,5.500011 h -5.000013 a 0.5000126,0.5000126 0 0 1 0,-1.000025 h 5.000013 a 1.5,1.5 0 0 1 1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6-7-5-8-2" /><g
id="g5"><use
x="0"
y="0"
xlink:href="#path3-6-3-9"
id="use4" /><use
x="0"
y="0"
xlink:href="#path3-6-7-5-8"
id="use5" /></g><path
id="rect35"
style="fill:#009688;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.74375,1 h 7.563281 a 0.24375,0.24375 45 0 1 0.24375,0.24375 v 7.575 a 0.24375,0.24375 135 0 1 -0.24375,0.24375 h -7.563281 a 0.24375,0.24375 45 0 1 -0.24375,-0.24375 v -7.575 a 0.24375,0.24375 135 0 1 0.24375,-0.24375 z"
inkscape:path-effect="#path-effect35"
inkscape:original-d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.5,1 h 8.050781 v 8.0625 h -8.050781 z"
transform="translate(-1.142612,2.9530855)" /><path
id="rect35-3"
style="fill:#009688;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.74375,1 h 7.563281 a 0.24375,0.24375 45 0 1 0.24375,0.24375 v 7.575 a 0.24375,0.24375 135 0 1 -0.24375,0.24375 h -7.563281 a 0.24375,0.24375 45 0 1 -0.24375,-0.24375 v -7.575 a 0.24375,0.24375 135 0 1 0.24375,-0.24375 z"
inkscape:path-effect="#path-effect35-7"
inkscape:original-d="m 11.154297,12.015625 c -0.277007,0 -0.5,0.222993 -0.5,0.5 v 9.050781 c 0,0.0019 -2.2e-5,0.0039 0,0.0059 -2.3e-5,0.002 0,0.0039 0,0.0059 3.45e-4,0.01513 0.0023,0.03016 0.0039,0.04492 0.02282,0.255546 0.234414,0.455078 0.496094,0.455078 h 9.050781 c 0.277007,0 0.5,-0.222993 0.5,-0.5 v -0.002 -9.048828 c 9e-5,-0.0039 0,-0.0078 0,-0.01172 0,-0.277007 -0.222993,-0.5 -0.5,-0.5 z m 0.5,1 h 8.050781 v 8.0625 h -8.050781 z"
transform="translate(10.783203,2.9530855)" /></svg>

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="1" y="5.5" width="4" height="4" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><rect x="6" y="5.5" width="4" height="4" fill="none" stroke="#009688" stroke-linecap="round" stroke-linejoin="round"/><rect x="11" y="5.5" width="4" height="4" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><path d="M2 12.5h12" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1 1.6"/></svg>

After

Width:  |  Height:  |  Size: 568 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="1.5" y="1.5" width="13" height="13" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><path d="M1.5 10c2-3 3.5-3 5 0s3 3 5 0c1-1.5 2-1.5 3-.5" fill="none" stroke="#009688" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 346 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M4 6.5h6a3.5 3.5 0 0 1 0 7H6" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><polyline points="6.5 4 4 6.5 6.5 9" fill="none" stroke="#009688" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 320 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="2.5" y="2.5" width="11" height="11" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><line x1="1" y1="15" x2="15" y2="1" fill="none" stroke="#009688" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 325 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M1.5 5V1.5H5M11 1.5h3.5V5M14.5 11v3.5H11M5 14.5H1.5V11" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><rect x="5.5" y="5.5" width="5" height="5" fill="none" stroke="#009688" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 352 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="1.5" y="4.5" width="6" height="7" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><rect x="7.5" y="4.5" width="7" height="7" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><line x1="7.5" y1="4.5" x2="7.5" y2="11.5" stroke="#009688" stroke-width="1.8"/></svg>

After

Width:  |  Height:  |  Size: 410 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polyline points="2.5 12.5 6 8 9.5 9.5 13 3.5" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><circle cx="2.5" cy="12.5" r="1.7" fill="#009688"/><circle cx="13" cy="3.5" r="1.7" fill="#009688"/></svg>

After

Width:  |  Height:  |  Size: 314 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="1.5 13.5 7.5 1.5 13.5 13.5" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><line x1="7.5" y1="1.5" x2="7.5" y2="13.5" stroke="#009688" stroke-width="1.6" stroke-linecap="round" stroke-dasharray="2 1.7"/></svg>

After

Width:  |  Height:  |  Size: 340 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="1.5 13.5 3.5 2.5 13.5 1.5 12.5 12.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="3.5" y1="2.5" x2="12.5" y2="12.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="3.5" y1="2.5" x2="13.5" y2="1.5" style="fill:none;stroke:#009688;stroke-width:2;stroke-linecap:round"/></svg>

After

Width:  |  Height:  |  Size: 455 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="0.5 1.5 6.5 0.5 7.5 6.5 1.5 7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polygon points="9.5 1.5 14.5 2.5 11.5 6.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polygon points="1.5 9.5 5.5 9 6 14.5 0.5 13.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><polygon points="8.5 8.5 14.5 7.5 13.5 14.5 7.5 13.5" style="fill:#009688;stroke:#009688;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 576 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points="1.5 13.5 3.5 2.5 13.5 1.5 12.5 12.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><line x1="3.5" y1="2.5" x2="12.5" y2="12.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><circle cx="1.5" cy="13.5" r="1" style="fill:#949494"/><circle cx="12.5" cy="12.5" r="1" style="fill:#949494"/><circle cx="3.5" cy="2.5" r="1" style="fill:#949494"/><circle cx="13.5" cy="1.5" r="1.8" style="fill:#009688"/></svg>

After

Width:  |  Height:  |  Size: 564 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M3 2v5.5a5 5 0 0 0 10 0V2" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><path d="M5.4 2v5.5a2.6 2.6 0 0 0 5.2 0V2" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 2h2.4M10.6 2H13" stroke="#009688" stroke-width="2" stroke-linecap="round"/></svg>

After

Width:  |  Height:  |  Size: 410 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="0.5" y="4.5" width="5.5" height="7" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><rect x="10" y="4.5" width="5.5" height="7" fill="none" stroke="#949494" stroke-linecap="round" stroke-linejoin="round"/><line x1="8" y1="3" x2="8" y2="13" stroke="#009688" stroke-dasharray="1.6 1.6"/></svg>

After

Width:  |  Height:  |  Size: 413 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><rect x="0.5" y="0.5" width="14" height="14" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/><path d="M0.5 7.5h14M7.5 0.5v14M0.5 0.5l14 14M14.5 0.5l-14 14" style="fill:none;stroke:#009688;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 352 B

+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="toolbar_big_brush.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs17" />
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="5.6568543"
inkscape:cx="-13.081475"
inkscape:cy="98.994949"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" />
<path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" />
<path
d="M 19.973012,35.500013 H 5.9730109 a 1.5,1.5 0 0 1 -1.5,-1.500019 V 6.000006 a 1.5,1.5 0 0 1 1.5,-1.500019 H 33.973006 a 1.5,1.5 0 0 1 1.500019,1.500019 v 12.999987 a 0.5000126,0.5000126 0 0 1 -1.000025,0 V 6.000006 A 0.49999998,0.49999998 0 0 0 33.973006,5.500012 H 5.9730109 a 0.49999998,0.49999998 0 0 0 -0.499997,0.499994 v 27.999988 a 0.49999998,0.49999998 0 0 0 0.499997,0.499993 H 19.973012 a 0.500013,0.500013 0 0 1 0,1.000026 z"
style="fill:#b6b6b6;stroke-width:0.999999;fill-opacity:1"
id="path4-6" />
<path
id="path30"
style="fill:#009688;fill-opacity:1;stroke-width:0;stroke-opacity:0;paint-order:stroke fill markers"
d="M 30.109375 6.9648438 A 1.8710937 1.8710937 0 0 0 28.705078 7.5996094 A 1.8710937 1.8710937 0 0 0 28.591797 7.7421875 L 18.103516 20.615234 A 6.1070809 6.1070809 0 0 0 17.226562 20.552734 A 6.1070809 6.1070809 0 0 0 11.513672 24.503906 A 6.1070809 6.1070809 0 0 0 11.121094 26.658203 A 6.1070809 6.1070809 0 0 0 11.121094 26.757812 A 4.4931102 4.4931102 0 0 1 11.15625 27.3125 A 4.4931102 4.4931102 0 0 1 7.7890625 31.662109 A 4.4931102 4.4931102 0 0 1 7.5839844 31.708984 A 0.55609465 0.55242634 0 0 0 7.2558594 32.212891 A 0.55609465 0.55242634 0 0 0 7.8105469 32.765625 A 0.55609465 0.55242634 0 0 0 7.8125 32.765625 L 7.9570312 32.765625 L 17.224609 32.765625 L 17.226562 32.765625 A 6.1070809 6.1070809 0 0 0 23.333984 26.658203 A 6.1070809 6.1070809 0 0 0 22.792969 24.144531 L 31.666016 9.875 A 1.8710937 1.8710937 0 0 1 31.638672 9.9101562 A 1.8710937 1.8710937 0 0 0 31.699219 9.8242188 A 1.8710937 1.8710937 0 0 0 31.980469 8.8359375 A 1.8710937 1.8710937 0 0 0 31.724609 7.890625 A 1.8710937 1.8710937 0 0 0 30.480469 7.0019531 A 1.8710937 1.8710937 0 0 0 30.109375 6.9648438 z M 28.525391 7.8476562 A 1.8710937 1.8710937 0 0 0 28.472656 7.9335938 A 1.8710937 1.8710937 0 0 1 28.478516 7.9199219 A 1.8710937 1.8710937 0 0 1 28.525391 7.8476562 z M 30.109375 7.9570312 A 0.87817276 0.87817276 0 0 1 30.988281 8.8359375 A 0.87817276 0.87817276 0 0 1 30.90625 9.2050781 A 0.87817276 0.87817276 0 0 1 30.791016 9.390625 L 29.974609 10.703125 L 22.230469 23.15625 A 6.1070809 6.1070809 0 0 0 19.183594 20.873047 L 28.388672 9.5703125 L 29.359375 8.3808594 A 0.87817276 0.87817276 0 0 1 29.511719 8.1933594 A 0.87817276 0.87817276 0 0 1 30.109375 7.9570312 z M 28.457031 7.9628906 A 1.8710937 1.8710937 0 0 0 28.373047 8.1425781 A 1.8710937 1.8710937 0 0 1 28.457031 7.9628906 z M 28.300781 8.359375 A 1.8710937 1.8710937 0 0 0 28.263672 8.5507812 A 1.8710937 1.8710937 0 0 1 28.298828 8.3613281 A 1.8710937 1.8710937 0 0 1 28.300781 8.359375 z M 17.226562 21.65625 A 5.0022264 5.0022264 0 0 1 22.230469 26.658203 A 5.0022264 5.0022264 0 0 1 17.226562 31.662109 L 13.724609 31.662109 L 10.199219 31.662109 A 5.6057596 5.6057596 0 0 0 11.822266 29.501953 A 5.6057596 5.6057596 0 0 0 12.267578 27.3125 A 5.0022264 5.0022264 0 0 1 12.224609 26.658203 A 5.0022264 5.0022264 0 0 1 12.224609 26.621094 A 5.0022264 5.0022264 0 0 1 17.226562 21.65625 z " />
<rect
style="fill:#b6b6b6;fill-opacity:1;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;paint-order:stroke fill markers"
id="rect40"
width="15.363631"
height="1.000026"
x="18.609375"
y="34.499989" />
<rect
style="fill:#b6b6b6;fill-opacity:1;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;paint-order:stroke fill markers"
id="rect41"
width="1.000025"
height="11.921875"
x="34.473"
y="18.546875" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

+97
View File
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="toolbar_face.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs17">
<inkscape:path-effect
effect="fillet_chamfer"
id="path-effect48"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,1.0055868,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1.4911902,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,1.0376412,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" />
<inkscape:path-effect
effect="fillet_chamfer"
id="path-effect47"
is_visible="true"
lpeversion="1"
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
radius="0"
unit="px"
method="auto"
mode="F"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" />
</defs>
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="22.627417"
inkscape:cx="23.113553"
inkscape:cy="18.318485"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" />
<path
d="m 33.973006,35.500013 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 A 0.49999998,0.49999998 0 0 0 34.473,33.999994 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" />
<path
d="M 19.973012,35.500013 H 5.9730109 a 1.5,1.5 0 0 1 -1.5,-1.500019 V 6.000006 a 1.5,1.5 0 0 1 1.5,-1.500019 H 33.973006 a 1.5,1.5 0 0 1 1.500019,1.500019 v 12.999987 a 0.5000126,0.5000126 0 0 1 -1.000025,0 V 6.000006 A 0.49999998,0.49999998 0 0 0 33.973006,5.500012 H 5.9730109 a 0.49999998,0.49999998 0 0 0 -0.499997,0.499994 v 27.999988 a 0.49999998,0.49999998 0 0 0 0.499997,0.499993 H 19.973012 a 0.500013,0.500013 0 0 1 0,1.000026 z"
style="fill:#b6b6b6;stroke-width:0.999999;fill-opacity:1"
id="path4-6" />
<rect
style="fill:#b6b6b6;fill-opacity:1;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;paint-order:stroke fill markers"
id="rect40"
width="15.363631"
height="1.000026"
x="18.609375"
y="34.499989" />
<rect
style="fill:#b6b6b6;fill-opacity:1;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;paint-order:stroke fill markers"
id="rect41"
width="1.000025"
height="11.921875"
x="34.473"
y="18.546875" />
<path
id="path42"
style="fill:#009688;stroke-width:0;stroke-opacity:0;paint-order:stroke fill markers;fill-opacity:1"
d="M 19.58431,7.9401469 19.519531,8.0820312 9.1699219,30.736328 a 0.61329334,0.61329334 42.827026 0 0 0.828125,0.767578 l 0,0 20.7832031,-7.320312 0.0019,-6.61e-4 a 0.7874119,0.7874119 107.77086 0 0 0.382891,-1.194652 L 20.714844,8.0449219 20.578195,7.8494958 A 0.57476577,0.57476577 174.78854 0 0 19.58431,7.9401469 Z M 20.232422,9.1015625 30.1875,23.332031 10.576172,30.240234 Z"
inkscape:path-effect="#path-effect48"
inkscape:original-d="M 20.001953,7.0253906 19.519531,8.0820312 9.1699219,30.736328 8.5917969,32 9.9980469,31.503906 30.78125,24.183594 31.761719,23.837891 31.166016,22.988281 20.714844,8.0449219 Z M 20.232422,9.1015625 30.1875,23.332031 10.576172,30.240234 Z" />
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

@@ -0,0 +1,240 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="40"
height="40"
viewBox="0 0 40 40"
version="1.1"
id="svg17"
sodipodi:docname="toolbar_texture_displacement.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs17" />
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="27.578125"
inkscape:cy="27.671875"
inkscape:window-width="3840"
inkscape:window-height="2126"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg17" />
<g
id="g17"
transform="translate(0.69176086,0.249987)">
<path
d="m 27.659236,35.176022 h -4.399987 c -0.508996,0 -0.844996,0 -0.954999,-0.394015 a 0.59299998,0.59299998 0 0 1 0.36,-0.669997 2.3,2.3 0 0 0 1.2,-2.188989 3.253,3.253 0 1 1 3.800012,3.205984 z M 24.12125,34.175997 h 2.988 a 2.253,2.253 0 1 0 -2.252999,-2.252976 3.445,3.445 0 0 1 -0.735001,2.252976 z"
style="fill:#009688;stroke-width:0.999999"
id="path1-6" />
<path
d="m 30.281245,30.538996 -0.846009,-0.534993 4.364031,-6.899981 A 0.222,0.222 0 0 0 33.439456,22.84588 l -5.4,6.644032 -0.776013,-0.63103 5.400001,-6.643994 a 1.222,1.222 0 0 1 1.981984,1.422992 z"
style="fill:#009688;stroke-width:0.999999"
id="path2-0" />
<path
d="m 33.281245,35.250026 h -0.999987 a 0.500013,0.500013 0 0 1 0,-1.000026 h 0.999987 a 0.49999998,0.49999998 0 0 0 0.499994,-0.499993 v -5.000013 a 0.5000126,0.5000126 0 0 1 1.000025,0 v 5.000013 a 1.5,1.5 0 0 1 -1.500019,1.500019 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path3-6" />
<path
d="M 19.281251,35.250026 H 5.28125 a 1.5,1.5 0 0 1 -1.5,-1.500019 V 5.750019 A 1.5,1.5 0 0 1 5.28125,4.25 h 27.999995 a 1.5,1.5 0 0 1 1.500019,1.500019 v 12.999987 a 0.5000126,0.5000126 0 0 1 -1.000025,0 V 5.750019 A 0.49999998,0.49999998 0 0 0 33.281245,5.250025 H 5.28125 A 0.49999998,0.49999998 0 0 0 4.781253,5.750019 V 33.750007 A 0.49999998,0.49999998 0 0 0 5.28125,34.25 h 14.000001 a 0.500013,0.500013 0 0 1 0,1.000026 z"
style="fill:#b6b6b6;stroke-width:0.999999"
id="path4-6" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-1"
width="39.379108"
height="0.99609375"
x="-19.909107"
y="27.094706"
ry="0.49804688"
transform="rotate(-45)" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2"
width="27.566595"
height="0.99609375"
x="7.9031763"
y="-0.27849278"
ry="0.49487707"
transform="rotate(45)" />
<g
id="g7"
transform="matrix(3.7795276,0,0,3.7795276,-350.69182,-427.25001)">
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2"
width="2.8453603"
height="0.2635498"
x="150.08304"
y="13.289762"
ry="0.1317749"
transform="rotate(45)"
rx="0.1317749" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-2"
width="1.7498204"
height="0.2635498"
x="12.763216"
y="-149.44461"
ry="0.1317749"
transform="rotate(135)"
rx="0.1317749" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-2-2"
width="0.82876241"
height="0.27337581"
x="13.654455"
y="-148.49495"
ry="0.1317749"
transform="rotate(135)"
rx="0.1317749" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-6"
width="2.5927844"
height="0.25224927"
x="150.38367"
y="12.286384"
ry="0.12612464"
transform="rotate(45)"
rx="0.12612464" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-6-1"
width="1.9647908"
height="0.2635498"
x="151.01166"
y="11.21043"
ry="0.1317749"
transform="rotate(45)"
rx="0.1317749" />
</g>
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2-2-8"
width="10.754118"
height="0.99609375"
x="-10.211728"
y="-31.661213"
ry="0.49804688"
transform="rotate(135)"
rx="0.49804688" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2-2-2-9"
width="6.6134944"
height="0.99609375"
x="-33.794979"
y="12.679931"
ry="0.49804688"
transform="rotate(-135)"
rx="0.49804688" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2-2-2-2-3"
width="3.1323304"
height="1.0332314"
x="-30.282875"
y="16.213961"
ry="0.49804688"
transform="rotate(-135)"
rx="0.49804688" />
<g
id="g7-1"
transform="matrix(0,-3.7795276,3.7795276,0,-427.55829,389.70233)">
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-9"
width="2.8453603"
height="0.2635498"
x="150.08304"
y="13.289762"
ry="0.1317749"
transform="rotate(45)"
rx="0.1317749" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-2-8"
width="1.7498204"
height="0.2635498"
x="12.763216"
y="-149.44461"
ry="0.1317749"
transform="rotate(135)"
rx="0.1317749" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-2-2-6"
width="0.82876241"
height="0.27337581"
x="13.654455"
y="-148.49495"
ry="0.1317749"
transform="rotate(135)"
rx="0.1317749" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-6-5"
width="2.5927844"
height="0.25224927"
x="150.38367"
y="12.286384"
ry="0.12612464"
transform="rotate(45)"
rx="0.12612464" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:0.264999;stroke-dasharray:none"
id="rect6-2-2-6-1-0"
width="1.9647908"
height="0.2635498"
x="151.01166"
y="11.21043"
ry="0.1317749"
transform="rotate(45)"
rx="0.1317749" />
</g>
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2-2-9-4"
width="9.0822706"
height="0.99609375"
x="-36.379971"
y="-4.5927153"
ry="0.49804688"
transform="rotate(-135)"
rx="0.49804688" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2-2-6-5-5"
width="9.7995005"
height="0.95338309"
x="-36.915619"
y="-8.385005"
ry="0.47669154"
transform="rotate(-135)"
rx="0.47669154" />
<rect
style="fill:#009688;fill-opacity:1;stroke-width:1.00157;stroke-dasharray:none"
id="rect6-2-2-6-1-0-0"
width="7.425981"
height="0.99609375"
x="-34.54211"
y="-12.451604"
ry="0.49804688"
transform="rotate(-135)"
rx="0.49804688" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

+1 -53
View File
@@ -1,6 +1,6 @@
{
"name": "Eryone",
"version": "02.04.00.06",
"version": "02.04.00.05",
"force_update": "0",
"description": "Eryone configurations",
"machine_model_list": [
@@ -432,18 +432,10 @@
"name": "Eryone ABS",
"sub_path": "filament/Eryone ABS.json"
},
{
"name": "Eryone ABS+-HS @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone ABS+-HS @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone ABS-CF",
"sub_path": "filament/Eryone ABS-CF.json"
},
{
"name": "Eryone ABS-GF @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone ABS-GF @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone ASA",
"sub_path": "filament/Eryone ASA.json"
@@ -452,10 +444,6 @@
"name": "Eryone ASA-CF",
"sub_path": "filament/Eryone ASA-CF.json"
},
{
"name": "Eryone ASA-HS @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone ASA-HS @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PA",
"sub_path": "filament/Eryone PA.json"
@@ -472,50 +460,18 @@
"name": "Eryone PETG",
"sub_path": "filament/Eryone PETG.json"
},
{
"name": "Eryone PETG HS @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PETG HS @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PETG-CF",
"sub_path": "filament/Eryone PETG-CF.json"
},
{
"name": "Eryone PETG-GF @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PETG-GF @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PETG-Lite @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PETG-Lite @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PETG-Matte @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PETG-Matte @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PETG-Translucent @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PETG-Translucent @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PLA",
"sub_path": "filament/Eryone PLA.json"
},
{
"name": "Eryone PLA+HS @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PLA+HS @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PLA-CF",
"sub_path": "filament/Eryone PLA-CF.json"
},
{
"name": "Eryone PLA-Matte @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PLA-Matte @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PLA-Matte HS @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone PLA-Matte HS @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone PP",
"sub_path": "filament/Eryone PP.json"
@@ -532,14 +488,6 @@
"name": "Eryone TPU",
"sub_path": "filament/Eryone TPU.json"
},
{
"name": "Eryone petg-Galaxy @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone petg-Galaxy @Thinker X400 0.4 nozzle.json"
},
{
"name": "Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle",
"sub_path": "filament/Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle.json"
},
{
"name": "fdm_filament_pla",
"sub_path": "filament/fdm_filament_pla.json"
@@ -1,54 +0,0 @@
{
"type": "filament",
"name": "Eryone ABS+-HS @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "aUH1I90BFXa0C84r",
"filament_id": "OFRgjTRp",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone ABS+-HS @Thinker X400 0.4 nozzle"
],
"fan_max_speed": [
"20"
],
"fan_min_speed": [
"0"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.96"
],
"filament_max_volumetric_speed": [
"25"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"ABS"
],
"hot_plate_temp": [
"90"
],
"hot_plate_temp_initial_layer": [
"90"
],
"nozzle_temperature": [
"255"
],
"nozzle_temperature_initial_layer": [
"255"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,54 +0,0 @@
{
"type": "filament",
"name": "Eryone ABS-GF @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "WnsZC7HYi5Z1MOcn",
"filament_id": "OFenMm2Y",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone ABS-GF @Thinker X400 0.4 nozzle"
],
"fan_max_speed": [
"20"
],
"fan_min_speed": [
"0"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.96"
],
"filament_max_volumetric_speed": [
"18"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"ABS"
],
"hot_plate_temp": [
"90"
],
"hot_plate_temp_initial_layer": [
"90"
],
"nozzle_temperature": [
"265"
],
"nozzle_temperature_initial_layer": [
"265"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,54 +0,0 @@
{
"type": "filament",
"name": "Eryone ASA-HS @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "xw8zqUsFb2WVaSo1",
"filament_id": "OFIzY5sP",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone ASA-HS @Thinker X400 0.4 nozzle"
],
"fan_max_speed": [
"20"
],
"fan_min_speed": [
"0"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"1"
],
"filament_max_volumetric_speed": [
"20"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"ASA"
],
"hot_plate_temp": [
"90"
],
"hot_plate_temp_initial_layer": [
"90"
],
"nozzle_temperature": [
"260"
],
"nozzle_temperature_initial_layer": [
"260"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,60 +0,0 @@
{
"type": "filament",
"name": "Eryone PETG HS @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "GtPiiNgHAnxrR9Tj",
"filament_id": "OFtqfvcE",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PETG HS @Thinker X400 0.4 nozzle"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_max_speed": [
"50"
],
"fan_min_speed": [
"30"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.97"
],
"filament_max_volumetric_speed": [
"15"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"PETG"
],
"full_fan_speed_layer": [
"2"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"nozzle_temperature": [
"240"
],
"nozzle_temperature_initial_layer": [
"240"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -40,7 +40,7 @@
"14"
],
"filament_settings_id": [
"Eryone PETG-CF"
"Eryone PETG"
],
"filament_type": [
"PETG-CF"
@@ -1,60 +0,0 @@
{
"type": "filament",
"name": "Eryone PETG-GF @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "S1FBfw93PzYJMhCa",
"filament_id": "OFbzOkXX",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PETG-GF @Thinker X400 0.4 nozzle"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_max_speed": [
"50"
],
"fan_min_speed": [
"30"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.96"
],
"filament_max_volumetric_speed": [
"13"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"PETG"
],
"full_fan_speed_layer": [
"2"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"nozzle_temperature": [
"250"
],
"nozzle_temperature_initial_layer": [
"250"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,60 +0,0 @@
{
"type": "filament",
"name": "Eryone PETG-Lite @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "CWHhUswq3j9XHAuC",
"filament_id": "OFyWb8AA",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PETG-Lite @Thinker X400 0.4 nozzle"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_max_speed": [
"50"
],
"fan_min_speed": [
"30"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.9796"
],
"filament_max_volumetric_speed": [
"13"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"PETG"
],
"full_fan_speed_layer": [
"2"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"nozzle_temperature": [
"245"
],
"nozzle_temperature_initial_layer": [
"245"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,60 +0,0 @@
{
"type": "filament",
"name": "Eryone PETG-Matte @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "pzceBG5k2u3X9TLO",
"filament_id": "OFSvr7Aj",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PETG-Matte @Thinker X400 0.4 nozzle"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_max_speed": [
"50"
],
"fan_min_speed": [
"30"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"1"
],
"filament_max_volumetric_speed": [
"22"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"PETG"
],
"full_fan_speed_layer": [
"2"
],
"hot_plate_temp": [
"80"
],
"hot_plate_temp_initial_layer": [
"80"
],
"nozzle_temperature": [
"250"
],
"nozzle_temperature_initial_layer": [
"250"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,60 +0,0 @@
{
"type": "filament",
"name": "Eryone PETG-Translucent @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "jN64L5SUnQB5dG1x",
"filament_id": "OFY2E8cd",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PETG-Translucent @Thinker X400 0.4 nozzle"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_max_speed": [
"50"
],
"fan_min_speed": [
"30"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.99"
],
"filament_max_volumetric_speed": [
"24"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"PETG"
],
"full_fan_speed_layer": [
"2"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"nozzle_temperature": [
"215"
],
"nozzle_temperature_initial_layer": [
"215"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,48 +0,0 @@
{
"type": "filament",
"name": "Eryone PLA+HS @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "AfUEns6VhCXsj9Ft",
"filament_id": "OFeRoHy3",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PLA+HS @Thinker X400 0.4 nozzle"
],
"fan_min_speed": [
"80"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.99"
],
"filament_max_volumetric_speed": [
"18"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"hot_plate_temp": [
"55"
],
"hot_plate_temp_initial_layer": [
"55"
],
"nozzle_temperature": [
"210"
],
"nozzle_temperature_initial_layer": [
"210"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,48 +0,0 @@
{
"type": "filament",
"name": "Eryone PLA-Matte @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "Ho1nQYsweqTTte0g",
"filament_id": "OFFMWFWL",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PLA-Matte @Thinker X400 0.4 nozzle"
],
"fan_min_speed": [
"80"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.99"
],
"filament_max_volumetric_speed": [
"21"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"hot_plate_temp": [
"55"
],
"hot_plate_temp_initial_layer": [
"55"
],
"nozzle_temperature": [
"215"
],
"nozzle_temperature_initial_layer": [
"215"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,48 +0,0 @@
{
"type": "filament",
"name": "Eryone PLA-Matte HS @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "8W0yhuRu7OBJkSOS",
"filament_id": "OF9mNFSM",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone PLA-Matte HS @Thinker X400 0.4 nozzle"
],
"fan_min_speed": [
"80"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"1.1"
],
"filament_max_volumetric_speed": [
"28"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"hot_plate_temp": [
"55"
],
"hot_plate_temp_initial_layer": [
"55"
],
"nozzle_temperature": [
"225"
],
"nozzle_temperature_initial_layer": [
"225"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,60 +0,0 @@
{
"type": "filament",
"name": "Eryone petg-Galaxy @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "R4BPYs8aAc9DFf0n",
"filament_id": "OFWDDu8u",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone petg-Galaxy @Thinker X400 0.4 nozzle"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_max_speed": [
"50"
],
"fan_min_speed": [
"30"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.96"
],
"filament_max_volumetric_speed": [
"21"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"filament_type": [
"PETG"
],
"full_fan_speed_layer": [
"2"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"nozzle_temperature": [
"245"
],
"nozzle_temperature_initial_layer": [
"245"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
@@ -1,48 +0,0 @@
{
"type": "filament",
"name": "Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle",
"inherits": "Eryone Standard PLA",
"from": "system",
"setting_id": "jCbto64oaAKrDaN0",
"filament_id": "OF99Cc22",
"instantiation": "true",
"compatible_printers": [
"Thinker X400 0.4 nozzle"
],
"filament_settings_id": [
"Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle"
],
"fan_min_speed": [
"80"
],
"filament_end_gcode": [
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
],
"filament_flow_ratio": [
"0.97"
],
"filament_max_volumetric_speed": [
"15"
],
"filament_start_gcode": [
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
],
"hot_plate_temp": [
"55"
],
"hot_plate_temp_initial_layer": [
"55"
],
"nozzle_temperature": [
"230"
],
"nozzle_temperature_initial_layer": [
"230"
],
"slow_down_layer_time": [
"4"
],
"slow_down_min_speed": [
"15"
]
}
+7 -11
View File
@@ -1,7 +1,7 @@
{
"name": "WonderMaker",
"url": "",
"version": "02.04.00.04",
"version": "02.04.00.03",
"force_update": "0",
"description": "WonderMaker configurations",
"machine_model_list": [
@@ -432,8 +432,12 @@
"sub_path": "machine/WonderMaker ZR 0.4 nozzle.json"
},
{
"name": "fdm_ultra_common",
"sub_path": "machine/fdm_ultra_common.json"
"name": "WonderMaker ZR Ultra 0.4 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra 0.4 nozzle.json"
},
{
"name": "WonderMaker ZR Ultra S 0.4 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra S 0.4 nozzle.json"
},
{
"name": "WonderMaker ZR 0.2 nozzle",
@@ -451,10 +455,6 @@
"name": "WonderMaker ZR Ultra 0.2 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra 0.2 nozzle.json"
},
{
"name": "WonderMaker ZR Ultra 0.4 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra 0.4 nozzle.json"
},
{
"name": "WonderMaker ZR Ultra 0.6 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra 0.6 nozzle.json"
@@ -467,10 +467,6 @@
"name": "WonderMaker ZR Ultra S 0.2 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra S 0.2 nozzle.json"
},
{
"name": "WonderMaker ZR Ultra S 0.4 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra S 0.4 nozzle.json"
},
{
"name": "WonderMaker ZR Ultra S 0.6 nozzle",
"sub_path": "machine/WonderMaker ZR Ultra S 0.6 nozzle.json"
+7 -8
View File
@@ -1,23 +1,22 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra 0.2 nozzle",
"inherits": "fdm_ultra_common",
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
"from": "system",
"setting_id": "AX42zNj8YsJ94ilv",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra",
"printer_variant": "0.2",
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
"default_bed_type": "4",
"max_layer_height": [
"0.14"
],
"nozzle_diameter": [
"0.2",
"0.2",
"0.2",
"0.2"
],
"printer_model": "WonderMaker ZR Ultra",
"printer_variant": "0.2",
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
"max_layer_height": [
"0.14"
],
"min_layer_height": [
"0.04"
],
+49 -1
View File
@@ -1,17 +1,65 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra 0.4 nozzle",
"inherits": "fdm_ultra_common",
"inherits": "fdm_klipper_common",
"from": "system",
"setting_id": "xJBdCljSZVDINXnP",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra",
"default_print_profile": "0.20mm Standard @WonderMaker ZR Ultra",
"default_bed_type": "4",
"default_filament_profile": [
"WonderMaker PLA Basic"
],
"single_extruder_multi_material": "0",
"nozzle_diameter": [
"0.4",
"0.4",
"0.4",
"0.4"
],
"printable_area": [
"0x0",
"300x0",
"300x270",
"0x270"
],
"bed_exclude_area": [],
"printable_height": "290",
"extruder_clearance_radius": "134",
"bed_mesh_min": [
"10",
"10"
],
"bed_mesh_max": [
"290",
"260"
],
"bed_mesh_probe_distance": [
"50",
"50"
],
"support_air_filtration": "0",
"support_chamber_temp_control": "0",
"machine_tool_change_time": "10",
"machine_load_filament_time": "0",
"machine_unload_filament_time": "0",
"retract_lift_below": [
"279",
"279",
"279",
"279"
],
"enable_long_retraction_when_cut": [
"0",
"0",
"0",
"0"
],
"long_retractions_when_cut": [
"0",
"0",
"0",
"0"
]
}
+7 -8
View File
@@ -1,23 +1,22 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra 0.6 nozzle",
"inherits": "fdm_ultra_common",
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
"from": "system",
"setting_id": "6OWxZLFn3RD54QfX",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra",
"printer_variant": "0.6",
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
"default_bed_type": "4",
"max_layer_height": [
"0.42"
],
"nozzle_diameter": [
"0.6",
"0.6",
"0.6",
"0.6"
],
"printer_model": "WonderMaker ZR Ultra",
"printer_variant": "0.6",
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
"max_layer_height": [
"0.42"
],
"min_layer_height": [
"0.12"
],
+7 -8
View File
@@ -1,23 +1,22 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra 0.8 nozzle",
"inherits": "fdm_ultra_common",
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
"from": "system",
"setting_id": "SY9snlsMkurhEYWP",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra",
"printer_variant": "0.8",
"default_print_profile": "0.40mm Standard @WonderMaker ZR Ultra 0.8 nozzle",
"default_bed_type": "4",
"max_layer_height": [
"0.56"
],
"nozzle_diameter": [
"0.8",
"0.8",
"0.8",
"0.8"
],
"printer_model": "WonderMaker ZR Ultra",
"printer_variant": "0.8",
"default_print_profile": "0.40mm Standard @WonderMaker ZR Ultra 0.8 nozzle",
"max_layer_height": [
"0.56"
],
"min_layer_height": [
"0.16"
],
+15 -5
View File
@@ -1,19 +1,29 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra S 0.2 nozzle",
"inherits": "WonderMaker ZR Ultra 0.2 nozzle",
"inherits": "WonderMaker ZR Ultra S 0.4 nozzle",
"from": "system",
"setting_id": "ZNAx3f7tX3DatiK1",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra S",
"nozzle_diameter": [
"0.2",
"0.2",
"0.2",
"0.2"
],
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
"printer_model": "WonderMaker ZR Ultra S",
"printer_variant": "0.2",
"support_air_filtration": "1",
"support_chamber_temp_control": "1"
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
"max_layer_height": [
"0.14"
],
"min_layer_height": [
"0.04"
],
"retraction_length": [
"0.4",
"0.4",
"0.4",
"0.4"
]
}
+50 -3
View File
@@ -1,18 +1,65 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra S 0.4 nozzle",
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
"inherits": "fdm_klipper_common",
"from": "system",
"setting_id": "8xoZ6vYv9ws0J97u",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra S",
"default_print_profile": "0.20mm Standard @WonderMaker ZR Ultra",
"default_bed_type": "4",
"default_filament_profile": [
"WonderMaker PLA Basic"
],
"single_extruder_multi_material": "0",
"nozzle_diameter": [
"0.4",
"0.4",
"0.4",
"0.4"
],
"default_print_profile": "0.20mm Standard @WonderMaker ZR Ultra",
"printable_area": [
"0x0",
"300x0",
"300x270",
"0x270"
],
"bed_exclude_area": [],
"printable_height": "290",
"extruder_clearance_radius": "134",
"bed_mesh_min": [
"10",
"10"
],
"bed_mesh_max": [
"290",
"260"
],
"bed_mesh_probe_distance": [
"50",
"50"
],
"support_air_filtration": "1",
"support_chamber_temp_control": "1"
"support_chamber_temp_control": "1",
"machine_tool_change_time": "10",
"machine_load_filament_time": "0",
"machine_unload_filament_time": "0",
"retract_lift_below": [
"279",
"279",
"279",
"279"
],
"enable_long_retraction_when_cut": [
"0",
"0",
"0",
"0"
],
"long_retractions_when_cut": [
"0",
"0",
"0",
"0"
]
}
+22 -9
View File
@@ -1,19 +1,32 @@
{
"type": "machine",
"name": "WonderMaker ZR Ultra S 0.6 nozzle",
"inherits": "WonderMaker ZR Ultra 0.6 nozzle",
"inherits": "WonderMaker ZR Ultra S 0.4 nozzle",
"from": "system",
"setting_id": "xuJnOPTmSW1BMo6p",
"instantiation": "true",
"printer_model": "WonderMaker ZR Ultra S",
"nozzle_diameter": [
"0.6",
"0.6",
"0.6",
"0.6"
],
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
"printer_variant": "0.6",
"support_air_filtration": "1",
"support_chamber_temp_control": "1"
"nozzle_diameter": [
"0.6"
],
"max_layer_height": [
"0.42"
],
"min_layer_height": [
"0.12"
],
"retraction_length": [
"1.4",
"1.4",
"1.4",
"1.4"
],
"retraction_minimum_travel": [
"3",
"3",
"3",
"3"
]
}

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