diff --git a/docs/ux/mockups/cmp_12__edge_str.svg b/docs/ux/mockups/cmp_12__edge_str.svg new file mode 100644 index 0000000000..3e641e90ec --- /dev/null +++ b/docs/ux/mockups/cmp_12__edge_str.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 12 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/ux/mockups/cmp_12__face_planar.svg b/docs/ux/mockups/cmp_12__face_planar.svg new file mode 100644 index 0000000000..85809d5bf6 --- /dev/null +++ b/docs/ux/mockups/cmp_12__face_planar.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/ux/mockups/cmp_12__sk_line.svg b/docs/ux/mockups/cmp_12__sk_line.svg new file mode 100644 index 0000000000..6535c9fe77 --- /dev/null +++ b/docs/ux/mockups/cmp_12__sk_line.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/ux/mockups/cmp_8__edge_str.svg b/docs/ux/mockups/cmp_8__edge_str.svg new file mode 100644 index 0000000000..2c41ce74fc --- /dev/null +++ b/docs/ux/mockups/cmp_8__edge_str.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/ux/mockups/cmp_8__face_planar.svg b/docs/ux/mockups/cmp_8__face_planar.svg new file mode 100644 index 0000000000..5a58e2fb72 --- /dev/null +++ b/docs/ux/mockups/cmp_8__face_planar.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/ux/mockups/cmp_8__sk_line.svg b/docs/ux/mockups/cmp_8__sk_line.svg new file mode 100644 index 0000000000..4ca4000d59 --- /dev/null +++ b/docs/ux/mockups/cmp_8__sk_line.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/ux/mockups/fresh__art.svg b/docs/ux/mockups/fresh__art.svg new file mode 100644 index 0000000000..a54dd49b43 --- /dev/null +++ b/docs/ux/mockups/fresh__art.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetText / imported art selected — pick what to do with itFresh document · 8 slotsABCModify2Text / imported art \ No newline at end of file diff --git a/docs/ux/mockups/fresh__art__modify.svg b/docs/ux/mockups/fresh__art__modify.svg new file mode 100644 index 0000000000..184611c682 --- /dev/null +++ b/docs/ux/mockups/fresh__art__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsABCDeleteDelEditText / imported art · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__bodies_2.svg b/docs/ux/mockups/fresh__bodies_2.svg new file mode 100644 index 0000000000..f282bef03a --- /dev/null +++ b/docs/ux/mockups/fresh__bodies_2.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetTwo bodies selected — pick what to do with itFresh document · 8 slotsMeasureDeleteDelTwo bodies \ No newline at end of file diff --git a/docs/ux/mockups/fresh__body_sheet.svg b/docs/ux/mockups/fresh__body_sheet.svg new file mode 100644 index 0000000000..635b2f6aa6 --- /dev/null +++ b/docs/ux/mockups/fresh__body_sheet.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetSheet body selected — pick what to do with itFresh document · 8 slotsMeasureModify2Sheet body \ No newline at end of file diff --git a/docs/ux/mockups/fresh__body_sheet__modify.svg b/docs/ux/mockups/fresh__body_sheet__modify.svg new file mode 100644 index 0000000000..0cd330046d --- /dev/null +++ b/docs/ux/mockups/fresh__body_sheet__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditSheet body · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__body_solid.svg b/docs/ux/mockups/fresh__body_solid.svg new file mode 100644 index 0000000000..ef21e2b8e2 --- /dev/null +++ b/docs/ux/mockups/fresh__body_solid.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetSolid body selected — pick what to do with itFresh document · 8 slotsMeasureModify2Solid body \ No newline at end of file diff --git a/docs/ux/mockups/fresh__body_solid__modify.svg b/docs/ux/mockups/fresh__body_solid__modify.svg new file mode 100644 index 0000000000..8b5d1485a0 --- /dev/null +++ b/docs/ux/mockups/fresh__body_solid__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditSolid body · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__coordsys.svg b/docs/ux/mockups/fresh__coordsys.svg new file mode 100644 index 0000000000..e20d08d000 --- /dev/null +++ b/docs/ux/mockups/fresh__coordsys.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCoordinate system selected — pick what to do with itFresh document · 8 slotsModify2Coordinate system \ No newline at end of file diff --git a/docs/ux/mockups/fresh__coordsys__modify.svg b/docs/ux/mockups/fresh__coordsys__modify.svg new file mode 100644 index 0000000000..b6b4871d16 --- /dev/null +++ b/docs/ux/mockups/fresh__coordsys__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditCoordinate system · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__datum_axis.svg b/docs/ux/mockups/fresh__datum_axis.svg new file mode 100644 index 0000000000..8174807ceb --- /dev/null +++ b/docs/ux/mockups/fresh__datum_axis.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetDatum axis selected — pick what to do with itFresh document · 8 slotsModify2Datum axis \ No newline at end of file diff --git a/docs/ux/mockups/fresh__datum_axis__modify.svg b/docs/ux/mockups/fresh__datum_axis__modify.svg new file mode 100644 index 0000000000..cba7005358 --- /dev/null +++ b/docs/ux/mockups/fresh__datum_axis__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditDatum axis · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__datum_plane.svg b/docs/ux/mockups/fresh__datum_plane.svg new file mode 100644 index 0000000000..ffabd59969 --- /dev/null +++ b/docs/ux/mockups/fresh__datum_plane.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetDatum plane selected — pick what to do with itFresh document · 8 slotsSketchShift+SReference2Modify2Datum plane \ No newline at end of file diff --git a/docs/ux/mockups/fresh__datum_plane__modify.svg b/docs/ux/mockups/fresh__datum_plane__modify.svg new file mode 100644 index 0000000000..9ac26e4ce1 --- /dev/null +++ b/docs/ux/mockups/fresh__datum_plane__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditDatum plane · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__datum_plane__reference.svg b/docs/ux/mockups/fresh__datum_plane__reference.svg new file mode 100644 index 0000000000..b42479441a --- /dev/null +++ b/docs/ux/mockups/fresh__datum_plane__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsPlaneShift+PHelixDatum plane · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__edge_circ.svg b/docs/ux/mockups/fresh__edge_circ.svg new file mode 100644 index 0000000000..3e72544c04 --- /dev/null +++ b/docs/ux/mockups/fresh__edge_circ.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCircular edge selected — pick what to do with itFresh document · 8 slotsMeasureCircular edge \ No newline at end of file diff --git a/docs/ux/mockups/fresh__edge_str.svg b/docs/ux/mockups/fresh__edge_str.svg new file mode 100644 index 0000000000..c4e54d5335 --- /dev/null +++ b/docs/ux/mockups/fresh__edge_str.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetStraight edge selected — pick what to do with itFresh document · 8 slotsReference3Straight edge \ No newline at end of file diff --git a/docs/ux/mockups/fresh__edge_str__reference.svg b/docs/ux/mockups/fresh__edge_str__reference.svg new file mode 100644 index 0000000000..80dd7a877a --- /dev/null +++ b/docs/ux/mockups/fresh__edge_str__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsMeasurePlaneShift+PAxisShift+AStraight edge · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__face_cyl.svg b/docs/ux/mockups/fresh__face_cyl.svg new file mode 100644 index 0000000000..d2335e4177 --- /dev/null +++ b/docs/ux/mockups/fresh__face_cyl.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCylindrical face selected — pick what to do with itFresh document · 8 slotsReference3EditCylindrical face \ No newline at end of file diff --git a/docs/ux/mockups/fresh__face_cyl__reference.svg b/docs/ux/mockups/fresh__face_cyl__reference.svg new file mode 100644 index 0000000000..7cb83afb56 --- /dev/null +++ b/docs/ux/mockups/fresh__face_cyl__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsMeasureAxisShift+AHelixCylindrical face · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__face_other.svg b/docs/ux/mockups/fresh__face_other.svg new file mode 100644 index 0000000000..d8dcfb96ab --- /dev/null +++ b/docs/ux/mockups/fresh__face_other.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCurved face selected — pick what to do with itFresh document · 8 slotsMeasureEditCurved face \ No newline at end of file diff --git a/docs/ux/mockups/fresh__face_planar.svg b/docs/ux/mockups/fresh__face_planar.svg new file mode 100644 index 0000000000..a66268fc9a --- /dev/null +++ b/docs/ux/mockups/fresh__face_planar.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetPlanar face selected — pick what to do with itFresh document · 8 slotsSketchShift+SExtrudeShift+EReference4EditPlanar face \ No newline at end of file diff --git a/docs/ux/mockups/fresh__face_planar__reference.svg b/docs/ux/mockups/fresh__face_planar__reference.svg new file mode 100644 index 0000000000..9aa608a5e7 --- /dev/null +++ b/docs/ux/mockups/fresh__face_planar__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+APlanar face · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__none.svg b/docs/ux/mockups/fresh__none.svg new file mode 100644 index 0000000000..56ac028b74 --- /dev/null +++ b/docs/ux/mockups/fresh__none.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected \ No newline at end of file diff --git a/docs/ux/mockups/fresh__none__reference.svg b/docs/ux/mockups/fresh__none__reference.svg new file mode 100644 index 0000000000..0492aa6de0 --- /dev/null +++ b/docs/ux/mockups/fresh__none__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CHelixPlaneShift+PAxisShift+ANothing selected · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_2ent.svg b/docs/ux/mockups/fresh__sk_2ent.svg new file mode 100644 index 0000000000..dd02122149 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_2ent.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetTwo sketch entities selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_2ent__create.svg b/docs/ux/mockups/fresh__sk_2ent__create.svg new file mode 100644 index 0000000000..98e984bff2 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_2ent__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Two sketch entities · Create \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_2ent__dressup.svg b/docs/ux/mockups/fresh__sk_2ent__dressup.svg new file mode 100644 index 0000000000..926594bb86 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_2ent__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetDress-up — pick oneFresh document · 8 slotsFilletFChamferHTwo sketch entities · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_2ent__modify.svg b/docs/ux/mockups/fresh__sk_2ent__modify.svg new file mode 100644 index 0000000000..242332967e --- /dev/null +++ b/docs/ux/mockups/fresh__sk_2ent__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXTwo sketch entities · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_2ent__reference.svg b/docs/ux/mockups/fresh__sk_2ent__reference.svg new file mode 100644 index 0000000000..aa105c3a9e --- /dev/null +++ b/docs/ux/mockups/fresh__sk_2ent__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKTwo sketch entities · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_arc.svg b/docs/ux/mockups/fresh__sk_arc.svg new file mode 100644 index 0000000000..0712508411 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_arc.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetSketch arc or circle selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_arc__create.svg b/docs/ux/mockups/fresh__sk_arc__create.svg new file mode 100644 index 0000000000..d22d916e60 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_arc__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch arc or circle · Create \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_arc__modify.svg b/docs/ux/mockups/fresh__sk_arc__modify.svg new file mode 100644 index 0000000000..cf3fc2450f --- /dev/null +++ b/docs/ux/mockups/fresh__sk_arc__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXSketch arc or circle · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_arc__reference.svg b/docs/ux/mockups/fresh__sk_arc__reference.svg new file mode 100644 index 0000000000..cfbe0a1042 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_arc__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKSketch arc or circle · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_line.svg b/docs/ux/mockups/fresh__sk_line.svg new file mode 100644 index 0000000000..e40d823e13 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_line.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetSketch line selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_line__create.svg b/docs/ux/mockups/fresh__sk_line__create.svg new file mode 100644 index 0000000000..1a6f7b561c --- /dev/null +++ b/docs/ux/mockups/fresh__sk_line__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch line · Create \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_line__dressup.svg b/docs/ux/mockups/fresh__sk_line__dressup.svg new file mode 100644 index 0000000000..3fce662ba1 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_line__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetDress-up — pick oneFresh document · 8 slotsFilletFChamferHSketch line · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_line__modify.svg b/docs/ux/mockups/fresh__sk_line__modify.svg new file mode 100644 index 0000000000..26318535ef --- /dev/null +++ b/docs/ux/mockups/fresh__sk_line__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXSketch line · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_line__reference.svg b/docs/ux/mockups/fresh__sk_line__reference.svg new file mode 100644 index 0000000000..2abc91fc99 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_line__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKSketch line · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_loop.svg b/docs/ux/mockups/fresh__sk_loop.svg new file mode 100644 index 0000000000..58eaa9e4fb --- /dev/null +++ b/docs/ux/mockups/fresh__sk_loop.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetClosed sketch loop selected — pick what to do with itFresh document · 8 slotsAdd material5Modify2Closed sketch loop \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_loop__add.svg b/docs/ux/mockups/fresh__sk_loop__add.svg new file mode 100644 index 0000000000..c6e6c90701 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_loop__add.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetAdd material — pick oneFresh document · 8 slotsExtrudeShift+ERevolveShift+RSurface ExtrudeShift+GSurface RevolveSurface FillClosed sketch loop · Add material \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_loop__modify.svg b/docs/ux/mockups/fresh__sk_loop__modify.svg new file mode 100644 index 0000000000..416e62d7cd --- /dev/null +++ b/docs/ux/mockups/fresh__sk_loop__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditClosed sketch loop · Modify \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_none.svg b/docs/ux/mockups/fresh__sk_none.svg new file mode 100644 index 0000000000..ce7604c47d --- /dev/null +++ b/docs/ux/mockups/fresh__sk_none.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetSketch, nothing picked selected — pick what to do with itFresh document · 8 slotsCreate9Reference2Sketch, nothing picked \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_none__create.svg b/docs/ux/mockups/fresh__sk_none__create.svg new file mode 100644 index 0000000000..06994f9517 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_none__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_none__reference.svg b/docs/ux/mockups/fresh__sk_none__reference.svg new file mode 100644 index 0000000000..e4e558bbd9 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_none__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsDimensionDConstructionQSketch, nothing picked · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_point.svg b/docs/ux/mockups/fresh__sk_point.svg new file mode 100644 index 0000000000..65acf94ac7 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_point.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetSketch point selected — pick what to do with itFresh document · 8 slotsCreate9MoveReference2DeleteDelSketch point \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_point__create.svg b/docs/ux/mockups/fresh__sk_point__create.svg new file mode 100644 index 0000000000..fbe094d147 --- /dev/null +++ b/docs/ux/mockups/fresh__sk_point__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch point · Create \ No newline at end of file diff --git a/docs/ux/mockups/fresh__sk_point__reference.svg b/docs/ux/mockups/fresh__sk_point__reference.svg new file mode 100644 index 0000000000..8b02eba29f --- /dev/null +++ b/docs/ux/mockups/fresh__sk_point__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsDimensionDConstrainKSketch point · Reference \ No newline at end of file diff --git a/docs/ux/mockups/fresh__vertex.svg b/docs/ux/mockups/fresh__vertex.svg new file mode 100644 index 0000000000..1e1661d6aa --- /dev/null +++ b/docs/ux/mockups/fresh__vertex.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetVertex selected — pick what to do with itFresh document · 8 slotsReference4Vertex \ No newline at end of file diff --git a/docs/ux/mockups/fresh__vertex__reference.svg b/docs/ux/mockups/fresh__vertex__reference.svg new file mode 100644 index 0000000000..aad3d46b6e --- /dev/null +++ b/docs/ux/mockups/fresh__vertex__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+AVertex · Reference \ No newline at end of file diff --git a/docs/ux/mockups/gen_offer_mockups.py b/docs/ux/mockups/gen_offer_mockups.py new file mode 100644 index 0000000000..b2379df846 --- /dev/null +++ b/docs/ux/mockups/gen_offer_mockups.py @@ -0,0 +1,736 @@ +#!/usr/bin/env python3 +"""Render the object-driven tool offer from docs/ux/tool_atlas.json. + +Fork-neutral on purpose: this file and everything it emits name no product, so the +two forks carry byte-identical copies (the charter itself is the only doc that +substitutes the product name). + +Every mockup in docs/ux/mockups/ and the review page docs/ux/offer_atlas.html are +generated by this script. Nothing is hand-drawn: the point of the offer is that a +tool's address never changes, and a human drawing 40-odd states by hand is exactly +how an address quietly changes. + + python3 docs/ux/mockups/gen_offer_mockups.py + +It fails loudly rather than rendering a broken map: an unknown slot, an unknown +selection id in `accepts`, or one address holding two different verbs for the same +selection is an error, not a warning. + +SVG on purpose. There is no rsvg/inkscape/cairosvg on the build box and +ImageMagick would rasterise through its own weak internal renderer; SVG renders +exactly in a browser at any zoom and stays diffable in git. Rasterise later if +slides need it. +""" + +import json +import re +import math +import os +import sys +from collections import defaultdict + +HERE = os.path.dirname(os.path.abspath(__file__)) +UX = os.path.dirname(HERE) +ATLAS = os.path.join(UX, "tool_atlas.json") + +# The reach target from the charter (L11 / 6.1): if the ring plus a real part do not +# fit here, the design has failed before it is built. +W, H = 1366, 768 + +C = { + "app": "#1a1d21", "chrome": "#23272d", "panel": "#20242a", "line": "#31363d", + "vp0": "#2f353d", "vp1": "#242930", "grid": "#333a43", + "text": "#e7ecf1", "muted": "#8e9aa7", "dim": "#5f6a76", + "top": "#93a1b1", "left": "#6f7b89", "right": "#5a6472", "edge": "#39414b", + "hi": "#f5a623", "hi_soft": "#f5a62333", "sheet": "#7fa8c9", + "ring": "#171a1e", "chip": "#2e343c", "chip_line": "#3c444e", + "key": "#454f5b", "accent": "#4f9bd9", "empty": "#2a2f36", +} + + +# ---------------------------------------------------------------- glyphs +# Each glyph draws inside a 24x24 box centred on (0,0) — i.e. -12..12. +def _g(body): + return body + + +GLYPHS = { + # model + "sketch": '', + "extrude": '', + "revolve": '', + "sweep": '', + "loft": '', + "thicken": '', + "rib": '', + "boolean": '', + "hole": '', + "thread": '', + "shell": '', + "cut": '', + "split": '', + "fillet": '', + "chamfer": '', + "draft": '', + "surf_off": '', + "pattern": '', + "mirror": '', + "pat_curve": '', + "move": '', + "mate": '', + "align": '', + "plane": '', + "axis": '', + "csys": '', + "helix": '', + "project": '', + "measure": '', + "mass": '', + "interfere": '', + "edit": '', + "del_face": '', + "colour": '', + "delete": '', + # sketch primitives + "sk_line": '', + "sk_rect": '', + "sk_circle": '', + "sk_arc": '', + "sk_slot": '', + "sk_ell": '', + "sk_spline": '', + "sk_poly": '', + "sk_point": '', + "sk_offset": '', + "sk_trim": '', + "sk_ext": '', + "sk_mir": '', + "sk_move": '', + "sk_dim": '', + "sk_lock": '', + "sk_constr": '', + # families (used when a slot holds more than one verb) + "fam_create": '', + "fam_add": '', + "fam_remove": '', + "fam_dressup": '', + "fam_repeat": '', + "fam_transform": '', + "fam_reference": '', + # Deliberately NOT the bare pencil: create/sketch already owns that shape and the two slots + # are adjacent (N and NW). A pencil over a solid reads as "change the thing that exists". + "fam_modify": '' + '', +} + +VERB_GLYPH = { + "sketch": "sketch", "extrude": "extrude", "revolve": "revolve", "sweep": "sweep", + "loft": "loft", "thicken": "thicken", "rib": "rib", "boolean": "boolean", + "surf_extrude": "extrude", "surf_revolve": "revolve", "surf_loft": "loft", + "surf_fill": "surf_off", "thicken_surf": "thicken", "hole": "hole", "thread": "thread", + "shell": "shell", "cut": "cut", "split": "split", "fillet": "fillet", + "chamfer": "chamfer", "draft": "draft", "surf_offset": "surf_off", + "pattern": "pattern", "mirror": "mirror", "pat_curve": "pat_curve", + "transform": "move", "mate": "mate", "align": "align", "plane": "plane", + "axis": "axis", "coordsys_v": "csys", "helix": "helix", "project": "project", + "measure": "measure", "mass_props": "mass", "interference": "interfere", + "edit_feature": "edit", "delete_face": "del_face", "colour": "colour", "delete": "delete", + "sk_line_t": "sk_line", "sk_rect": "sk_rect", "sk_circle": "sk_circle", + "sk_arc_t": "sk_arc", "sk_slot": "sk_slot", "sk_ellipse": "sk_ell", + "sk_spline": "sk_spline", "sk_polygon": "sk_poly", "sk_point_t": "sk_point", + "sk_offset": "sk_offset", "sk_trim": "sk_trim", "sk_fillet": "fillet", + "sk_chamfer": "chamfer", "sk_mirror": "sk_mir", "sk_move": "sk_move", + "sk_dimension": "sk_dim", "sk_constrain": "sk_lock", "sk_construct": "sk_constr", + "sk_extend": "sk_ext", "sk_delete": "delete", +} + + +def glyph(name, cx, cy, colour, scale=1.0, sw=1.6): + body = GLYPHS.get(name, '') + return (f'{body}') + + +# ---------------------------------------------------------------- iso scene +COS30, SIN30 = math.cos(math.radians(30)), math.sin(math.radians(30)) + + +def iso(x, y, z, ox, oy, s=1.0): + return (ox + (x - y) * COS30 * s, oy + (x + y) * SIN30 * s - z * s) + + +def poly(pts, fill, stroke=None, extra=""): + d = " ".join(f"{x:.1f},{y:.1f}" for x, y in pts) + # Only emit our own stroke-width when the caller has not supplied one: a duplicate + # attribute is last-one-wins in a browser but invalid markup, and it is exactly the + # kind of thing a stricter renderer refuses outright. + if stroke: + st = f' stroke="{stroke}"' + ("" if "stroke-width" in extra else ' stroke-width="1"') + else: + st = ' stroke="none"' + return f'' + + +def box(ox, oy, w=150, d=105, h=52, s=1.0, hi=None): + """Three visible faces of a box. `hi` names the face/edge to highlight.""" + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + top = [P(0, 0, h), P(w, 0, h), P(w, d, h), P(0, d, h)] + left = [P(0, d, h), P(w, d, h), P(w, d, 0), P(0, d, 0)] + right = [P(w, 0, h), P(w, d, h), P(w, d, 0), P(w, 0, 0)] + out = [ + poly(left, C["left"], C["edge"]), + poly(right, C["right"], C["edge"]), + poly(top, C["hi"] if hi == "top" else C["top"], C["edge"]), + ] + if hi == "top": + out.append(poly(top, "none", "#ffd07a", ' stroke-width="2.5"')) + if hi == "front_edge": + a, b = P(0, d, h), P(w, d, h) + out.append(f'') + if hi == "vertex": + v = P(w, d, h) + out.append(f'') + if hi == "whole": + out.append(poly(top, "none", "#ffd07a", ' stroke-width="2.5"')) + out.append(poly(left, "none", "#ffd07a", ' stroke-width="2.5"')) + out.append(poly(right, "none", "#ffd07a", ' stroke-width="2.5"')) + return "".join(out), P + + +def bore(P, cx, cy, h, r=22, s=1.0, hi=False): + """A cylindrical bore through the top face, drawn as ellipse + wall.""" + c = P(cx, cy, h) + rx, ry = r * COS30 * 2 * s, r * SIN30 * 2 * s + col = C["hi"] if hi else "#20252b" + wall = C["hi"] if hi == "wall" else "#3b434d" + return (f'' + f'' + + (f'' if hi else "")), c + + +def scene(kind, ox, oy): + """Return (svg, anchor) for a selection kind. Anchor = where the ring centres.""" + s = 1.0 + if kind == "origin": + # A document with nothing in it: the three origin planes are all there is to click. + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + g = poly([P(-70, -70, 0), P(70, -70, 0), P(70, 70, 0), P(-70, 70, 0)], + "#4f9bd91f", "#4f9bd977", ' stroke-width="1.5" stroke-dasharray="6 4"') + g += poly([P(-70, 0, -70), P(70, 0, -70), P(70, 0, 70), P(-70, 0, 70)], + "#e05c5c14", "#e05c5c66", ' stroke-width="1.5" stroke-dasharray="6 4"') + g += poly([P(0, -70, -70), P(0, 70, -70), P(0, 70, 70), P(0, -70, 70)], + "#5ce07a14", "#5ce07a66", ' stroke-width="1.5" stroke-dasharray="6 4"') + return g, P(0, 0, 0) + if kind == "empty": + g, P = box(ox, oy, s=s) + return g, P(75, 52, 26) + if kind == "box_top": + g, P = box(ox, oy, s=s, hi="top") + return g, P(75, 52, 52) + if kind == "box_whole": + g, P = box(ox, oy, s=s, hi="whole") + return g, P(75, 52, 26) + if kind == "box_edge": + g, P = box(ox, oy, s=s, hi="front_edge") + return g, P(75, 105, 52) + if kind == "box_vertex": + g, P = box(ox, oy, s=s, hi="vertex") + return g, P(150, 105, 52) + if kind in ("box_bore", "box_bore_rim"): + g, P = box(ox, oy, s=s) + b, c = bore(P, 75, 52, 52, hi=("wall" if kind == "box_bore" else True)) + return g + b, c + if kind == "box_fillet_face": + g, P = box(ox, oy, s=s) + a, b = P(0, 0, 52), P(0, 105, 52) + g += (f'') + return g, P(0, 52, 52) + if kind == "sheet": + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + pts = [P(0, 0, 40), P(150, 0, 55), P(150, 105, 30), P(0, 105, 18)] + return (poly(pts, C["sheet"], "#ffd07a", ' stroke-width="2.5" opacity="0.85"'), + P(75, 52, 36)) + if kind == "two_boxes": + g1, P1 = box(ox - 60, oy - 10, w=110, d=80, h=44, hi="whole") + g2, P2 = box(ox + 70, oy + 26, w=95, d=70, h=60, hi="whole") + return g1 + g2, (ox + 42, oy + 6) + if kind == "datum": + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + g, _ = box(ox, oy, s=s) + pts = [P(-25, -25, 70), P(175, -25, 70), P(175, 130, 70), P(-25, 130, 70)] + g += poly(pts, "#4f9bd933", C["hi"], ' stroke-width="2.5" stroke-dasharray="6 4"') + return g, P(75, 52, 70) + if kind == "axis": + g, P = box(ox, oy, s=s) + a, b = P(-30, 52, 52), P(180, 52, 52) + g += (f'') + return g, P(75, 52, 52) + if kind == "csys": + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + g, _ = box(ox, oy, s=s) + o = P(0, 0, 52) + for tgt, col in ((P(60, 0, 52), "#e05c5c"), (P(0, 60, 52), "#5ce07a"), (P(0, 0, 112), "#5c9ce0")): + g += (f'') + g += f'' + return g, o + if kind == "art": + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + g, _ = box(ox, oy, s=s) + c = P(75, 52, 52) + g += (f'' + f'ABC') + return g, c + if kind == "loop": + P = lambda x, y, z: iso(x, y, z, ox, oy, s) + g, _ = box(ox, oy, s=s) + pts = [P(28, 22, 52), P(122, 22, 52), P(122, 83, 52), P(28, 83, 52)] + g += poly(pts, C["hi_soft"], C["hi"], ' stroke-width="3"') + return g, P(75, 52, 52) + # --- sketch mode: flat, camera normal to the plane + gx, gy = ox - 30, oy - 10 + grid = "".join( + f'' + for i in range(11)) + "".join( + f'' + for i in range(16)) + if kind == "sk_empty": + return grid, (gx, gy) + if kind == "sk_line": + return (grid + f'' + f'' + f'', (gx, gy + 10)) + if kind == "sk_arc": + return (grid + f'', (gx, gy)) + if kind == "sk_point": + return (grid + f'', (gx, gy)) + if kind == "sk_two": + return (grid + f'' + f'', (gx, gy + 5)) + return grid, (gx, gy) + + +# ---------------------------------------------------------------- app chrome +def chrome(title, status, mode="model", empty_doc=False): + tabs = ["Prepare", "Preview", "Design"] + g = [f'', + f'' + f'' + f'', + f'', + f''] + x = 24 + for t in tabs: + on = (t == "Design") + g.append(f'{t}') + if on: + g.append(f'') + x += len(t) * 9 + 34 + # toolbar + g.append(f'' + f'') + fams = (["sketch", "extrude", "hole", "fillet", "pattern", "boolean", "plane", "move", "measure"] + if mode == "model" else + ["sk_line", "sk_rect", "sk_circle", "sk_arc", "sk_slot", "sk_spline", "sk_dim", "sk_trim", "sk_lock"]) + for i, gl in enumerate(fams): + cx = 40 + i * 46 + g.append(f'') + g.append(glyph(gl, cx, 68, C["muted"], 0.62, 1.7)) + # left rail + g.append(f'' + f'') + g.append(f'FEATURES') + # A "fresh document" mockup that shows six existing features is a lie, and it is the one + # state the group will look at hardest — it is the first-run picture (B5). + tree = ([] if empty_doc else + [("Sketch1", 0), ("Extrude1", 0), ("Hole1", 1), ("Fillet1", 1), ("Sketch2", 0), ("Extrude2", 0)]) + if empty_doc: + g.append(f'nothing yet') + for i, (n, ind) in enumerate(tree): + yy = 150 + i * 26 + g.append(glyph("sketch" if n.startswith("Sketch") else "extrude", 30 + ind * 14, yy - 4, C["dim"], 0.42, 1.8)) + g.append(f'{n}') + # status bar + g.append(f'' + f'{status}') + g.append(f'{title}') + return "".join(g) + + +# ---------------------------------------------------------------- the ring +def ring(cx, cy, items, capacity, sel_name, radius=134): + """items: dict angle_index -> (glyph, label, key, count) or None for an empty slot.""" + # The scrim is deliberately faint. §4.1: the offer "never blocks the view of what it acts + # on" — at 0.55 the disc swallowed the very face the ring was opened on, which is the rule + # failing in its own mockup. + g = [f'', + f'', + f''] + step = 360.0 / capacity + for i in range(capacity): + ang = math.radians(-90 + i * step) + px, py = cx + radius * math.cos(ang), cy + radius * math.sin(ang) + it = items.get(i) + if not it: + g.append(f'') + continue + gl, label, key, count = it + g.append(f'') + g.append(glyph(gl, px, py - 2, C["text"], 0.92, 1.7)) + g.append(f'{label}') + if key: + kw = 13 + len(key) * 6.6 + g.append(f'' + f'{key}') + if count and count > 1: + g.append(f'' + f'{count}') + # The selection name sits on the LOWER rim of the centre hole, not above it: above, it + # landed on top of the north slot's shortcut chip and hid it. Below, the pick stays + # visible through the hole and the pill is clear of the south chip at cy+104. + w = 13 + len(sel_name) * 6.9 + g.append(f'' + f'{sel_name}') + return "".join(g) + + +# ---------------------------------------------------------------- enumeration +def load(): + with open(ATLAS, encoding="utf-8") as f: + return json.load(f) + + +def validate(A): + slot_ids = {s["id"] for s in A["slots"]} + sel_ids = {s["id"] for s in A["selections"]} + errs = [] + seen = {} + for v in A["verbs"]: + if v["slot"] not in slot_ids: + errs.append(f'{v["id"]}: unknown slot {v["slot"]!r}') + for a in v["accepts"]: + if a not in sel_ids: + errs.append(f'{v["id"]}: accepts unknown selection {a!r}') + if v["id"] in seen: + errs.append(f'{v["id"]}: duplicate verb id') + seen[v["id"]] = v["slot"] + if errs: + sys.exit("tool_atlas.json is inconsistent:\n " + "\n ".join(errs)) + return slot_ids, sel_ids + + +def eligible(A, sel_id, doc): + sel = next(s for s in A["selections"] if s["id"] == sel_id) + out = [] + for v in A["verbs"]: + if v.get("mode", "model") != sel["mode"]: + continue + if sel_id not in v["accepts"]: + continue + n = v.get("needs") or {} + if n.get("bodies", 0) > doc["bodies"]: + continue + if n.get("sketches", 0) > doc["sketches"]: + continue + if n.get("sheet") and not doc["sheet"]: + continue + out.append(v) + return out + + +def by_slot(A, verbs): + order = [s["id"] for s in A["slots"]] + d = defaultdict(list) + for v in verbs: + d[v["slot"]].append(v) + return {k: d[k] for k in order if d[k]} + + +def ring_items(A, grouped): + order = [s["id"] for s in A["slots"]] + slot_label = {s["id"]: s["label"] for s in A["slots"]} + items = {} + for i, sid in enumerate(order): + vs = grouped.get(sid) + if not vs: + continue + if len(vs) == 1: + v = vs[0] + items[i] = (VERB_GLYPH.get(v["id"], "fam_" + sid), v["name"], v.get("key"), 1) + else: + items[i] = ("fam_" + sid, slot_label[sid], None, len(vs)) + return items + + +# ---------------------------------------------------------------- rendering +OVERFLOWS = [] # (selection, doc state, family, verbs that did not fit the sub-ring) + + +def svg_doc(inner): + return (f'{inner}') + + +def render_state(A, sel, doc, capacity=8, secondary=None): + verbs = eligible(A, sel["id"], doc) + grouped = by_slot(A, verbs) + anchor_x, anchor_y = 810, 400 + fresh = doc["bodies"] == 0 and doc["sketches"] == 0 + shape = "origin" if (fresh and sel["shape"] == "empty") else sel["shape"] + art, (ax, ay) = scene(shape, anchor_x - 90, anchor_y - 40) + if secondary: + vs = grouped[secondary] + # A sub-ring ANCHORS ON ITS PARENT'S DIRECTION. Fanning from north instead put Extrude + # at N — Create's address in the primary map — so the second level contradicted the + # first. Anchored, an address is two consistent strokes: Add material is NE, and the + # first verb of Add material is NE again. + base = [s["id"] for s in A["slots"]].index(secondary) + overflow = [] + if len(vs) > capacity: + # Do NOT wrap: (base+i) % capacity would quietly put verb 9 on top of verb 1, which + # is the invariant failing silently — the one outcome worse than an ugly ring. Show + # what fits, mark the rest, and report it. + overflow = vs[capacity - 1:] + vs = vs[:capacity - 1] + items = {(base + i) % capacity: + (VERB_GLYPH.get(v["id"], "fam_" + secondary), v["name"], v.get("key"), 1) + for i, v in enumerate(vs)} + if overflow: + items[(base + capacity - 1) % capacity] = ("fam_" + secondary, "More", None, len(overflow)) + OVERFLOWS.append((sel["name"], doc["id"], secondary, [v["name"] for v in overflow])) + label = next(s["label"] for s in A["slots"] if s["id"] == secondary) + sel_name = f'{sel["name"]} · {label}' + status = f'{label} — pick one' + else: + items = ring_items(A, grouped) + sel_name = sel["name"] + status = ("Click a face or a reference plane, then a tool" + if sel["id"] == "none" else f'{sel["name"]} selected — pick what to do with it') + inner = chrome(f'{doc["name"]} · {capacity} slots', status, sel["mode"], empty_doc=fresh) + inner += art + inner += ring(ax, ay, items, capacity, sel_name) + return svg_doc(inner), verbs, grouped + + +def main(): + A = load() + validate(A) + docs = {d["id"]: d for d in A["doc_states"]} + outdir = HERE + rows, files = [], [] + total_primary = total_secondary = 0 + fill_sum = fill_n = 0 + + for d in A["doc_states"]: + for sel in A["selections"]: + svg, verbs, grouped = render_state(A, sel, d) + name = f'{d["id"]}__{sel["id"]}.svg' + with open(os.path.join(outdir, name), "w", encoding="utf-8") as f: + f.write(svg) + files.append((name, f'{sel["name"]} — {d["name"]}')) + total_primary += 1 + fill_sum += len(grouped) + fill_n += 1 + secondaries = [] + for sid, vs in grouped.items(): + if len(vs) > 1: + s2, _, _ = render_state(A, sel, d, secondary=sid) + n2 = f'{d["id"]}__{sel["id"]}__{sid}.svg' + with open(os.path.join(outdir, n2), "w", encoding="utf-8") as f: + f.write(s2) + label = next(s["label"] for s in A["slots"] if s["id"] == sid) + files.append((n2, f'{sel["name"]} — {label} ring')) + secondaries.append(sid) + total_secondary += 1 + rows.append({ + "doc": d["name"], "sel": sel["name"], "mode": sel["mode"], + "verbs": len(verbs), "slots": len(grouped), + "second": len(secondaries), + "detail": {sid: [v["name"] for v in vs] for sid, vs in grouped.items()}, + }) + + # comparison sheet: 8 vs 12 slots on the same three selections + for cap in (8, 12): + for sid in ("face_planar", "edge_str", "sk_line"): + sel = next(s for s in A["selections"] if s["id"] == sid) + svg, _, _ = render_state(A, sel, docs["rich"], capacity=cap) + n = f'cmp_{cap}__{sid}.svg' + with open(os.path.join(outdir, n), "w", encoding="utf-8") as f: + f.write(svg) + + write_atlas(A, rows, files, total_primary, total_secondary, + fill_sum / max(1, fill_n)) + print(f"{total_primary} primary + {total_secondary} secondary = " + f"{total_primary+total_secondary} offer states rendered") + print(f"mean populated slots per primary ring: {fill_sum/max(1,fill_n):.2f} of 8") + if OVERFLOWS: + seen = {(f, tuple(v)) for _, _, f, v in OVERFLOWS} + print(f"OVERFLOW: {len(OVERFLOWS)} sub-rings did not fit 8 slots — " + f"{len(seen)} distinct case(s):") + for f, v in sorted(seen): + print(f" {f}: {', '.join(v)} pushed behind 'More'") + + +def write_atlas(A, rows, files, n_prim, n_sec, mean_fill): + gui_missing = [v["name"] for v in A["verbs"] if not v.get("gui", True)] + esc = lambda s: (s.replace("&", "&").replace("<", "<").replace(">", ">")) + cards = "".join( + f'
{esc(t)}
{esc(t)}
' + for n, t in files) + cmp8 = "".join(f'
' + f'
8 slots — {s}
' + for s in ("face_planar", "edge_str", "sk_line")) + cmp12 = "".join(f'
' + f'
12 slots — {s}
' + for s in ("face_planar", "edge_str", "sk_line")) + if OVERFLOWS: + cases = sorted({(f, tuple(v)) for _, _, f, v in OVERFLOWS}) + over_html = ("Measured, not predicted: " + "; ".join( + f'the {esc(f)} sub-ring needs {8 + len(v)} addresses, so ' + f'{esc(", ".join(v))} {"is" if len(v) == 1 else "are"} pushed behind a “More” slot' + for f, v in cases) + + ". This is the decision the ring size actually turns on — either a verb moves to " + "another family, or the tail goes to a third level, or the ring is not eight. " + "It affects sketch mode only; every model-mode family fits.") + else: + over_html = "No sub-ring exceeds the ring capacity. Eight slots is sufficient everywhere." + trs = "".join( + f'{esc(r["sel"])}{esc(r["doc"])}{r["verbs"]}' + f'{r["slots"]}/8{r["second"]}' + f'{esc(" · ".join(k + ": " + ", ".join(v) for k, v in r["detail"].items()))}' + for r in rows) + html = f"""Design tab — offer atlas + +
+

