mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-23 08:53:05 +00:00
Design: slot Radius caption, keyboard offer, plane combo removal, mass props, docs
Mirror of snaporca ac85277bac..0e7cb3ec78 (six changes, applied as a patch to DesignPanel.cpp rather than copied, so this fork's 30 permitted divergent lines survive — parity re-checked afterwards: the five shared files are byte-identical, DesignCanvas.cpp and DesignPanel.cpp differ by exactly 16 and 30 lines). - The straight slot's inline field says Radius, which is what it sets. It stores the half-width and passed the typed number through unchanged, so 30 produced a 60 mm slot. - The offer opens from the keyboard (Menu, Shift+F10), anchored on the viewport rather than wherever the pointer happens to be. The card hint names the new route. - The sketch card's Plane combo is gone; the plane comes from the viewport. Also stops build_candidate collapsing a face plane to a base plane while editing. - Mass properties and the dead Edit row are wired into the offer; DesignOffer.hpp is regenerated from tool_atlas.json, verified by re-running the generator and diffing. - docs/rig_build_traps.md + scripts/rig-build.sh, which derives its fork identity from project() so it cannot be pointed at the other fork's image or volume. - docs/design_tab.md refreshed (44 commits stale) + a PR description, with this fork's own merge-base and diff shape rather than snaporca's. Built green in the deps container with the new script and verified on the rig: Menu and Shift+F10 both open the offer at the viewport centre with the pointer parked off-canvas, and the sketch card shows no Plane row. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LyRwbuq6fjn3VV9U9UvhBM
This commit is contained in:
co-authored by
Claude Opus 5
parent
6e9910303b
commit
fd1bc092d8
+138
-14
@@ -1,8 +1,9 @@
|
||||
# The Design tab
|
||||
|
||||
A parametric CAD modeller inside the slicer. Draw a sketch, turn it into a solid, refine it,
|
||||
and send it straight to Prepare — without leaving for another application and coming back
|
||||
through an STL.
|
||||
Object-driven parametric CAD inside the slicer. Point at geometry; the geometry offers the
|
||||
verbs that apply to it. Selection comes first and the tool consumes it. Draw a sketch,
|
||||
constrain it, turn it into a solid, refine it, and send it straight to Prepare — without
|
||||
leaving for another application and coming back through an STL.
|
||||
|
||||
The model is a **recipe**, not a mesh. Every action becomes a feature in a tree that is
|
||||
replayed from the start whenever anything changes, so editing a dimension you set twenty
|
||||
@@ -14,19 +15,142 @@ already ships for STEP import.
|
||||
## Getting started
|
||||
|
||||
1. Open the **Design** tab.
|
||||
2. Pick a plane — XY, XZ or YZ — and press **Sketch**.
|
||||
3. Draw a closed profile, then press **✓** to finish the sketch.
|
||||
4. Select the sketch and press **Extrude** (`Shift+E`).
|
||||
2. Click a face or a reference plane in the viewport, then press `Shift+S` (Sketch). The offer
|
||||
opens with the sketch tools on it.
|
||||
3. Draw a closed profile, then press **✓ Confirm** in the floating action bar.
|
||||
4. With the sketch selected, press `Shift+E` (Extrude).
|
||||
5. Press **Commit to Plate** to hand the solid to Prepare.
|
||||
|
||||
The status line under the toolbar is the thing to watch: it says what the current tool is
|
||||
waiting for, and it is where a refusal explains itself.
|
||||
waiting for. When no plane is picked it reads *"Click a face or a reference plane in the
|
||||
viewport, then a sketch tool"*; once one is picked it reads *"Sketching on <face> — pick a
|
||||
tool"*. It is also where a refusal explains itself.
|
||||
|
||||
---
|
||||
|
||||
## Selecting
|
||||
|
||||
- One left-click selects what is under the cursor. There is no click-cycling through
|
||||
face → edge → body.
|
||||
- A click near a corner takes the corner, not the face behind it.
|
||||
- Left-drag sweeps a rubber band, and a rubber band takes the whole body.
|
||||
- An open sketch line can be clicked, even where it bounds a region.
|
||||
- Double-click a sketch stroke to edit it — the gesture belongs on the geometry.
|
||||
- Editing a dimension's value **updates** that dimension instead of adding a second one next
|
||||
to it.
|
||||
- The floating chrome that belongs to a sketch leaves with the sketch when it ends.
|
||||
- Sketching happens on the face you clicked, first click.
|
||||
- A sketch whose entities form no wire **fails** instead of extruding a default box. A
|
||||
subtraction that removes nothing is reported as an error instead of a silent success.
|
||||
|
||||
---
|
||||
|
||||
## The offer
|
||||
|
||||
Right-click on the geometry, released without moving the mouse (an 8 px budget — a
|
||||
right-drag that orbits the camera does not open it). Left-click still only selects, so
|
||||
pointing at things stays quiet.
|
||||
|
||||
The offer also opens by itself the moment you press Sketch on a face or plane, showing the
|
||||
sketch tools — the app hands you the tools directly.
|
||||
|
||||
**Eight families, always in this fixed order:** Create, Add material, Remove, Dress-up,
|
||||
Repeat, Transform, Reference, Modify.
|
||||
|
||||
- A family with at least one applicable verb shows it. Several applicable verbs collapse
|
||||
into a submenu under the family name.
|
||||
- A family with nothing applicable is **shown greyed in place, with the reason** — e.g.
|
||||
*"Create — Click a face or a reference plane in the viewport, then a sketch tool"*. It is
|
||||
not hidden. A control that cannot be used still says what it is and what you would have to
|
||||
do first.
|
||||
- Inside a sketch the offer shows the sketch verbs; outside it shows the feature verbs.
|
||||
|
||||
**Document-level actions never enter the offer**, because they act on the document and not
|
||||
on a selection: Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo,
|
||||
Redo, Variables, Section view, Origin planes, World axes. They live in the toolbar.
|
||||
|
||||
---
|
||||
|
||||
## Keyboard
|
||||
|
||||
Single letters drive sketch tools **while a sketch is open**; Shift+letter drives feature
|
||||
tools and single letters drive view toggles **when no sketch is open**. The two maps are
|
||||
selected by the mode, not by whether a sketch session is running.
|
||||
|
||||
### Sketch (while a sketch is open)
|
||||
|
||||
| Key | Tool |
|
||||
|---|---|
|
||||
| `L` | Line — click start, then end |
|
||||
| `R` | Rectangle — click two opposite corners |
|
||||
| `C` | Circle — click centre, then radius |
|
||||
| `A` | Arc — click start, end, then a point |
|
||||
| `S` | Slot — two centreline ends, then width |
|
||||
| `E` | Ellipse — centre, major end, minor point |
|
||||
| `B` | Spline — click control points |
|
||||
| `P` | Point — click to place |
|
||||
| `G` | Polygon — click centre, then a vertex |
|
||||
| `D` | Dimension — click 2 points or an entity |
|
||||
| `T` | Trim — click a segment to trim it |
|
||||
| `X` | Extend — click a line/arc to extend it |
|
||||
| `O` | Offset — pick an entity, drag the distance |
|
||||
| `M` | Mirror — pick axis, then entities |
|
||||
| `F` | Fillet — pick two lines, set the radius |
|
||||
| `H` | Chamfer — pick two lines, set the distance |
|
||||
| `K` | Constrain — finish the live sketch and enter constrain |
|
||||
| `Q` | Construction toggle — draw the next entity as construction geometry |
|
||||
| `Del` | Delete the selected sketch entity |
|
||||
| `Esc` | Cancel the live tool |
|
||||
|
||||
### Feature (when no sketch is open)
|
||||
|
||||
| Key | Tool |
|
||||
|---|---|
|
||||
| `Shift+S` | Sketch |
|
||||
| `Shift+E` | Extrude — extrude a profile, or push/pull a picked face |
|
||||
| `Shift+R` | Revolve |
|
||||
| `Shift+W` | Sweep |
|
||||
| `Shift+L` | Loft |
|
||||
| `Shift+N` | Pattern |
|
||||
| `Shift+G` | Surface Extrude |
|
||||
| `Shift+J` | Surface Revolve |
|
||||
| `Shift+O` | Surface Loft |
|
||||
| `Shift+Q` | Surface Fill |
|
||||
| `Shift+U` | Surface Offset |
|
||||
| `Shift+V` | Thicken Surface |
|
||||
| `Shift+P` | Plane |
|
||||
| `Shift+A` | Axis |
|
||||
| `Shift+C` | Coord Sys |
|
||||
| `Shift+Y` | Transform |
|
||||
| `Shift+Z` | Mirror |
|
||||
| `Shift+B` | Boolean |
|
||||
| `Shift+X` | Cut |
|
||||
| `Shift+F` | Fillet / Chamfer |
|
||||
| `Shift+D` | Draft |
|
||||
| `Shift+K` | Shell |
|
||||
| `Shift+H` | Hole |
|
||||
| `Shift+T` | Thread |
|
||||
| `Shift+I` | Import STEP |
|
||||
| `Shift+M` | Import mesh |
|
||||
|
||||
### View toggles (single letters, when no sketch is open)
|
||||
|
||||
| Key | Action |
|
||||
|---|---|
|
||||
| `P` | Origin planes on/off |
|
||||
| `A` | World axes on/off |
|
||||
| `X` | Section view on/off |
|
||||
|
||||
While the section is on: `PageUp` / `PageDown` move the cut plane, `F` flips which half is
|
||||
kept. With no section on, `F` is Place on Face — lay the picked face flat on the bed.
|
||||
|
||||
---
|
||||
|
||||
## Sketching
|
||||
|
||||
A sketch is a closed (or open) 2D profile on a plane or on a flat face of an existing body.
|
||||
Press `Shift+S`, click the face or plane you want to sketch on, and draw. The toolbar and
|
||||
the offer both carry the sketch tools.
|
||||
|
||||
**Entities:** line, polyline, rectangle (corner / centre / oblique / rounded), circle
|
||||
(centre-radius / 2-point / 3-point), arc (centre-point / 3-point / tangent), ellipse and
|
||||
@@ -168,10 +292,10 @@ mesh.
|
||||
|
||||
## View controls
|
||||
|
||||
**Section view** hides half the model so you can see inside — `PageUp`/`PageDown` move the
|
||||
plane, Flip shows the other half, `Delete` removes it. **Place on Face** (`F`) lays a picked
|
||||
face flat on the bed. The bed and its grid can be toggled off when they get in the way, and
|
||||
origin planes and world axes can be shown while you orient yourself.
|
||||
**Section view** (`X`) hides half the model so you can see inside — `PageUp`/`PageDown` move
|
||||
the plane, `F` flips which half is kept. **Place on Face** (`F`, when section is off) lays a
|
||||
picked face flat on the bed. Origin planes (`P`) and world axes (`A`) can be toggled on while
|
||||
you orient yourself.
|
||||
|
||||
---
|
||||
|
||||
@@ -182,12 +306,12 @@ Being straight about the edges, so nobody discovers them the hard way:
|
||||
- **Rib** needs a sketch containing an explicit open line. A parametric rectangle sketch
|
||||
carries no individual entities, so Rib cannot use one.
|
||||
- **Surface Loft** and **Surface Fill** have kernel tests but have not been exercised by hand.
|
||||
- Two kernel tests are known-broken and excluded from the suite: a tangent-constraint case
|
||||
that aborts inside the vendored solver, and an internal-thread groove volume below its
|
||||
asserted threshold. Both are tracked, neither is fixed.
|
||||
- Card wiring for 9 of the 16 late-wired tools has never been click-tested.
|
||||
- Mate resolves by composing transforms directly. There is no 3D assembly solver, so mates
|
||||
are applied in order rather than solved simultaneously, and mate limits are not implemented.
|
||||
- Move-face and replace-face are not implemented — OCCT offers no clean primitive for them.
|
||||
- There is no automated GUI test in CI. Every behaviour above is traced to code and to a
|
||||
hand pass, not to a synthetic click.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# Design (CAD) tab — upstream pull request
|
||||
|
||||
## What this adds
|
||||
|
||||
A sketch-first parametric CAD tab inside the slicer. The workflow is direct:
|
||||
sketch → constrain → solid features → commit to plate. The whole feature recipe is
|
||||
persisted inside the 3MF, so reopening restores an editable model rather than a frozen mesh.
|
||||
|
||||
- Kernel: OCCT, which upstream already links for STEP import — see
|
||||
[cad_dependency_weight.md](docs/cad_dependency_weight.md)
|
||||
- Constraint solver: vendored SolveSpace `libslvs` subset
|
||||
- Interaction model: object-driven — point at geometry, the geometry offers the verbs that
|
||||
apply to it; see [cad_ux_guidelines.md](docs/cad_ux_guidelines.md)
|
||||
- Full user-facing documentation: [design_tab.md](docs/design_tab.md)
|
||||
|
||||
## Why it belongs in the slicer
|
||||
|
||||
Every round trip through an external CAD tool costs a file export, a re-import, and the
|
||||
design intent that both steps discard. A part modified after slicing should return to its
|
||||
feature history, not to a mesh. Keeping the CAD model inside the slicer preserves that
|
||||
loop — the nozzle diameter, the build volume and the material are known at design time.
|
||||
|
||||
For the integration case in full: [design_tab_upstream_portability.md](docs/design_tab_upstream_portability.md).
|
||||
|
||||
## How it is built
|
||||
|
||||
The `SLIC3R_CAD` CMake flag (default ON) gates the entire tab. With it OFF the tab is not
|
||||
compiled and the deps prefix matches upstream exactly — the dependency diff is one line in
|
||||
OCCT's CMake: `BUILD_MODULE_ModelingAlgorithms=OFF → ON`.
|
||||
|
||||
Measured cost table: [cad_dependency_weight.md](docs/cad_dependency_weight.md).
|
||||
|
||||
## Diff shape
|
||||
|
||||
<!-- fork-specific: measured against this fork's upstream base; re-run the commands above after mirroring -->
|
||||
|
||||
Against merge-base `d6cb667b894f`:
|
||||
|
||||
306 files changed, 83032 insertions(+), 777 deletions(-)
|
||||
|
||||
350 commits, of which 284 are new files and 37 modify upstream files. 99.3 % of the diff
|
||||
is new code. The negotiable surface is the 37 modified files.
|
||||
|
||||
## Tests
|
||||
|
||||
205 `TEST_CASE` blocks across 6 new test source files. This counts assertions written, not
|
||||
assertions passed — a run needs a build.
|
||||
|
||||
`scripts/kernel-test.sh` is the headless verification contract: it builds only
|
||||
`libslic3r_tests` (not the GUI app), needs no display, and exit 0 means the CAD suite
|
||||
passed. It now runs with **no exclusions** — both cases that used to be quarantined (the
|
||||
circle-line tangency solver abort and the internal-thread reference) are fixed.
|
||||
|
||||
## Licensing
|
||||
|
||||
The vendored solver in `src/libslic3r/slvs/` is **GPL-3.0** (see `src/libslic3r/slvs/LICENSE`),
|
||||
not LGPL. The combined work is distributable under AGPL-3.0. See the Licensing section of
|
||||
[design_tab_upstream_portability.md](docs/design_tab_upstream_portability.md) for the
|
||||
AGPLv3/GPLv3 compatibility argument; this point should be confirmed with upstream explicitly.
|
||||
|
||||
## Not verified
|
||||
|
||||
- Card wiring for 9 of the 16 late-wired tools was never click-tested.
|
||||
- There is no automated GUI test in CI. A green kernel run says nothing about the GUI —
|
||||
synthetic clicks never drift, so the test suite and the viewport are two separate realities.
|
||||
- The click-test defect rate has **not converged**: a second pass found no new defects, but
|
||||
four further days of work found five more. The earlier pass is not evidence of stability.
|
||||
|
||||
## Reviewer's map
|
||||
|
||||
See the [Where the code lives](docs/design_tab.md#where-the-code-lives) table in the user
|
||||
doc for the file-to-role mapping, and [docs/ux/tool_atlas.json](docs/ux/tool_atlas.json) as
|
||||
the generated-from source of `src/slic3r/GUI/DesignOffer.hpp`.
|
||||
@@ -0,0 +1,123 @@
|
||||
# Rig build traps
|
||||
|
||||
The build rig is two long-lived containers, `snaporca-gui` and `orcacad-gui`, one per fork. Each
|
||||
mounts only its fork's build volume (`snaporca_buildcache` / `orcacad_buildcache`) at
|
||||
`/OrcaSlicer/build`, its fork's `resources/`, and a shots directory — nothing else. They run the
|
||||
binary; they do not build it. Rebuild with `scripts/rig-build.sh`.
|
||||
|
||||
| fork repo | project() | deps image | build volume | GUI container | binary |
|
||||
|---|---|---|---|---|---|
|
||||
| `snaporca` | `Snapmaker_Orca` | `snaporca-deps` | `snaporca_buildcache` | `snaporca-gui` | `snapmaker-orca` |
|
||||
| `orca_cad` | `OrcaSlicer` | `orcacad-deps` | `orcacad_buildcache` | `orcacad-gui` | `orca-slicer` |
|
||||
|
||||
`scripts/rig-build.sh` exists alongside `scripts/docker-iter-build.sh` for one reason: it does a
|
||||
target-only `ninja` into the volume the GUI rig launches from, so a session can test a single
|
||||
change without a full repackage, whereas `docker-iter-build.sh` runs the full packaged build.
|
||||
Both start a throwaway container from the deps image with the live repo mounted over the baked
|
||||
tree — never build inside the GUI container (Trap 1).
|
||||
|
||||
Every trap below has already cost about a session to re-derive, once each. They are recorded now
|
||||
so no fresh session pays them again. Symptoms, causes, and exact recovery commands follow.
|
||||
|
||||
---
|
||||
|
||||
## Trap 1 — never configure inside the GUI container
|
||||
|
||||
**Symptom.** After building inside the GUI container, the fork's targets no longer exist; ninja
|
||||
reports an unknown target, and `orca-slicer` / `OrcaSlicer` have been replaced by
|
||||
`snapmaker-orca` / `Snapmaker_Orca`.
|
||||
|
||||
**Cause.** The GUI image's baked `/OrcaSlicer` tree is the Jun-13 Snapmaker-derived source
|
||||
(`project(Snapmaker_Orca)`, executable `snapmaker-orca`). `orcacad-deps` is layered on
|
||||
`snaporca-deps`, so even on the mainline fork the baked tree is the other fork's. A `cmake .`
|
||||
there reconfigures the shared build dir under the wrong project name.
|
||||
|
||||
**Fix.** Build only via `scripts/rig-build.sh`, which starts a throwaway container from the deps
|
||||
image with the live repo mounted over the baked tree — `src`, `resources`, `cmake`, `deps_src`,
|
||||
`localization`, `CMakeLists.txt`, `version.inc` — and writes into the same volume the rig
|
||||
launches from.
|
||||
|
||||
---
|
||||
|
||||
## Trap 2 — stale `NLopt_DIR` in CMakeCache
|
||||
|
||||
**Symptom.** Configure fails with `Cannot find NLopt library 'nlopt_cxx' in '<prefix>/lib'`.
|
||||
|
||||
**Cause.** `cmake/modules/FindNLopt.cmake:26` is `set(NLopt_DIR $ENV{NLOPT})`. With `NLOPT`
|
||||
unset that expands to `set(NLopt_DIR)` — zero arguments — which *unsets the normal variable* and
|
||||
lets a leftover CACHE entry of the same name (e.g. `<prefix>/lib/cmake/nlopt`) show through the
|
||||
following `if(NOT NLopt_DIR)`. The `else()` branch then searches for `nlopt_cxx` under
|
||||
`${NLopt_DIR}/lib` with `NO_DEFAULT_PATH`, while the deps prefix ships plain `nlopt`.
|
||||
|
||||
**Fix.** From inside the build dir:
|
||||
|
||||
cmake -U NLopt_DIR -U NLopt_LIBS .
|
||||
|
||||
Do **not** `sed` the entry out of `CMakeCache.txt` — deleting a line breaks the cache parser.
|
||||
|
||||
---
|
||||
|
||||
## Trap 3 — the image lacks `deps_src/pybind11`
|
||||
|
||||
**Symptom.** Configure aborts with `pybind11 headers not found in /OrcaSlicer/deps_src/pybind11.
|
||||
Did you initialize submodules?` (the `FATAL_ERROR` guarding `PYBIND11_SOURCE_DIR` in the mainline
|
||||
fork's root `CMakeLists.txt`, near line 948).
|
||||
|
||||
**Cause.** The deps image predates that requirement. Only the mainline (`orca_cad`) fork has
|
||||
`deps_src/pybind11` and the requirement; snaporca has neither.
|
||||
|
||||
**Fix.** Mount `deps_src` over the baked tree — `scripts/rig-build.sh` does. Corollary: mounting a
|
||||
snaporca tree into an `orcacad-deps` build reproduces this error exactly.
|
||||
|
||||
---
|
||||
|
||||
## Trap 4 — `OCCT_LIBS` lags one configure
|
||||
|
||||
**Symptom.** A wall of undefined references to `TopOpeBRepBuild` symbols. It reads as a broken
|
||||
OCCT installation. It is not.
|
||||
|
||||
**Cause.** `src/libslic3r/CMakeLists.txt:603` does
|
||||
`set(OCCT_LIBS "${OCCT_LIBS}" CACHE INTERNAL "OCCT toolkits linked by libslic3r")` at the END of
|
||||
its own configure, while the consumer in the root `CMakeLists.txt` (`if (NOT OCCT_LIBS)` …
|
||||
`foreach (_tk IN LISTS OCCT_LIBS)`) reads whatever is already in the cache. The first reconfigure
|
||||
after the `TKFillet TKOffset` prepend (`src/libslic3r/CMakeLists.txt:599`) therefore links the
|
||||
previous list and drops `TKBool`/`TKOffset`.
|
||||
|
||||
**Fix.** Configure twice. `scripts/rig-build.sh` runs `cmake .` twice for exactly this reason; if
|
||||
you ever configure by hand, run it twice.
|
||||
|
||||
---
|
||||
|
||||
## Trap 5 — `SLIC3R_CAD=ON` in the cache, macro never defined
|
||||
|
||||
**Symptom.** The build succeeds and links, but the Design tab is simply absent — or it fails with
|
||||
`class GLCanvas3D has no member named set_design_sketch_tool`.
|
||||
|
||||
**Cause.** The cache carries `SLIC3R_CAD=ON`, but the root `CMakeLists.txt` actually configured is
|
||||
a stale baked copy that predates the gate and never runs `add_definitions(-DSLIC3R_CAD)` (the
|
||||
gate is `if (SLIC3R_CAD)` / `add_definitions(-DSLIC3R_CAD)` in the root list — line 179/180 in
|
||||
snaporca, 319/320 in orca_cad). Every `#ifdef SLIC3R_CAD` block therefore compiles out while the
|
||||
option still reads ON.
|
||||
|
||||
**Fix.** Always mount the live `CMakeLists.txt` and `cmake/` — never inherit them from the image.
|
||||
This is why `scripts/docker-iter-build.sh`, `scripts/kernel-test.sh` and `scripts/rig-build.sh`
|
||||
all mount both.
|
||||
|
||||
---
|
||||
|
||||
## The binary the rig actually launches
|
||||
|
||||
`ninja <target>` writes `/OrcaSlicer/build/src/Release/<binary>`; only `build_linux.sh`
|
||||
additionally packages to `/OrcaSlicer/build/package/bin/<binary>`. `orca_cad`'s
|
||||
`scripts/gui-session.sh` defaults `BIN` to `src/Release/orca-slicer`, but snaporca's defaults to
|
||||
`package/bin/snapmaker-orca`. So after a target-only rebuild on snaporca, launching
|
||||
`gui-session.sh` with its default runs the **stale packaged** binary — the change under test is
|
||||
invisible and the session hunts a phantom. Pass `BIN` explicitly:
|
||||
|
||||
docker exec -e BIN=/OrcaSlicer/build/src/Release/snapmaker-orca snaporca-gui /OrcaSlicer/scripts/gui-session.sh
|
||||
|
||||
`scripts/rig-build.sh` prints the correct line for the current fork when it finishes.
|
||||
|
||||
Note also that the GUI containers do **not** mount `scripts/`: `/OrcaSlicer/scripts` inside them
|
||||
is the baked copy, so a local edit to `gui-session.sh` has no effect until you
|
||||
`docker cp scripts/gui-session.sh <container>:/OrcaSlicer/scripts/`.
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -829,8 +829,8 @@
|
||||
"bodies": 1
|
||||
},
|
||||
"refusal": null,
|
||||
"gui": false,
|
||||
"action": null
|
||||
"gui": true,
|
||||
"action": "btn:mass"
|
||||
},
|
||||
{
|
||||
"id": "interference",
|
||||
@@ -871,7 +871,7 @@
|
||||
"needs": {},
|
||||
"refusal": null,
|
||||
"gui": true,
|
||||
"action": null
|
||||
"action": "btn:edit"
|
||||
},
|
||||
{
|
||||
"id": "delete_face",
|
||||
|
||||
Reference in New Issue
Block a user