mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 14:32:36 +00:00
docs: UX guidelines and charter for the Orca-CAD design group
The call with SoftFever settled that Orca-CAD is one of the branches to be implemented and that a design+dev group forms around it. A group without a written doctrine reviews by taste, and a CAD reviewed by taste becomes FreeCAD one locally-reasonable side panel at a time. So the doctrine is written first, as something a reviewer can FAIL a pull request against: ten laws each with its own test, the interaction grammar they compose into, the accessibility floor as a merge requirement, and a ten-question gate answered in every UI pull request. The position is Shapr3D's interaction economy, not its feature list — direct, gestural, almost no chrome, depth revealed by what you touch. Depth for mechanical designers arrives as progressive disclosure of tools that never move, in three tiers, non-modal, with assemblies and exploded views obeying the same point-then-act grammar as a beginner's extrude. The one thing neither Shapr3D nor FreeCAD has is that we live inside a slicer: plate, nozzle, material and build volume are known at design time, so print-domain failures are warnings on the geometry, not a report. Section 10 is an honest inventory: what already complies, and the six things that violate the laws today, none of them defended. The appendix keeps the anti-patterns we have already paid for, because each one is cheap to reintroduce. snaporca-2is.
This commit is contained in:
@@ -0,0 +1,405 @@
|
||||
# Orca-CAD — UX guidelines and design charter
|
||||
|
||||
Status: proposed, v1. Owner: design working group. Applies to the Design tab in
|
||||
both forks (Orca-CAD on OrcaSlicer, SnapOrca-CAD on Snapmaker Orca) — the CAD
|
||||
sources are byte-identical across them, so the UX doctrine is one doctrine.
|
||||
|
||||
This document is a **review instrument**, not an essay. Sections 3–9 are written
|
||||
so that a reviewer can hold a pull request against them and get a yes or a no.
|
||||
If a rule here cannot be failed, it is badly written and should be rewritten.
|
||||
|
||||
---
|
||||
|
||||
## 1. Why this exists
|
||||
|
||||
A CAD tool acquires its interface by accretion. Every feature arrives needing
|
||||
"just one more field", the side panel is the cheapest place to put it, and after
|
||||
forty features the product is FreeCAD: complete, respected, and abandoned by
|
||||
almost everyone who opens it once. That end state is not a failure of any single
|
||||
decision. It is the sum of forty locally reasonable ones taken without a written
|
||||
rule to violate.
|
||||
|
||||
So we write the rule down first, and we make additions argue against it.
|
||||
|
||||
## 2. Product thesis
|
||||
|
||||
**Orca-CAD is a modelling space for people who want a part, inside the tool that
|
||||
prints it.**
|
||||
|
||||
Two audiences, one interface:
|
||||
|
||||
- The maker who has an idea and a printer, and who has bounced off FreeCAD.
|
||||
They should be modelling something real within ten minutes of first opening
|
||||
the tab, without a tutorial, without knowing the word "constraint".
|
||||
- The mechanical designer who needs assemblies, mates, exploded views,
|
||||
variables, and a feature history they can edit six months later. They should
|
||||
not have to leave for SolidWorks the moment the work gets serious.
|
||||
|
||||
The reference for *how it feels* is Shapr3D: direct, gestural, quiet, almost no
|
||||
chrome, depth revealed by what you touch rather than by what is on screen. The
|
||||
anti-references are Blender (a modal keyboard language you must learn before the
|
||||
first success) and FreeCAD (a workbench-and-dialog architecture where the
|
||||
geometry is a preview of a form you fill in elsewhere).
|
||||
|
||||
We are not cloning Shapr3D's feature set. We are adopting its *interaction
|
||||
economy*: the smallest number of visible controls that still makes an expert
|
||||
fast.
|
||||
|
||||
**And one thing neither reference has:** Orca-CAD lives inside a slicer. The
|
||||
plate, the nozzle, the material and the print constraints are known to the
|
||||
application at design time. Designing for print is not a plugin here, it is the
|
||||
home advantage. Where a rule below trades generality for print-awareness, it
|
||||
trades in favour of print-awareness.
|
||||
|
||||
## 3. The laws
|
||||
|
||||
Non-negotiable. A change that breaks one of these does not get merged on the
|
||||
grounds that it was easier, that the alternative is more work, or that another
|
||||
CAD does it that way. Each law carries a test — the question a reviewer asks.
|
||||
|
||||
### L1 — Geometry first: you point, then you act
|
||||
|
||||
Controls live **on the geometry**: handles, arrows, points, small circles and
|
||||
boxes, with an inline label tab for typed values. Not in a side panel of combos
|
||||
and spin fields.
|
||||
|
||||
The canonical gesture: **select a face or plane in the viewport, then click the
|
||||
sketch tool.** Never: click the sketch tool, then choose a plane from a list.
|
||||
The tool consumes what you pointed at.
|
||||
|
||||
> **Test.** Can the operation be performed start to finish without the pointer
|
||||
> leaving the viewport, except to press the tool itself? If a control had to be
|
||||
> added to a panel to make it work, the design is not finished.
|
||||
|
||||
This is the law the others serve. It was stated after two proposals in a row
|
||||
reached for a dropdown, and the failure mode it names is real and recurrent: a
|
||||
fix that "adds a row to the plane combo" is the side-panel pattern wearing a
|
||||
different hat.
|
||||
|
||||
### L2 — Everything draggable is typable, and everything typable is draggable
|
||||
|
||||
Any value produced by direct manipulation (a fillet radius, an extrude depth, a
|
||||
pattern spacing, a plane offset) shows a live label on the geometry, and that
|
||||
label is an editable field. Any value entered numerically has a corresponding
|
||||
handle in the viewport.
|
||||
|
||||
Dragging is for finding the answer. Typing is for committing to it. A tool that
|
||||
offers only one of the two is half a tool.
|
||||
|
||||
> **Test.** Point at the number the tool produces. Can you drag it? Can you
|
||||
> click it and type? Both must be yes.
|
||||
|
||||
### L3 — Noun then verb, always the same way round
|
||||
|
||||
Selection precedes action, without exception, across sketch tools, features,
|
||||
dress-up, booleans and mates. There is no tool in the product that is armed
|
||||
first and asks for its input afterwards.
|
||||
|
||||
> **Test.** Does this tool work if the user has already selected the thing they
|
||||
> want it applied to? Does it work *only* that way?
|
||||
|
||||
### L4 — No modal dialog in the modelling loop
|
||||
|
||||
Dialogs belong to document-level actions: open, save, import, export, preferences.
|
||||
Modelling never opens one. A feature that needs three values gets three labels on
|
||||
the geometry, not a form; a feature that needs a confirmation gets a ghost preview
|
||||
and a click in empty space.
|
||||
|
||||
> **Test.** Between starting an operation and seeing its result, does a window
|
||||
> appear that must be dismissed? If yes, redesign.
|
||||
|
||||
### L5 — One click, one visible change
|
||||
|
||||
Every click either changes what is on screen or tells the user why it did not.
|
||||
A click that opens something invisible, arms an invisible state, or requires a
|
||||
second identical click to have any effect is a defect, not a design.
|
||||
|
||||
This law exists because we shipped its violation twice. Sketch-tool family
|
||||
buttons were flyouts whose first click only rendered a pressed state — three
|
||||
separate sessions filed bugs against tools that were working. Solid picking used
|
||||
a click *cycle* (first click selects the body, second refines to the face), so
|
||||
sketching on a face appeared broken to anyone who clicked a face once, the way
|
||||
every human does.
|
||||
|
||||
> **Test.** Perform the gesture exactly once, as a first-time user would. Take a
|
||||
> screenshot. Is the state visibly different, and is the difference the one the
|
||||
> user intended?
|
||||
|
||||
### L6 — The default is the answer four times out of five
|
||||
|
||||
Every option that has a default must have the *common* answer as its default,
|
||||
measured against real parts, not against generality. "New body" as the default
|
||||
result of an extrude is wrong: most extrudes join. Radius as the input for a
|
||||
circle is wrong: drawings give diameter.
|
||||
|
||||
> **Test.** Take ten real parts. In how many is the default correct? Below eight,
|
||||
> change the default or infer it from context.
|
||||
|
||||
### L7 — Errors are caught before the commit, in the user's words
|
||||
|
||||
A self-intersecting profile, a cut that removes no material, a wall thinner than
|
||||
the nozzle: these are reported at the moment they become knowable, on the
|
||||
geometry that is wrong, phrased as what happened and what to do — not as a kernel
|
||||
exception after the fact, and never silently.
|
||||
|
||||
> **Test.** Is the failure detectable before the user commits? Then it must be
|
||||
> reported before the user commits. Read the message aloud: does it name a thing
|
||||
> the user can see and an action they can take?
|
||||
|
||||
### L8 — The camera is the application's job
|
||||
|
||||
Selecting a sketch plane orients the view to it. Committing a feature does not
|
||||
throw the camera away. Zoom-to-fit exists and is one keystroke. The user is never
|
||||
required to fight the view in order to reach the geometry, and orbit is bound to
|
||||
the gesture people actually try.
|
||||
|
||||
> **Test.** Count camera manipulations in a representative modelling session.
|
||||
> Any camera action the application could have performed for the user is a bug.
|
||||
|
||||
### L9 — Accessible by construction, not by retrofit
|
||||
|
||||
The floor, applied to every new interaction (details in §6): full keyboard
|
||||
reach, no meaning carried by colour alone, hit targets that survive a shaky hand
|
||||
and a HiDPI screen, legible labels over an arbitrary 3D background, no gesture
|
||||
that depends on timing.
|
||||
|
||||
> **Test.** Drive the whole interaction from the keyboard. Then drive it in
|
||||
> greyscale. Both must work.
|
||||
|
||||
### L10 — Vocabulary from the drawing office
|
||||
|
||||
Names come from the language of people who make parts: fillet, chamfer, boss,
|
||||
rib, counterbore, mate, exploded view. Not from the kernel (no "boolean
|
||||
subtract", no "B-rep"), not from invented product-speak. Where the drawing-office
|
||||
word and the beginner's word differ, use the drawing-office word and make the
|
||||
tooltip teach it — an approachable tool that leaves the user unable to talk to a
|
||||
machinist has failed them.
|
||||
|
||||
> **Test.** Would a shop-floor engineer recognise this word? Would a first-time
|
||||
> user be able to look it up and find a real definition?
|
||||
|
||||
## 4. Interaction grammar
|
||||
|
||||
The rules above compose into one sentence the whole product obeys:
|
||||
|
||||
> **Point at geometry → press a tool → manipulate handles → type exact values →
|
||||
> click empty space to commit.**
|
||||
|
||||
Consequences worth stating explicitly:
|
||||
|
||||
- **Empty space commits.** Escape cancels. These two never change meaning
|
||||
between tools.
|
||||
- **The status line is one imperative sentence** naming what the tool wants
|
||||
next, and it names the target when the target came from a selection
|
||||
("Circle — click centre, then radius · on the picked face"). It is the
|
||||
authoritative feedback surface for the armed tool; the toolbar is not.
|
||||
- **Hover previews, click commits.** A hover shows the ghost of what a click
|
||||
would do wherever this is cheap to compute.
|
||||
- **Selection is persistent and visible** until consumed or cleared. A tool that
|
||||
consumes a selection clears it, so the next feature cannot silently inherit it.
|
||||
- **Every gesture is undoable**, and the feature tree is editable history, not a
|
||||
log. Re-editing a feature re-enters the same on-geometry interaction that
|
||||
created it.
|
||||
|
||||
## 5. Layout and screen budget
|
||||
|
||||
The viewport is the application. Chrome is a tax on it.
|
||||
|
||||
- **One toolbar**, contextual to the mode (model / sketch). Tools are grouped by
|
||||
what they make, not by which subsystem implements them.
|
||||
- **A left rail for the document, not for parameters**: feature tree, bodies,
|
||||
variables. It answers "what exists", never "what value should this be".
|
||||
- **No parameter panel.** Where one exists today it is technical debt with a
|
||||
scheduled removal (§10).
|
||||
- **Print context is ambient**, not a panel: the plate is visible in the design
|
||||
space, and print-domain warnings appear on the geometry that will fail.
|
||||
- **Nothing is added to permanent chrome without removing something**, or
|
||||
demonstrating that the addition is used in the majority of sessions.
|
||||
|
||||
## 6. Accessibility floor
|
||||
|
||||
Not a phase. A merge requirement.
|
||||
|
||||
- **Keyboard**: every operation reachable and completable without a pointer.
|
||||
Single-letter shortcuts for sketch tools, documented in the tool's own
|
||||
tooltip. A visible focus state on every focusable element. No shortcut that
|
||||
only works while the pointer happens to be over the canvas.
|
||||
- **Colour**: never the sole carrier of meaning. Selection is colour *and*
|
||||
outline; an error is colour *and* an icon *and* text. Verify in greyscale.
|
||||
- **Contrast**: labels over the 3D viewport get a scrim or halo so 4.5:1 holds
|
||||
against any background the model can produce, including a white body under a
|
||||
white plate.
|
||||
- **Targets**: handles and grips no smaller than 32 px at 100 % scale, scaling
|
||||
with the OS factor; the grab tolerance is larger than the drawn glyph.
|
||||
- **Timing**: no double-click-to-mean-something-else, no press-and-hold as the
|
||||
only route to a function, no cycle that depends on repeated clicks
|
||||
(see L5).
|
||||
- **Motion**: animation is functional (showing where a thing went), never
|
||||
decorative, and it respects the reduced-motion preference.
|
||||
- **Text**: no fixed-width assumptions; the UI holds together in German and in
|
||||
Chinese, at 125 % and 200 % scale. Every string routed through the normal
|
||||
translation path.
|
||||
|
||||
## 7. Depth without clutter — the three tiers
|
||||
|
||||
Power for experts is delivered by **progressive disclosure of tools, never by
|
||||
relocation of tools**. A tool that appears in a later tier is in the same place
|
||||
it will always be; it is simply not shown yet.
|
||||
|
||||
| Tier | Who | What appears |
|
||||
|---|---|---|
|
||||
| **Make** | first hour | Sketch, extrude, revolve, hole, fillet/chamfer, move, commit to plate |
|
||||
| **Model** | competent user | Patterns, shell, draft, sweep/loft, booleans, reference geometry, variables, import/export |
|
||||
| **Mechanism** | mechanical designer | Assemblies and mates, exploded views, interference detection, surfaces, feature-level editing of imported solids |
|
||||
|
||||
Rules that keep this honest:
|
||||
|
||||
1. **Tiers are non-modal.** No mode switch, no workbench selector, no "advanced
|
||||
mode" toggle that changes the meaning of anything. The tier only governs what
|
||||
is *offered*.
|
||||
2. **A tier reveals itself by use.** Using a body reveals boolean tools; adding
|
||||
a second body reveals assembly tools. The product notices what you are doing.
|
||||
3. **Nothing moves when a tier appears.** A user who learned where fillet lives
|
||||
finds it in the same place forever.
|
||||
4. **An expert tool obeys the same grammar** as a beginner tool. Mates are
|
||||
picked in 3D like everything else, not configured in a table.
|
||||
5. **Exploded views are a view state**, not a document mode — reversible,
|
||||
draggable along mate axes, and never a separate file.
|
||||
|
||||
## 8. Designing for print — the home advantage
|
||||
|
||||
Design-time knowledge the application already has, and must use:
|
||||
|
||||
- **The plate is present** in the design space, at the real size, with the real
|
||||
origin. Committing a body to the plate is one action and preserves placement.
|
||||
- **Print-domain checks run on the model, on the geometry, before slicing**:
|
||||
walls thinner than the nozzle, unsupported overhangs beyond the material's
|
||||
angle, features smaller than the layer height, a part that does not fit the
|
||||
build volume.
|
||||
- **These are warnings on the geometry, never a report.** The thin wall glows;
|
||||
the tooltip says how thin and what the nozzle is.
|
||||
- **Material and machine context is inherited** from the active slicer profile,
|
||||
not re-entered in the Design tab.
|
||||
- **The round trip is preserved**: editing a design after slicing returns to the
|
||||
feature history, not to a mesh.
|
||||
|
||||
## 9. The review gate
|
||||
|
||||
Every pull request that touches the Design tab UI answers these, in the PR body.
|
||||
A "no" that is not accompanied by an argument is a request for changes.
|
||||
|
||||
1. Which law (L1–L10) does the change most directly serve?
|
||||
2. Can the whole operation be completed without the pointer leaving the
|
||||
viewport? If not, why is this the exception?
|
||||
3. Are the values draggable *and* typable?
|
||||
4. Screenshot of the state after **exactly one** click of the new gesture,
|
||||
performed as a first-time user.
|
||||
5. Keyboard-only walkthrough: does it complete?
|
||||
6. Greyscale screenshot: is every state still distinguishable?
|
||||
7. What was **removed**? (Net additions to permanent chrome require an argument.)
|
||||
8. Which tier does it belong to, and does it appear without moving anything else?
|
||||
9. What does it do when the geometry is invalid, and is that reported before the
|
||||
commit?
|
||||
10. Interaction cost: actions required for the canonical task it addresses,
|
||||
before and after.
|
||||
|
||||
## 10. Where we stand today — honest inventory
|
||||
|
||||
Complying with the laws already:
|
||||
|
||||
- Sketch inline editors — draw an entity and its dimension tab opens on the
|
||||
geometry; Tab walks Length → Width → Angle.
|
||||
- Fillet/chamfer draggable radius arrow with an editable value label.
|
||||
- Extrude depth arrow; move-body three-axis arrows.
|
||||
- Datum-plane resize handles and offset arrow; ghost reference planes picked in
|
||||
3D.
|
||||
- Imported-art place/size gizmo.
|
||||
- Sketch plane taken from the picked face, with the target named in the status
|
||||
line, and the sketch-plane dropdown deleted outright.
|
||||
|
||||
Violating them, with removal scheduled:
|
||||
|
||||
- **Every tool card is a two-column form** of combos and spin fields in the left
|
||||
panel. This is the single largest debt in the product and the reason this
|
||||
document exists. Tracked as an epic; each card is replaced by its on-geometry
|
||||
equivalent, not improved in place.
|
||||
- Seven remaining plane pickers still populate a combo instead of consuming a
|
||||
viewport selection.
|
||||
- Pattern has no on-geometry spacing arrow or count badge.
|
||||
- Hole is positioned by X/Y fields rather than by a point on a face.
|
||||
- Booleans and cuts pick their operands from lists rather than in 3D.
|
||||
- Fillet/chamfer edge selection still requires the click cycle L5 forbids.
|
||||
|
||||
Nothing on the violating list is defended. The only open question for each is
|
||||
what its on-geometry replacement should be.
|
||||
|
||||
## 11. How the group works
|
||||
|
||||
**Roles.** Product/UX lead (owns this document and casts the tie-break vote on
|
||||
interaction questions); kernel maintainer; GUI maintainer; a print-domain
|
||||
reviewer; a mechanical-design reviewer who uses the product on real work; an
|
||||
accessibility reviewer. One person may hold more than one role; the UX lead and
|
||||
the mechanical-design reviewer should not be the same person.
|
||||
|
||||
**Cadence.** A short weekly review of open interaction proposals. A monthly pass
|
||||
over the violating inventory in §10 — anything that has not moved in two months
|
||||
is either scheduled or explicitly accepted as permanent, with a reason written
|
||||
into this document.
|
||||
|
||||
**How a change moves.**
|
||||
|
||||
1. *Problem* — a described user difficulty, ideally with an interaction-cost
|
||||
measurement, never a solution in disguise.
|
||||
2. *Sketch* — one or two on-geometry interaction proposals, drawn or described
|
||||
as a gesture sequence. Reviewed against §3 before any code.
|
||||
3. *Prototype* — built behind whatever the smallest safe path is, driven end to
|
||||
end on a real display, and screenshotted at each state.
|
||||
4. *Gate* — §9 answered in the PR.
|
||||
5. *Merge*, then update §10.
|
||||
|
||||
**Decisions are written down.** Any resolution that constrains future work is
|
||||
appended to this document as a numbered law or as an accepted exception with its
|
||||
reasoning. A decision that lives only in a call is not a decision.
|
||||
|
||||
**How disagreements resolve.** Against the laws first. If the laws do not decide
|
||||
it, the tie-break is the interaction cost measured on the canonical tasks in
|
||||
§12; if that does not decide it, the UX lead chooses and records why.
|
||||
|
||||
## 12. Canonical tasks — the benchmark
|
||||
|
||||
The measure of every UX change is the cost of these five tasks. Each is timed and
|
||||
counted (clicks, keystrokes, camera actions, mode switches) on the headless rig
|
||||
and, periodically, with real users who have not seen the product.
|
||||
|
||||
| # | Task | What it exercises |
|
||||
|---|---|---|
|
||||
| **B1** | Bracket: sketch an L, extrude, two holes, fillet the inside corner, send to plate | The inner loop |
|
||||
| **B2** | Change a hole diameter and the plate thickness, six features deep, and rebuild | Parametric editability |
|
||||
| **B3** | Take an imported STEP, delete a boss, close the face, thicken a wall to nozzle width | Direct editing + print awareness |
|
||||
| **B4** | Two parts, one revolute mate, check interference, produce an exploded view | The Mechanism tier |
|
||||
| **B5** | First-run: from opening the Design tab to a printed-ready solid, no documentation | Approachability |
|
||||
|
||||
Targets are set once each task has been measured on the current build; B5's
|
||||
target is expressed in minutes-to-first-solid, and it is the number this project
|
||||
is ultimately judged by.
|
||||
|
||||
---
|
||||
|
||||
### Appendix — anti-patterns we have already paid for
|
||||
|
||||
Kept because each cost real time and each is easy to reintroduce.
|
||||
|
||||
- **The dropdown that grew a row.** Fixing "cannot sketch on a face" by adding a
|
||||
"Face of Body 1" entry to a plane combo. It reads as a small fix and it is the
|
||||
side-panel architecture reproducing itself.
|
||||
- **The invisible first click.** Flyout buttons and pick cycles whose first click
|
||||
changes nothing meaningful. Filed as bugs three separate times against working
|
||||
code, and made a real bug look fixed when it was not.
|
||||
- **The fix verified through a path the user will never take.** A face-sketch fix
|
||||
confirmed by double-clicking to reach face level. Users click once. A fix
|
||||
reachable only by an undiscoverable gesture is indistinguishable from no fix.
|
||||
- **The wrong feedback surface.** Measuring an armed tool by the toolbar, which
|
||||
never renders keyboard-armed state. The status line is the surface that
|
||||
answers.
|
||||
- **The silent success.** A cut that removed no material, reported as done. Now
|
||||
an error naming the likely cause.
|
||||
Reference in New Issue
Block a user