The offer — atlas of every state

+

Every state of the object-driven tool offer, generated from + docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that + address is the same in every selection where it appears, and slots that do not apply are drawn + empty rather than compacted.

+
+
{len(A["verbs"])}verbs mapped
+
{len(A["selections"])}selection kinds
+
{n_prim}primary rings
+
{n_sec}secondary rings
+
{n_prim+n_sec}states total
+
{mean_fill:.1f}/8mean slots filled
+
{len(gui_missing)}verbs with no GUI yet
+
+
+
+

Decision 1 — ring capacity

+

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is + the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses + for more verbs at 30° spacing and positions that stop being nameable.

+
{cmp8}
+
{cmp12}
+ +

Decision 2 — one map or one per mode

+

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, + so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode + states below against the model-mode ones — if a verb that exists in both modes ever appears at two + addresses, the shared map has failed and the split map is the answer.

+ +

The matrix — every selection, every document state

+
+ + {trs} +
SelectionDocumentVerbsSlots2nd ringsWhat lands where
+ +

Overflow — the one place eight slots is not enough

+

{over_html}

+ +

Not in the offer

+

{esc(", ".join(A["chrome_only"]["items"]))} — these act on the document, not on a selection, + so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: + {esc(", ".join(gui_missing))}.

+ +

All states

+
{cards}
+
+""" + with open(os.path.join(UX, "offer_atlas.html"), "w", encoding="utf-8") as f: + f.write(html) + + # A second, SELF-CONTAINED copy for review outside the repo: the artifact host blocks + # every external request, so relative would silently show nothing. Curated + # rather than all 113 states — the whole set inlined is 1.5 MB, which is a poor thing to + # send to the low-end machine this design is meant to serve (6.1). + def inline(name): + p = os.path.join(HERE, name) + if not os.path.exists(p): + return "" + s = open(p, encoding="utf-8").read() + return s.replace("{inline(n)}
{esc(t)}
' + for n, t in picks if inline(n)) + head, _, tail = html.partition('

All states

') + # The comparison grids in the head use , which resolves to nothing + # once the page is served on its own. Inline those too rather than shipping empty frames. + head = re.sub(r']*>', + lambda m: inline(m.group(1)), head) + inline_html = head + '

The states

\n
' + figs + '
\n' + with open(os.path.join(UX, "offer_atlas_inline.html"), "w", encoding="utf-8") as f: + f.write(inline_html) + + +if __name__ == "__main__": + main() diff --git a/docs/ux/mockups/rich__art.svg b/docs/ux/mockups/rich__art.svg new file mode 100644 index 0000000000..e835ed1ce0 --- /dev/null +++ b/docs/ux/mockups/rich__art.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Text / imported art selected — pick what to do with itWorking document · 8 slotsABCPatternShift+NMoveShift+YModify2Text / imported art \ No newline at end of file diff --git a/docs/ux/mockups/rich__art__modify.svg b/docs/ux/mockups/rich__art__modify.svg new file mode 100644 index 0000000000..4c8cdef2b5 --- /dev/null +++ b/docs/ux/mockups/rich__art__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsABCDeleteDelEditText / imported art · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__bodies_2.svg b/docs/ux/mockups/rich__bodies_2.svg new file mode 100644 index 0000000000..a977b7f1de --- /dev/null +++ b/docs/ux/mockups/rich__bodies_2.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two bodies selected — pick what to do with itWorking document · 8 slotsCombineShift+BMateReference2DeleteDelTwo bodies \ No newline at end of file diff --git a/docs/ux/mockups/rich__bodies_2__reference.svg b/docs/ux/mockups/rich__bodies_2__reference.svg new file mode 100644 index 0000000000..1bfbac0db0 --- /dev/null +++ b/docs/ux/mockups/rich__bodies_2__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasureInterferenceTwo bodies · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_sheet.svg b/docs/ux/mockups/rich__body_sheet.svg new file mode 100644 index 0000000000..a1cc27808d --- /dev/null +++ b/docs/ux/mockups/rich__body_sheet.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sheet body selected — pick what to do with itWorking document · 8 slotsThicken SurfaceSurface OffsetMoveShift+YMeasureModify3Sheet body \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_sheet__modify.svg b/docs/ux/mockups/rich__body_sheet__modify.svg new file mode 100644 index 0000000000..7ce8dbee54 --- /dev/null +++ b/docs/ux/mockups/rich__body_sheet__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsColourDeleteDelEditSheet body · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_solid.svg b/docs/ux/mockups/rich__body_solid.svg new file mode 100644 index 0000000000..e958532347 --- /dev/null +++ b/docs/ux/mockups/rich__body_solid.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Solid body selected — pick what to do with itWorking document · 8 slotsRemove3Dress-up2Repeat3MoveShift+YReference3Modify3Solid body \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_solid__dressup.svg b/docs/ux/mockups/rich__body_solid__dressup.svg new file mode 100644 index 0000000000..7a9ceed334 --- /dev/null +++ b/docs/ux/mockups/rich__body_solid__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferSolid body · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_solid__modify.svg b/docs/ux/mockups/rich__body_solid__modify.svg new file mode 100644 index 0000000000..7a6340d40f --- /dev/null +++ b/docs/ux/mockups/rich__body_solid__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsColourDeleteDelEditSolid body · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_solid__reference.svg b/docs/ux/mockups/rich__body_solid__reference.svg new file mode 100644 index 0000000000..27639836c6 --- /dev/null +++ b/docs/ux/mockups/rich__body_solid__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMassProjectMeasureSolid body · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_solid__remove.svg b/docs/ux/mockups/rich__body_solid__remove.svg new file mode 100644 index 0000000000..edbddb7115 --- /dev/null +++ b/docs/ux/mockups/rich__body_solid__remove.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsShellShift+KCutShift+XSplitSolid body · Remove \ No newline at end of file diff --git a/docs/ux/mockups/rich__body_solid__repeat.svg b/docs/ux/mockups/rich__body_solid__repeat.svg new file mode 100644 index 0000000000..74dd67c7de --- /dev/null +++ b/docs/ux/mockups/rich__body_solid__repeat.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Repeat — pick oneWorking document · 8 slotsPatternShift+NMirrorShift+ZPattern on CurveSolid body · Repeat \ No newline at end of file diff --git a/docs/ux/mockups/rich__coordsys.svg b/docs/ux/mockups/rich__coordsys.svg new file mode 100644 index 0000000000..8cef106106 --- /dev/null +++ b/docs/ux/mockups/rich__coordsys.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Coordinate system selected — pick what to do with itWorking document · 8 slotsMateModify2Coordinate system \ No newline at end of file diff --git a/docs/ux/mockups/rich__coordsys__modify.svg b/docs/ux/mockups/rich__coordsys__modify.svg new file mode 100644 index 0000000000..92eb28d3dc --- /dev/null +++ b/docs/ux/mockups/rich__coordsys__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditCoordinate system · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__datum_axis.svg b/docs/ux/mockups/rich__datum_axis.svg new file mode 100644 index 0000000000..c9da648ab7 --- /dev/null +++ b/docs/ux/mockups/rich__datum_axis.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum axis selected — pick what to do with itWorking document · 8 slotsModify2Datum axis \ No newline at end of file diff --git a/docs/ux/mockups/rich__datum_axis__modify.svg b/docs/ux/mockups/rich__datum_axis__modify.svg new file mode 100644 index 0000000000..fd0ae80c52 --- /dev/null +++ b/docs/ux/mockups/rich__datum_axis__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditDatum axis · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__datum_plane.svg b/docs/ux/mockups/rich__datum_plane.svg new file mode 100644 index 0000000000..8ef88bd9a3 --- /dev/null +++ b/docs/ux/mockups/rich__datum_plane.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum plane selected — pick what to do with itWorking document · 8 slotsSketchShift+SRemove2MirrorShift+ZReference3Modify2Datum plane \ No newline at end of file diff --git a/docs/ux/mockups/rich__datum_plane__modify.svg b/docs/ux/mockups/rich__datum_plane__modify.svg new file mode 100644 index 0000000000..39e5cad41e --- /dev/null +++ b/docs/ux/mockups/rich__datum_plane__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditDatum plane · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__datum_plane__reference.svg b/docs/ux/mockups/rich__datum_plane__reference.svg new file mode 100644 index 0000000000..bae3119b6b --- /dev/null +++ b/docs/ux/mockups/rich__datum_plane__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsProjectPlaneShift+PHelixDatum plane · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__datum_plane__remove.svg b/docs/ux/mockups/rich__datum_plane__remove.svg new file mode 100644 index 0000000000..c98b33ad31 --- /dev/null +++ b/docs/ux/mockups/rich__datum_plane__remove.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsHoleShift+HCutShift+XDatum plane · Remove \ No newline at end of file diff --git a/docs/ux/mockups/rich__edge_circ.svg b/docs/ux/mockups/rich__edge_circ.svg new file mode 100644 index 0000000000..1d07291623 --- /dev/null +++ b/docs/ux/mockups/rich__edge_circ.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Circular edge selected — pick what to do with itWorking document · 8 slotsThreadShift+TDress-up2MeasureCircular edge \ No newline at end of file diff --git a/docs/ux/mockups/rich__edge_circ__dressup.svg b/docs/ux/mockups/rich__edge_circ__dressup.svg new file mode 100644 index 0000000000..b315fc2e22 --- /dev/null +++ b/docs/ux/mockups/rich__edge_circ__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferCircular edge · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/rich__edge_str.svg b/docs/ux/mockups/rich__edge_str.svg new file mode 100644 index 0000000000..2c41ce74fc --- /dev/null +++ b/docs/ux/mockups/rich__edge_str.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/ux/mockups/rich__edge_str__dressup.svg b/docs/ux/mockups/rich__edge_str__dressup.svg new file mode 100644 index 0000000000..8e674c044f --- /dev/null +++ b/docs/ux/mockups/rich__edge_str__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferStraight edge · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/rich__edge_str__reference.svg b/docs/ux/mockups/rich__edge_str__reference.svg new file mode 100644 index 0000000000..bc99ca6a13 --- /dev/null +++ b/docs/ux/mockups/rich__edge_str__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasurePlaneShift+PAxisShift+AStraight edge · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_cyl.svg b/docs/ux/mockups/rich__face_cyl.svg new file mode 100644 index 0000000000..3c2860373f --- /dev/null +++ b/docs/ux/mockups/rich__face_cyl.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Cylindrical face selected — pick what to do with itWorking document · 8 slotsThreadShift+TReference3Modify2Cylindrical face \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_cyl__modify.svg b/docs/ux/mockups/rich__face_cyl__modify.svg new file mode 100644 index 0000000000..9f573682ad --- /dev/null +++ b/docs/ux/mockups/rich__face_cyl__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditCylindrical face · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_cyl__reference.svg b/docs/ux/mockups/rich__face_cyl__reference.svg new file mode 100644 index 0000000000..a62be81de8 --- /dev/null +++ b/docs/ux/mockups/rich__face_cyl__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasureAxisShift+AHelixCylindrical face · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_other.svg b/docs/ux/mockups/rich__face_other.svg new file mode 100644 index 0000000000..e5cff4eee5 --- /dev/null +++ b/docs/ux/mockups/rich__face_other.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Curved face selected — pick what to do with itWorking document · 8 slotsThickenDraftShift+DMeasureModify2Curved face \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_other__modify.svg b/docs/ux/mockups/rich__face_other__modify.svg new file mode 100644 index 0000000000..8b5fcfd63f --- /dev/null +++ b/docs/ux/mockups/rich__face_other__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditCurved face · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar.svg b/docs/ux/mockups/rich__face_planar.svg new file mode 100644 index 0000000000..5a58e2fb72 --- /dev/null +++ b/docs/ux/mockups/rich__face_planar.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar__add.svg b/docs/ux/mockups/rich__face_planar__add.svg new file mode 100644 index 0000000000..82acc85038 --- /dev/null +++ b/docs/ux/mockups/rich__face_planar__add.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar__dressup.svg b/docs/ux/mockups/rich__face_planar__dressup.svg new file mode 100644 index 0000000000..8d32b9f212 --- /dev/null +++ b/docs/ux/mockups/rich__face_planar__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferDraftShift+DPlanar face · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar__modify.svg b/docs/ux/mockups/rich__face_planar__modify.svg new file mode 100644 index 0000000000..bffd218131 --- /dev/null +++ b/docs/ux/mockups/rich__face_planar__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditPlanar face · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar__reference.svg b/docs/ux/mockups/rich__face_planar__reference.svg new file mode 100644 index 0000000000..4682f1e7b1 --- /dev/null +++ b/docs/ux/mockups/rich__face_planar__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CProjectMeasurePlaneShift+PAxisShift+APlanar face · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar__remove.svg b/docs/ux/mockups/rich__face_planar__remove.svg new file mode 100644 index 0000000000..b77a5a0c50 --- /dev/null +++ b/docs/ux/mockups/rich__face_planar__remove.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsHoleShift+HShellShift+KPlanar face · Remove \ No newline at end of file diff --git a/docs/ux/mockups/rich__face_planar__transform.svg b/docs/ux/mockups/rich__face_planar__transform.svg new file mode 100644 index 0000000000..2e27983c8b --- /dev/null +++ b/docs/ux/mockups/rich__face_planar__transform.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Transform — pick oneWorking document · 8 slotsMateAlign toPlanar face · Transform \ No newline at end of file diff --git a/docs/ux/mockups/rich__none.svg b/docs/ux/mockups/rich__none.svg new file mode 100644 index 0000000000..4e8a9dc640 --- /dev/null +++ b/docs/ux/mockups/rich__none.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Click a face or a reference plane, then a toolWorking document · 8 slotsSketchShift+SReference4Nothing selected \ No newline at end of file diff --git a/docs/ux/mockups/rich__none__reference.svg b/docs/ux/mockups/rich__none__reference.svg new file mode 100644 index 0000000000..14c47c4b27 --- /dev/null +++ b/docs/ux/mockups/rich__none__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CHelixPlaneShift+PAxisShift+ANothing selected · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_2ent.svg b/docs/ux/mockups/rich__sk_2ent.svg new file mode 100644 index 0000000000..738b01ecf2 --- /dev/null +++ b/docs/ux/mockups/rich__sk_2ent.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two sketch entities selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_2ent__create.svg b/docs/ux/mockups/rich__sk_2ent__create.svg new file mode 100644 index 0000000000..6d27ffa34a --- /dev/null +++ b/docs/ux/mockups/rich__sk_2ent__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Two sketch entities · Create \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_2ent__dressup.svg b/docs/ux/mockups/rich__sk_2ent__dressup.svg new file mode 100644 index 0000000000..929520b8d2 --- /dev/null +++ b/docs/ux/mockups/rich__sk_2ent__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletFChamferHTwo sketch entities · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_2ent__modify.svg b/docs/ux/mockups/rich__sk_2ent__modify.svg new file mode 100644 index 0000000000..d8be7c2d4f --- /dev/null +++ b/docs/ux/mockups/rich__sk_2ent__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXTwo sketch entities · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_2ent__reference.svg b/docs/ux/mockups/rich__sk_2ent__reference.svg new file mode 100644 index 0000000000..9ffc2592a8 --- /dev/null +++ b/docs/ux/mockups/rich__sk_2ent__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKTwo sketch entities · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_arc.svg b/docs/ux/mockups/rich__sk_arc.svg new file mode 100644 index 0000000000..d470369f1a --- /dev/null +++ b/docs/ux/mockups/rich__sk_arc.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch arc or circle selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_arc__create.svg b/docs/ux/mockups/rich__sk_arc__create.svg new file mode 100644 index 0000000000..1f901596ec --- /dev/null +++ b/docs/ux/mockups/rich__sk_arc__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch arc or circle · Create \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_arc__modify.svg b/docs/ux/mockups/rich__sk_arc__modify.svg new file mode 100644 index 0000000000..52f9d7d3e5 --- /dev/null +++ b/docs/ux/mockups/rich__sk_arc__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXSketch arc or circle · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_arc__reference.svg b/docs/ux/mockups/rich__sk_arc__reference.svg new file mode 100644 index 0000000000..53e949c184 --- /dev/null +++ b/docs/ux/mockups/rich__sk_arc__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKSketch arc or circle · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_line.svg b/docs/ux/mockups/rich__sk_line.svg new file mode 100644 index 0000000000..4ca4000d59 --- /dev/null +++ b/docs/ux/mockups/rich__sk_line.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_line__create.svg b/docs/ux/mockups/rich__sk_line__create.svg new file mode 100644 index 0000000000..c37f2d0e45 --- /dev/null +++ b/docs/ux/mockups/rich__sk_line__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch line · Create \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_line__dressup.svg b/docs/ux/mockups/rich__sk_line__dressup.svg new file mode 100644 index 0000000000..29e86762d2 --- /dev/null +++ b/docs/ux/mockups/rich__sk_line__dressup.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletFChamferHSketch line · Dress-up \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_line__modify.svg b/docs/ux/mockups/rich__sk_line__modify.svg new file mode 100644 index 0000000000..b9775b7d94 --- /dev/null +++ b/docs/ux/mockups/rich__sk_line__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXSketch line · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_line__reference.svg b/docs/ux/mockups/rich__sk_line__reference.svg new file mode 100644 index 0000000000..6eb1ef621f --- /dev/null +++ b/docs/ux/mockups/rich__sk_line__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKSketch line · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_loop.svg b/docs/ux/mockups/rich__sk_loop.svg new file mode 100644 index 0000000000..c07d1c09c3 --- /dev/null +++ b/docs/ux/mockups/rich__sk_loop.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Closed sketch loop selected — pick what to do with itWorking document · 8 slotsAdd material8PatternShift+NModify2Closed sketch loop \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_loop__add.svg b/docs/ux/mockups/rich__sk_loop__add.svg new file mode 100644 index 0000000000..bf9f429b81 --- /dev/null +++ b/docs/ux/mockups/rich__sk_loop__add.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsSurface FillExtrudeShift+ERevolveShift+RSweepShift+WLoftShift+LSurface ExtrudeShift+GSurface RevolveSurface LoftClosed sketch loop · Add material \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_loop__modify.svg b/docs/ux/mockups/rich__sk_loop__modify.svg new file mode 100644 index 0000000000..c466379c9e --- /dev/null +++ b/docs/ux/mockups/rich__sk_loop__modify.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditClosed sketch loop · Modify \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_none.svg b/docs/ux/mockups/rich__sk_none.svg new file mode 100644 index 0000000000..ffe49ab9a0 --- /dev/null +++ b/docs/ux/mockups/rich__sk_none.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked selected — pick what to do with itWorking document · 8 slotsCreate9Reference2Sketch, nothing picked \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_none__create.svg b/docs/ux/mockups/rich__sk_none__create.svg new file mode 100644 index 0000000000..c9a2bc698d --- /dev/null +++ b/docs/ux/mockups/rich__sk_none__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_none__reference.svg b/docs/ux/mockups/rich__sk_none__reference.svg new file mode 100644 index 0000000000..cc9d465fa4 --- /dev/null +++ b/docs/ux/mockups/rich__sk_none__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsDimensionDConstructionQSketch, nothing picked · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_point.svg b/docs/ux/mockups/rich__sk_point.svg new file mode 100644 index 0000000000..f089787bca --- /dev/null +++ b/docs/ux/mockups/rich__sk_point.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch point selected — pick what to do with itWorking document · 8 slotsCreate9MoveReference2DeleteDelSketch point \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_point__create.svg b/docs/ux/mockups/rich__sk_point__create.svg new file mode 100644 index 0000000000..5d2070a6c5 --- /dev/null +++ b/docs/ux/mockups/rich__sk_point__create.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch point · Create \ No newline at end of file diff --git a/docs/ux/mockups/rich__sk_point__reference.svg b/docs/ux/mockups/rich__sk_point__reference.svg new file mode 100644 index 0000000000..e090382a24 --- /dev/null +++ b/docs/ux/mockups/rich__sk_point__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsDimensionDConstrainKSketch point · Reference \ No newline at end of file diff --git a/docs/ux/mockups/rich__vertex.svg b/docs/ux/mockups/rich__vertex.svg new file mode 100644 index 0000000000..f37bbd7d47 --- /dev/null +++ b/docs/ux/mockups/rich__vertex.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Vertex selected — pick what to do with itWorking document · 8 slotsReference4Vertex \ No newline at end of file diff --git a/docs/ux/mockups/rich__vertex__reference.svg b/docs/ux/mockups/rich__vertex__reference.svg new file mode 100644 index 0000000000..ceabba032e --- /dev/null +++ b/docs/ux/mockups/rich__vertex__reference.svg @@ -0,0 +1 @@ +PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+AVertex · Reference \ No newline at end of file diff --git a/docs/ux/offer_atlas.html b/docs/ux/offer_atlas.html new file mode 100644 index 0000000000..13ef9beac3 --- /dev/null +++ b/docs/ux/offer_atlas.html @@ -0,0 +1,68 @@ +Design tab — offer atlas + +
+

The offer — atlas of every state

+

Every state of the object-driven tool offer, generated from + docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that + address is the same in every selection where it appears, and slots that do not apply are drawn + empty rather than compacted.

+
+
60verbs mapped
+
20selection kinds
+
40primary rings
+
73secondary rings
+
113states total
+
3.5/8mean slots filled
+
6verbs with no GUI yet
+
+
+
+

Decision 1 — ring capacity

+

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is + the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses + for more verbs at 30° spacing and positions that stop being nameable.

+
8 slots — face_planar
8 slots — edge_str
8 slots — sk_line
+
12 slots — face_planar
12 slots — edge_str
12 slots — sk_line
+ +

Decision 2 — one map or one per mode

+

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, + so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode + states below against the model-mode ones — if a verb that exists in both modes ever appears at two + addresses, the shared map has failed and the split map is the answer.

+ +

The matrix — every selection, every document state

+
+ + +
SelectionDocumentVerbsSlots2nd ringsWhat lands where
Nothing selectedWorking document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceWorking document188/86create: Sketch · add: Extrude, Thicken · remove: Hole, Shell · dressup: Fillet, Chamfer, Draft · repeat: Pattern · transform: Mate, Align to · reference: Plane, Axis, Coord Sys, Project, Measure · modify: Edit, Delete Face
Cylindrical faceWorking document63/82remove: Thread · reference: Axis, Helix, Measure · modify: Edit, Delete Face
Curved faceWorking document54/81add: Thicken · dressup: Draft · reference: Measure · modify: Edit, Delete Face
Straight edgeWorking document63/82dressup: Fillet, Chamfer · repeat: Pattern on Curve · reference: Plane, Axis, Measure
Circular edgeWorking document43/81remove: Thread · dressup: Fillet, Chamfer · reference: Measure
VertexWorking document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyWorking document156/85remove: Shell, Cut, Split · dressup: Fillet, Chamfer · repeat: Pattern, Mirror, Pattern on Curve · transform: Move · reference: Project, Measure, Mass · modify: Edit, Colour, Delete
Sheet bodyWorking document75/81add: Thicken Surface · dressup: Surface Offset · transform: Move · reference: Measure · modify: Edit, Colour, Delete
Two bodiesWorking document54/81add: Combine · transform: Mate · reference: Measure, Interference · modify: Delete
Datum planeWorking document95/83create: Sketch · remove: Hole, Cut · repeat: Mirror · reference: Plane, Helix, Project · modify: Edit, Delete
Datum axisWorking document21/81modify: Edit, Delete
Coordinate systemWorking document32/81transform: Mate · modify: Edit, Delete
Text / imported artWorking document43/81repeat: Pattern · transform: Move · modify: Edit, Delete
Closed sketch loopWorking document113/82add: Extrude, Revolve, Sweep, Loft, Surface Extrude, Surface Revolve, Surface Loft, Surface Fill · repeat: Pattern · modify: Edit, Delete
Sketch, nothing pickedWorking document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleWorking document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointWorking document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Nothing selectedFresh document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceFresh document74/81create: Sketch · add: Extrude · reference: Plane, Axis, Coord Sys, Measure · modify: Edit
Cylindrical faceFresh document42/81reference: Axis, Helix, Measure · modify: Edit
Curved faceFresh document22/80reference: Measure · modify: Edit
Straight edgeFresh document31/81reference: Plane, Axis, Measure
Circular edgeFresh document11/80reference: Measure
VertexFresh document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyFresh document32/81reference: Measure · modify: Edit, Delete
Sheet bodyFresh document32/81reference: Measure · modify: Edit, Delete
Two bodiesFresh document22/80reference: Measure · modify: Delete
Datum planeFresh document53/82create: Sketch · reference: Plane, Helix · modify: Edit, Delete
Datum axisFresh document21/81modify: Edit, Delete
Coordinate systemFresh document21/81modify: Edit, Delete
Text / imported artFresh document21/81modify: Edit, Delete
Closed sketch loopFresh document72/82add: Extrude, Revolve, Surface Extrude, Surface Revolve, Surface Fill · modify: Edit, Delete
Sketch, nothing pickedFresh document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleFresh document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointFresh document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
+ +

Overflow — the one place eight slots is not enough

+

Measured, not predicted: the create sub-ring needs 10 addresses, so Polygon, Point are pushed behind a “More” slot. This is the decision the ring size actually turns on — either a verb moves to another family, or the tail goes to a third level, or the ring is not eight. It affects sketch mode only; every model-mode family fits.

+ +

Not in the offer

+

Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, Redo, Variables, Section view, Origin planes, World axes — these act on the document, not on a selection, + so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: + Split, Pattern on Curve, Align to, Measure, Mass, Interference.

+ +

All states

+
Nothing selected — Working document
Nothing selected — Working document
Nothing selected — Reference ring
Nothing selected — Reference ring
Planar face — Working document
Planar face — Working document
Planar face — Add material ring
Planar face — Add material ring
Planar face — Remove ring
Planar face — Remove ring
Planar face — Dress-up ring
Planar face — Dress-up ring
Planar face — Transform ring
Planar face — Transform ring
Planar face — Reference ring
Planar face — Reference ring
Planar face — Modify ring
Planar face — Modify ring
Cylindrical face — Working document
Cylindrical face — Working document
Cylindrical face — Reference ring
Cylindrical face — Reference ring
Cylindrical face — Modify ring
Cylindrical face — Modify ring
Curved face — Working document
Curved face — Working document
Curved face — Modify ring
Curved face — Modify ring
Straight edge — Working document
Straight edge — Working document
Straight edge — Dress-up ring
Straight edge — Dress-up ring
Straight edge — Reference ring
Straight edge — Reference ring
Circular edge — Working document
Circular edge — Working document
Circular edge — Dress-up ring
Circular edge — Dress-up ring
Vertex — Working document
Vertex — Working document
Vertex — Reference ring
Vertex — Reference ring
Solid body — Working document
Solid body — Working document
Solid body — Remove ring
Solid body — Remove ring
Solid body — Dress-up ring
Solid body — Dress-up ring
Solid body — Repeat ring
Solid body — Repeat ring
Solid body — Reference ring
Solid body — Reference ring
Solid body — Modify ring
Solid body — Modify ring
Sheet body — Working document
Sheet body — Working document
Sheet body — Modify ring
Sheet body — Modify ring
Two bodies — Working document
Two bodies — Working document
Two bodies — Reference ring
Two bodies — Reference ring
Datum plane — Working document
Datum plane — Working document
Datum plane — Remove ring
Datum plane — Remove ring
Datum plane — Reference ring
Datum plane — Reference ring
Datum plane — Modify ring
Datum plane — Modify ring
Datum axis — Working document
Datum axis — Working document
Datum axis — Modify ring
Datum axis — Modify ring
Coordinate system — Working document
Coordinate system — Working document
Coordinate system — Modify ring
Coordinate system — Modify ring
Text / imported art — Working document
Text / imported art — Working document
Text / imported art — Modify ring
Text / imported art — Modify ring
Closed sketch loop — Working document
Closed sketch loop — Working document
Closed sketch loop — Add material ring
Closed sketch loop — Add material ring
Closed sketch loop — Modify ring
Closed sketch loop — Modify ring
Sketch, nothing picked — Working document
Sketch, nothing picked — Working document
Sketch, nothing picked — Create ring
Sketch, nothing picked — Create ring
Sketch, nothing picked — Reference ring
Sketch, nothing picked — Reference ring
Sketch line — Working document
Sketch line — Working document
Sketch line — Create ring
Sketch line — Create ring
Sketch line — Dress-up ring
Sketch line — Dress-up ring
Sketch line — Reference ring
Sketch line — Reference ring
Sketch line — Modify ring
Sketch line — Modify ring
Sketch arc or circle — Working document
Sketch arc or circle — Working document
Sketch arc or circle — Create ring
Sketch arc or circle — Create ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Modify ring
Sketch arc or circle — Modify ring
Sketch point — Working document
Sketch point — Working document
Sketch point — Create ring
Sketch point — Create ring
Sketch point — Reference ring
Sketch point — Reference ring
Two sketch entities — Working document
Two sketch entities — Working document
Two sketch entities — Create ring
Two sketch entities — Create ring
Two sketch entities — Dress-up ring
Two sketch entities — Dress-up ring
Two sketch entities — Reference ring
Two sketch entities — Reference ring
Two sketch entities — Modify ring
Two sketch entities — Modify ring
Nothing selected — Fresh document
Nothing selected — Fresh document
Nothing selected — Reference ring
Nothing selected — Reference ring
Planar face — Fresh document
Planar face — Fresh document
Planar face — Reference ring
Planar face — Reference ring
Cylindrical face — Fresh document
Cylindrical face — Fresh document
Cylindrical face — Reference ring
Cylindrical face — Reference ring
Curved face — Fresh document
Curved face — Fresh document
Straight edge — Fresh document
Straight edge — Fresh document
Straight edge — Reference ring
Straight edge — Reference ring
Circular edge — Fresh document
Circular edge — Fresh document
Vertex — Fresh document
Vertex — Fresh document
Vertex — Reference ring
Vertex — Reference ring
Solid body — Fresh document
Solid body — Fresh document
Solid body — Modify ring
Solid body — Modify ring
Sheet body — Fresh document
Sheet body — Fresh document
Sheet body — Modify ring
Sheet body — Modify ring
Two bodies — Fresh document
Two bodies — Fresh document
Datum plane — Fresh document
Datum plane — Fresh document
Datum plane — Reference ring
Datum plane — Reference ring
Datum plane — Modify ring
Datum plane — Modify ring
Datum axis — Fresh document
Datum axis — Fresh document
Datum axis — Modify ring
Datum axis — Modify ring
Coordinate system — Fresh document
Coordinate system — Fresh document
Coordinate system — Modify ring
Coordinate system — Modify ring
Text / imported art — Fresh document
Text / imported art — Fresh document
Text / imported art — Modify ring
Text / imported art — Modify ring
Closed sketch loop — Fresh document
Closed sketch loop — Fresh document
Closed sketch loop — Add material ring
Closed sketch loop — Add material ring
Closed sketch loop — Modify ring
Closed sketch loop — Modify ring
Sketch, nothing picked — Fresh document
Sketch, nothing picked — Fresh document
Sketch, nothing picked — Create ring
Sketch, nothing picked — Create ring
Sketch, nothing picked — Reference ring
Sketch, nothing picked — Reference ring
Sketch line — Fresh document
Sketch line — Fresh document
Sketch line — Create ring
Sketch line — Create ring
Sketch line — Dress-up ring
Sketch line — Dress-up ring
Sketch line — Reference ring
Sketch line — Reference ring
Sketch line — Modify ring
Sketch line — Modify ring
Sketch arc or circle — Fresh document
Sketch arc or circle — Fresh document
Sketch arc or circle — Create ring
Sketch arc or circle — Create ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Modify ring
Sketch arc or circle — Modify ring
Sketch point — Fresh document
Sketch point — Fresh document
Sketch point — Create ring
Sketch point — Create ring
Sketch point — Reference ring
Sketch point — Reference ring
Two sketch entities — Fresh document
Two sketch entities — Fresh document
Two sketch entities — Create ring
Two sketch entities — Create ring
Two sketch entities — Dress-up ring
Two sketch entities — Dress-up ring
Two sketch entities — Reference ring
Two sketch entities — Reference ring
Two sketch entities — Modify ring
Two sketch entities — Modify ring
+
diff --git a/docs/ux/offer_atlas_inline.html b/docs/ux/offer_atlas_inline.html new file mode 100644 index 0000000000..51f7b28f61 --- /dev/null +++ b/docs/ux/offer_atlas_inline.html @@ -0,0 +1,67 @@ +Design tab — offer atlas + +
+

The offer — atlas of every state

+

Every state of the object-driven tool offer, generated from + docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that + address is the same in every selection where it appears, and slots that do not apply are drawn + empty rather than compacted.

+
+
60verbs mapped
+
20selection kinds
+
40primary rings
+
73secondary rings
+
113states total
+
3.5/8mean slots filled
+
6verbs with no GUI yet
+
+
+
+

Decision 1 — ring capacity

+

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is + the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses + for more verbs at 30° spacing and positions that stop being nameable.

+
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
8 slots — face_planar
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge
8 slots — edge_str
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
8 slots — sk_line
+
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
12 slots — face_planar
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 12 slotsDress-up2Pattern on CurveReference3Straight edge
12 slots — edge_str
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
12 slots — sk_line
+ +

Decision 2 — one map or one per mode

+

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, + so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode + states below against the model-mode ones — if a verb that exists in both modes ever appears at two + addresses, the shared map has failed and the split map is the answer.

+ +

The matrix — every selection, every document state

+
+ + +
SelectionDocumentVerbsSlots2nd ringsWhat lands where
Nothing selectedWorking document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceWorking document188/86create: Sketch · add: Extrude, Thicken · remove: Hole, Shell · dressup: Fillet, Chamfer, Draft · repeat: Pattern · transform: Mate, Align to · reference: Plane, Axis, Coord Sys, Project, Measure · modify: Edit, Delete Face
Cylindrical faceWorking document63/82remove: Thread · reference: Axis, Helix, Measure · modify: Edit, Delete Face
Curved faceWorking document54/81add: Thicken · dressup: Draft · reference: Measure · modify: Edit, Delete Face
Straight edgeWorking document63/82dressup: Fillet, Chamfer · repeat: Pattern on Curve · reference: Plane, Axis, Measure
Circular edgeWorking document43/81remove: Thread · dressup: Fillet, Chamfer · reference: Measure
VertexWorking document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyWorking document156/85remove: Shell, Cut, Split · dressup: Fillet, Chamfer · repeat: Pattern, Mirror, Pattern on Curve · transform: Move · reference: Project, Measure, Mass · modify: Edit, Colour, Delete
Sheet bodyWorking document75/81add: Thicken Surface · dressup: Surface Offset · transform: Move · reference: Measure · modify: Edit, Colour, Delete
Two bodiesWorking document54/81add: Combine · transform: Mate · reference: Measure, Interference · modify: Delete
Datum planeWorking document95/83create: Sketch · remove: Hole, Cut · repeat: Mirror · reference: Plane, Helix, Project · modify: Edit, Delete
Datum axisWorking document21/81modify: Edit, Delete
Coordinate systemWorking document32/81transform: Mate · modify: Edit, Delete
Text / imported artWorking document43/81repeat: Pattern · transform: Move · modify: Edit, Delete
Closed sketch loopWorking document113/82add: Extrude, Revolve, Sweep, Loft, Surface Extrude, Surface Revolve, Surface Loft, Surface Fill · repeat: Pattern · modify: Edit, Delete
Sketch, nothing pickedWorking document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleWorking document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointWorking document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Nothing selectedFresh document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceFresh document74/81create: Sketch · add: Extrude · reference: Plane, Axis, Coord Sys, Measure · modify: Edit
Cylindrical faceFresh document42/81reference: Axis, Helix, Measure · modify: Edit
Curved faceFresh document22/80reference: Measure · modify: Edit
Straight edgeFresh document31/81reference: Plane, Axis, Measure
Circular edgeFresh document11/80reference: Measure
VertexFresh document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyFresh document32/81reference: Measure · modify: Edit, Delete
Sheet bodyFresh document32/81reference: Measure · modify: Edit, Delete
Two bodiesFresh document22/80reference: Measure · modify: Delete
Datum planeFresh document53/82create: Sketch · reference: Plane, Helix · modify: Edit, Delete
Datum axisFresh document21/81modify: Edit, Delete
Coordinate systemFresh document21/81modify: Edit, Delete
Text / imported artFresh document21/81modify: Edit, Delete
Closed sketch loopFresh document72/82add: Extrude, Revolve, Surface Extrude, Surface Revolve, Surface Fill · modify: Edit, Delete
Sketch, nothing pickedFresh document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleFresh document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointFresh document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
+ +

Overflow — the one place eight slots is not enough

+

Measured, not predicted: the create sub-ring needs 10 addresses, so Polygon, Point are pushed behind a “More” slot. This is the decision the ring size actually turns on — either a verb moves to another family, or the tail goes to a third level, or the ring is not eight. It affects sketch mode only; every model-mode family fits.

+ +

Not in the offer

+

Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, Redo, Variables, Section view, Origin planes, World axes — these act on the document, not on a selection, + so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: + Split, Pattern on Curve, Align to, Measure, Mass, Interference.

+ +

The states

+
PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected
Fresh document, nothing selected — the first-run picture
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Click a face or a reference plane, then a toolWorking document · 8 slotsSketchShift+SReference4Nothing selected
Nothing selected
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
Planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Cylindrical face selected — pick what to do with itWorking document · 8 slotsThreadShift+TReference3Modify2Cylindrical face
Cylindrical face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Curved face selected — pick what to do with itWorking document · 8 slotsThickenDraftShift+DMeasureModify2Curved face
Curved face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge
Straight edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Circular edge selected — pick what to do with itWorking document · 8 slotsThreadShift+TDress-up2MeasureCircular edge
Circular edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Vertex selected — pick what to do with itWorking document · 8 slotsReference4Vertex
Vertex
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Solid body selected — pick what to do with itWorking document · 8 slotsRemove3Dress-up2Repeat3MoveShift+YReference3Modify3Solid body
Solid body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sheet body selected — pick what to do with itWorking document · 8 slotsThicken SurfaceSurface OffsetMoveShift+YMeasureModify3Sheet body
Sheet body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two bodies selected — pick what to do with itWorking document · 8 slotsCombineShift+BMateReference2DeleteDelTwo bodies
Two bodies
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum plane selected — pick what to do with itWorking document · 8 slotsSketchShift+SRemove2MirrorShift+ZReference3Modify2Datum plane
Datum plane
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum axis selected — pick what to do with itWorking document · 8 slotsModify2Datum axis
Datum axis
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Coordinate system selected — pick what to do with itWorking document · 8 slotsMateModify2Coordinate system
Coordinate system
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Text / imported art selected — pick what to do with itWorking document · 8 slotsABCPatternShift+NMoveShift+YModify2Text / imported art
Text / imported art
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Closed sketch loop selected — pick what to do with itWorking document · 8 slotsAdd material8PatternShift+NModify2Closed sketch loop
Closed sketch loop
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked selected — pick what to do with itWorking document · 8 slotsCreate9Reference2Sketch, nothing picked
Sketch, nothing picked
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
Sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch arc or circle selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle
Sketch arc or circle
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch point selected — pick what to do with itWorking document · 8 slotsCreate9MoveReference2DeleteDelSketch point
Sketch point
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two sketch entities selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities
Two sketch entities
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material
Planar face · Add material sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CProjectMeasurePlaneShift+PAxisShift+APlanar face · Reference
Planar face · Reference sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create
Sketch · Create sub-ring (the overflow case)
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsShellShift+KCutShift+XSplitSolid body · Remove
Solid body · Remove sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
8 slots — planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
12 slots — planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
8 slots — sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
12 slots — sketch line
diff --git a/docs/ux/tool_atlas.json b/docs/ux/tool_atlas.json new file mode 100644 index 0000000000..3ede7c175e --- /dev/null +++ b/docs/ux/tool_atlas.json @@ -0,0 +1,220 @@ +{ + "_comment": [ + "Source of truth for the object-driven tool offer (see docs/cad_ux_guidelines.md 4.1).", + "Every verb, the selections it accepts, the document state it needs, and its fixed", + "compass address. Extracted from the code, not from memory:", + " verbs + shortcuts + refusal messages -> src/slic3r/GUI/DesignPanel.cpp (feat_dropdown", + " call sites at 524/662/734/790/874/904, sk_key table at 369-400, m_keys_feature)", + " kernel coverage -> src/libslic3r/CadDocument.hpp (enum CadFeatureType)", + " headless coverage -> src/slic3r/GUI/McpControl.cpp (method == \"...\")", + " selection kinds -> src/slic3r/GUI/DesignCanvas.hpp (the on_*_selected callbacks)", + "gen_offer_mockups.py reads this file; the eventual C++ offer table is generated from it", + "too, so the map exists once." + ], + + "slots": [ + {"id": "create", "pos": "N", "angle": 270, "label": "Create", "why": "makes new geometry from nothing you have yet"}, + {"id": "add", "pos": "NE", "angle": 315, "label": "Add material", "why": "grows solid or sheet material"}, + {"id": "remove", "pos": "E", "angle": 0, "label": "Remove", "why": "takes material away"}, + {"id": "dressup", "pos": "SE", "angle": 45, "label": "Dress-up", "why": "finishes faces and edges without changing the shape's intent"}, + {"id": "repeat", "pos": "S", "angle": 90, "label": "Repeat", "why": "copies what exists"}, + {"id": "transform", "pos": "SW", "angle": 135, "label": "Transform", "why": "moves without changing shape"}, + {"id": "reference", "pos": "W", "angle": 180, "label": "Reference", "why": "makes datums, curves and measurements"}, + {"id": "modify", "pos": "NW", "angle": 225, "label": "Modify", "why": "edits or removes what is already there"} + ], + + "selections": [ + {"id": "none", "name": "Nothing selected", "mode": "model", "shape": "empty"}, + {"id": "face_planar", "name": "Planar face", "mode": "model", "shape": "box_top"}, + {"id": "face_cyl", "name": "Cylindrical face", "mode": "model", "shape": "box_bore"}, + {"id": "face_other", "name": "Curved face", "mode": "model", "shape": "box_fillet_face"}, + {"id": "edge_str", "name": "Straight edge", "mode": "model", "shape": "box_edge"}, + {"id": "edge_circ", "name": "Circular edge", "mode": "model", "shape": "box_bore_rim"}, + {"id": "vertex", "name": "Vertex", "mode": "model", "shape": "box_vertex"}, + {"id": "body_solid", "name": "Solid body", "mode": "model", "shape": "box_whole"}, + {"id": "body_sheet", "name": "Sheet body", "mode": "model", "shape": "sheet"}, + {"id": "bodies_2", "name": "Two bodies", "mode": "model", "shape": "two_boxes"}, + {"id": "datum_plane", "name": "Datum plane", "mode": "model", "shape": "datum"}, + {"id": "datum_axis", "name": "Datum axis", "mode": "model", "shape": "axis"}, + {"id": "coordsys", "name": "Coordinate system", "mode": "model", "shape": "csys"}, + {"id": "art", "name": "Text / imported art","mode": "model", "shape": "art"}, + {"id": "sk_loop", "name": "Closed sketch loop", "mode": "model", "shape": "loop"}, + {"id": "sk_none", "name": "Sketch, nothing picked", "mode": "sketch", "shape": "sk_empty"}, + {"id": "sk_line", "name": "Sketch line", "mode": "sketch", "shape": "sk_line"}, + {"id": "sk_arc", "name": "Sketch arc or circle","mode": "sketch","shape": "sk_arc"}, + {"id": "sk_point", "name": "Sketch point", "mode": "sketch", "shape": "sk_point"}, + {"id": "sk_2ent", "name": "Two sketch entities","mode": "sketch", "shape": "sk_two"} + ], + + "doc_states": [ + {"id": "rich", "name": "Working document", "bodies": 2, "sketches": 2, "sheet": true, + "note": "two solids, two sketches, one sheet body — everything doc-gated is legal"}, + {"id": "fresh", "name": "Fresh document", "bodies": 0, "sketches": 0, "sheet": false, + "note": "nothing built yet — shows how much of the ring is empty on first open"} + ], + + "verbs": [ + {"id": "sketch", "name": "Sketch", "slot": "create", "key": "Shift+S", "feature": "Sketch", "mcp": null, + "accepts": ["face_planar", "datum_plane", "none"], "needs": {}, + "refusal": "Click a face or a reference plane in the viewport, then a sketch tool", "gui": true}, + + {"id": "extrude", "name": "Extrude", "slot": "add", "key": "Shift+E", "feature": "Extrude", "mcp": "extrude", + "accepts": ["sk_loop", "face_planar"], "needs": {}, + "refusal": "Create a sketch, or pick a solid face, first", "gui": true}, + {"id": "revolve", "name": "Revolve", "slot": "add", "key": "Shift+R", "feature": "Revolve", "mcp": "revolve", + "accepts": ["sk_loop"], "needs": {}, + "refusal": "Create a sketch profile to revolve first", "gui": true}, + {"id": "sweep", "name": "Sweep", "slot": "add", "key": "Shift+W", "feature": "Sweep", "mcp": null, + "accepts": ["sk_loop"], "needs": {"sketches": 2}, + "refusal": "Create a profile sketch to sweep first", "gui": true}, + {"id": "loft", "name": "Loft", "slot": "add", "key": "Shift+L", "feature": "Loft", "mcp": null, + "accepts": ["sk_loop"], "needs": {"sketches": 2}, + "refusal": "Create at least two profile sketches to loft", "gui": true}, + {"id": "thicken", "name": "Thicken", "slot": "add", "key": null, "feature": "Thicken", "mcp": "thicken", + "accepts": ["face_planar", "face_other"], "needs": {"bodies": 1}, + "refusal": "Thicken needs a solid body — add or import one first", "gui": true}, + {"id": "rib", "name": "Rib", "slot": "add", "key": null, "feature": "Rib", "mcp": "rib", + "accepts": ["sk_line"], "needs": {"bodies": 1}, + "refusal": "Rib needs a solid body — add or import one first", "gui": true}, + {"id": "boolean", "name": "Combine", "slot": "add", "key": "Shift+B", "feature": "Boolean", "mcp": "boolean", + "accepts": ["bodies_2"], "needs": {"bodies": 2}, + "refusal": "Boolean needs two bodies — create or import a second solid", "gui": true}, + {"id": "surf_extrude", "name": "Surface Extrude", "slot": "add", "key": "Shift+G", "feature": "SurfaceExtrude","mcp": "surface_extrude", + "accepts": ["sk_loop"], "needs": {}, "refusal": "Create a sketch first", "gui": true}, + {"id": "surf_revolve", "name": "Surface Revolve", "slot": "add", "key": null, "feature": "SurfaceRevolve","mcp": "surface_revolve", + "accepts": ["sk_loop"], "needs": {}, "refusal": "Create a sketch profile to revolve first", "gui": true}, + {"id": "surf_loft", "name": "Surface Loft", "slot": "add", "key": null, "feature": "SurfaceLoft", "mcp": "surface_loft", + "accepts": ["sk_loop"], "needs": {"sketches": 2}, "refusal": "Create at least two profile sketches to loft", "gui": true}, + {"id": "surf_fill", "name": "Surface Fill", "slot": "add", "key": null, "feature": "SurfaceFill", "mcp": "surface_fill", + "accepts": ["sk_loop"], "needs": {}, "refusal": "Create a closed sketch first", "gui": true}, + {"id": "thicken_surf", "name": "Thicken Surface", "slot": "add", "key": null, "feature": "ThickenSurface","mcp": "thicken_surface", + "accepts": ["body_sheet"], "needs": {"sheet": true}, "refusal": "target is not a sheet body", "gui": true}, + + {"id": "hole", "name": "Hole", "slot": "remove", "key": "Shift+H", "feature": "Hole", "mcp": "hole", + "accepts": ["face_planar", "datum_plane"], "needs": {"bodies": 1}, + "refusal": "Pick a face or a plane to drill into", "gui": true}, + {"id": "thread", "name": "Thread", "slot": "remove", "key": "Shift+T", "feature": "Thread", "mcp": null, + "accepts": ["face_cyl", "edge_circ"], "needs": {"bodies": 1}, + "refusal": "Pick a cylindrical surface (bore / outer) or a circular edge for a thread", "gui": true}, + {"id": "shell", "name": "Shell", "slot": "remove", "key": "Shift+K", "feature": "Shell", "mcp": "shell", + "accepts": ["face_planar", "body_solid"], "needs": {"bodies": 1}, + "refusal": "Shell needs a solid body", "gui": true}, + {"id": "cut", "name": "Cut", "slot": "remove", "key": "Shift+X", "feature": "Cut", "mcp": null, + "accepts": ["body_solid", "datum_plane"], "needs": {"bodies": 1}, + "refusal": "Create a solid body to cut first", "gui": true}, + {"id": "split", "name": "Split", "slot": "remove", "key": null, "feature": "Cut", "mcp": "split", + "accepts": ["body_solid"], "needs": {"bodies": 1}, "refusal": "Split needs a solid body", "gui": false}, + + {"id": "fillet", "name": "Fillet", "slot": "dressup", "key": "Shift+F", "feature": "Fillet", "mcp": "fillet", + "accepts": ["edge_str", "edge_circ", "face_planar", "body_solid"], "needs": {"bodies": 1}, + "refusal": "Pick an edge to round", "gui": true}, + {"id": "chamfer", "name": "Chamfer", "slot": "dressup", "key": null, "feature": "Chamfer", "mcp": "chamfer", + "accepts": ["edge_str", "edge_circ", "face_planar", "body_solid"], "needs": {"bodies": 1}, + "refusal": "Pick an edge to bevel", "gui": true}, + {"id": "draft", "name": "Draft", "slot": "dressup", "key": "Shift+D", "feature": "Draft", "mcp": "draft", + "accepts": ["face_planar", "face_other"], "needs": {"bodies": 1}, + "refusal": "Pick a face to taper", "gui": true}, + {"id": "surf_offset", "name": "Surface Offset", "slot": "dressup", "key": null, "feature": "SurfaceOffset", "mcp": "surface_offset", + "accepts": ["body_sheet"], "needs": {"sheet": true}, "refusal": "target is not a sheet body", "gui": true}, + + {"id": "pattern", "name": "Pattern", "slot": "repeat", "key": "Shift+N", "feature": "Pattern", "mcp": "pattern", + "accepts": ["body_solid", "face_planar", "sk_loop", "art"], "needs": {"bodies": 1}, + "refusal": "Create a solid body to pattern first", "gui": true}, + {"id": "mirror", "name": "Mirror", "slot": "repeat", "key": "Shift+Z", "feature": "Mirror", "mcp": "mirror", + "accepts": ["body_solid", "datum_plane"], "needs": {"bodies": 1}, + "refusal": "Mirror needs a body — add or import one first", "gui": true}, + {"id": "pat_curve", "name": "Pattern on Curve","slot": "repeat", "key": null, "feature": "Pattern", "mcp": "pattern_on_curve", + "accepts": ["body_solid", "edge_str"], "needs": {"bodies": 1}, + "refusal": "Pattern on curve needs a body and a curve", "gui": false}, + + {"id": "transform", "name": "Move", "slot": "transform", "key": "Shift+Y", "feature": "Transform", "mcp": "transform", + "accepts": ["body_solid", "body_sheet", "art"], "needs": {"bodies": 1}, + "refusal": "Transform needs a body — add or import one first", "gui": true}, + {"id": "mate", "name": "Mate", "slot": "transform", "key": null, "feature": "Mate", "mcp": "mate", + "accepts": ["coordsys", "bodies_2", "face_planar"], "needs": {"bodies": 2}, + "refusal": "A mate needs two coordinate systems", "gui": true}, + {"id": "align", "name": "Align to", "slot": "transform", "key": null, "feature": "Transform", "mcp": "transform", + "accepts": ["face_planar"], "needs": {"bodies": 1}, "refusal": "Align needs a body", "gui": false}, + + {"id": "plane", "name": "Plane", "slot": "reference", "key": "Shift+P", "feature": "Plane", "mcp": null, + "accepts": ["none", "face_planar", "edge_str", "datum_plane", "vertex"], "needs": {}, + "refusal": null, "gui": true}, + {"id": "axis", "name": "Axis", "slot": "reference", "key": "Shift+A", "feature": "Axis", "mcp": "axis", + "accepts": ["none", "face_planar", "face_cyl", "edge_str", "vertex"], "needs": {}, + "refusal": null, "gui": true}, + {"id": "coordsys_v", "name": "Coord Sys", "slot": "reference", "key": "Shift+C", "feature": "CoordSys", "mcp": "coordsys", + "accepts": ["none", "face_planar", "vertex"], "needs": {}, "refusal": null, "gui": true}, + {"id": "helix", "name": "Helix", "slot": "reference", "key": null, "feature": "Helix", "mcp": "helix", + "accepts": ["none", "datum_plane", "face_cyl"], "needs": {}, "refusal": null, "gui": true}, + {"id": "project", "name": "Project", "slot": "reference", "key": null, "feature": "Project", "mcp": "project", + "accepts": ["body_solid", "face_planar", "datum_plane"], "needs": {"bodies": 1}, + "refusal": "Project needs a body — add or import one first", "gui": true}, + {"id": "measure", "name": "Measure", "slot": "reference", "key": null, "feature": null, "mcp": "measure", + "accepts": ["face_planar", "face_cyl", "face_other", "edge_str", "edge_circ", "vertex", "body_solid", "body_sheet", "bodies_2", "sk_line", "sk_arc", "sk_2ent"], + "needs": {}, "refusal": null, "gui": false}, + {"id": "mass_props", "name": "Mass", "slot": "reference", "key": null, "feature": null, "mcp": "mass_properties", + "accepts": ["body_solid"], "needs": {"bodies": 1}, "refusal": null, "gui": false}, + {"id": "interference", "name": "Interference", "slot": "reference", "key": null, "feature": null, "mcp": "check_interference", + "accepts": ["bodies_2"], "needs": {"bodies": 2}, "refusal": null, "gui": false}, + + {"id": "edit_feature", "name": "Edit", "slot": "modify", "key": null, "feature": null, "mcp": "set_feature_expr", + "accepts": ["body_solid", "face_planar", "face_cyl", "face_other", "sk_loop", "art", "datum_plane", "datum_axis", "coordsys", "body_sheet"], + "needs": {}, "refusal": null, "gui": true}, + {"id": "delete_face", "name": "Delete Face", "slot": "modify", "key": null, "feature": "DeleteFace", "mcp": "delete_face", + "accepts": ["face_planar", "face_cyl", "face_other"], "needs": {"bodies": 1}, + "refusal": "Delete Face needs a body — add or import one first", "gui": true}, + {"id": "colour", "name": "Colour", "slot": "modify", "key": null, "feature": null, "mcp": null, + "accepts": ["body_solid", "body_sheet"], "needs": {"bodies": 1}, "refusal": null, "gui": true}, + {"id": "delete", "name": "Delete", "slot": "modify", "key": "Del", "feature": null, "mcp": null, + "accepts": ["body_solid", "body_sheet", "sk_loop", "art", "datum_plane", "datum_axis", "coordsys", "bodies_2", "sk_line", "sk_arc", "sk_point", "sk_2ent"], + "needs": {}, "refusal": null, "gui": true}, + + {"id": "sk_line_t", "name": "Line", "slot": "create", "key": "L", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_rect", "name": "Rectangle", "slot": "create", "key": "R", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_circle", "name": "Circle", "slot": "create", "key": "C", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_arc_t", "name": "Arc", "slot": "create", "key": "A", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_slot", "name": "Slot", "slot": "create", "key": "S", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_ellipse", "name": "Ellipse", "slot": "create", "key": "E", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_spline", "name": "Spline", "slot": "create", "key": "B", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_polygon", "name": "Polygon", "slot": "create", "key": "G", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_point_t", "name": "Point", "slot": "create", "key": "P", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_point", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + + {"id": "sk_offset", "name": "Offset", "slot": "add", "key": "O", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_trim", "name": "Trim", "slot": "remove", "key": "T", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_fillet", "name": "Fillet", "slot": "dressup", "key": "F", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_chamfer", "name": "Chamfer", "slot": "dressup", "key": "H", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_mirror", "name": "Mirror", "slot": "repeat", "key": "M", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_move", "name": "Move", "slot": "transform", "key": null, "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_point", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_dimension", "name": "Dimension", "slot": "reference", "key": "D", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_line", "sk_arc", "sk_point", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_constrain", "name": "Constrain", "slot": "reference", "key": "K", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_point", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_construct", "name": "Construction", "slot": "reference", "key": "Q", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_none", "sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_extend", "name": "Extend", "slot": "modify", "key": "X", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_2ent"], "needs": {}, "refusal": null, "gui": true}, + {"id": "sk_delete", "name": "Delete", "slot": "modify", "key": "Del", "feature": "Sketch", "mcp": null, "mode": "sketch", + "accepts": ["sk_line", "sk_arc", "sk_point", "sk_2ent"], "needs": {}, "refusal": null, "gui": true} + ], + + "chrome_only": { + "_why": "document-level actions act on the DOCUMENT, not on a selection, so they stay in chrome and never enter the offer (see 4.1)", + "items": ["Import STEP", "Import mesh", "Text", "SVG", "Export STEP", "Commit to Plate", + "Undo", "Redo", "Variables", "Section view", "Origin planes", "World axes"] + } +}