export type WorkbenchId = | 'Part Design' | 'Part' | 'Sketcher' | 'Draft' | 'BIM' | 'TechDraw' | 'Spreadsheet' | 'Assembly' | 'CAM' | 'FEM' | 'Mesh' | 'Surface' | 'Inspection' export type CommandIntent = 'create' | 'edit' | 'inspect' | 'view' | 'export' export type CommandDefinition = { id: string label: string icon: string shortcut?: string intent: CommandIntent } export type WorkbenchDefinition = { id: WorkbenchId category: 'Modeling' | 'Documentation' | 'Engineering' | 'Utilities' description: string taskTitle: string taskSummary: string objectType: string groups: { label: string; commands: CommandDefinition[] }[] } const command = (id: string, label: string, icon: string, intent: CommandIntent, shortcut?: string): CommandDefinition => ({ id, label, icon, intent, shortcut }) export const workbenchDefinitions: Record = { 'Part Design': { id: 'Part Design', category: 'Modeling', description: 'Feature-based parametric solid modeling', taskTitle: 'Part Design task', taskSummary: 'Create or edit an ordered Body feature.', objectType: 'PartDesign::Feature', groups: [ { label: 'Structure', commands: [command('create-body', 'Create body', 'box', 'create', 'Ctrl+B'), command('create-sketch', 'Create sketch', 'circle-dot', 'create', 'G, N'), command('attach-sketch', 'Attach sketch', 'paperclip', 'edit'), command('edit-sketch', 'Edit sketch', 'pencil', 'edit'), command('shape-binder', 'Shape binder', 'copy', 'create'), command('datum', 'Datum geometry', 'layers', 'create')] }, { label: 'Additive', commands: [command('pad', 'Pad', 'arrow-up', 'create', 'P'), command('revolution', 'Revolution', 'rotate', 'create'), command('additive-loft', 'Additive loft', 'route', 'create'), command('additive-pipe', 'Additive pipe', 'git-branch', 'create'), command('additive-primitive', 'Additive primitive', 'box', 'create')] }, { label: 'Subtractive', commands: [command('pocket', 'Pocket', 'arrow-down', 'create', 'K, P'), command('hole', 'Hole', 'circle-dot', 'create'), command('groove', 'Groove', 'minus', 'create'), command('subtractive-loft', 'Subtractive loft', 'route', 'create'), command('subtractive-pipe', 'Subtractive pipe', 'git-branch', 'create')] }, { label: 'Transformation', commands: [command('mirrored', 'Mirrored', 'flip-horizontal', 'create'), command('linear-pattern', 'Linear pattern', 'repeat', 'create'), command('polar-pattern', 'Polar pattern', 'refresh-cw', 'create'), command('multi-transform', 'Multi-transform', 'shuffle', 'create')] }, { label: 'Dress-up', commands: [command('fillet', 'Fillet', 'corner-down-right', 'create'), command('chamfer', 'Chamfer', 'scissors', 'create'), command('thickness', 'Thickness', 'layers-2', 'create'), command('draft', 'Draft', 'sliders-horizontal', 'create')] }, ], }, Part: { id: 'Part', category: 'Modeling', description: 'Primitives, booleans and solid inspection', taskTitle: 'Part task', taskSummary: 'Build independent solids and boolean results.', objectType: 'Part::Feature', groups: [ { label: 'Primitives', commands: [command('primitive', 'Create primitives', 'box', 'create'), command('helix', 'Create helix', 'route', 'create'), command('prism', 'Create prism', 'triangle', 'create')] }, { label: 'Boolean', commands: [command('union', 'Union', 'plus', 'create'), command('cut', 'Cut', 'minus', 'create'), command('intersection', 'Intersection', 'circle', 'create'), command('compound', 'Compound', 'layers', 'create')] }, { label: 'Modify', commands: [command('fillet-part', 'Fillet', 'corner-down-right', 'create'), command('chamfer-part', 'Chamfer', 'scissors', 'create'), command('check-shape', 'Check geometry', 'circle-check', 'inspect'), command('measure-part', 'Measure', 'ruler', 'inspect')] }, ], }, Sketcher: { id: 'Sketcher', category: 'Modeling', description: 'Constrained 2D geometry and profiles', taskTitle: 'Sketcher task', taskSummary: 'Edit geometry, constraints and solver state.', objectType: 'Sketcher::SketchObject', groups: [ { label: 'Sketch', commands: [command('new-sketch', 'Create sketch', 'file-plus', 'create', 'G, N'), command('edit-sketch-mode', 'Edit sketch', 'pencil', 'edit'), command('close-sketch', 'Close sketch', 'x', 'edit')] }, { label: 'Geometry', commands: [command('line', 'Create polyline', 'minus', 'create', 'G, M'), command('arc', 'Create arc', 'circle', 'create'), command('circle', 'Create circle', 'circle-dot', 'create'), command('rectangle', 'Create rectangle', 'square', 'create'), command('trim', 'Trim geometry', 'scissors', 'edit')] }, { label: 'Constraints', commands: [command('constrain-horizontal', 'Horizontal', 'move-horizontal', 'create'), command('constrain-vertical', 'Vertical', 'move-vertical', 'create'), command('constrain-coincident', 'Coincident', 'circle-dot', 'create'), command('constrain-dimension', 'Constrain dimension', 'ruler', 'create')] }, { label: 'Solver', commands: [command('toggle-auto-constraints', 'Auto constraints', 'wand-sparkles', 'view'), command('toggle-degrees', 'Show degrees of freedom', 'activity', 'view')] }, ], }, Draft: { id: 'Draft', category: 'Modeling', description: '2D drafting, working planes and snaps', taskTitle: 'Draft task', taskSummary: 'Draw and modify planar construction geometry.', objectType: 'Draft::Feature', groups: [ { label: 'Working plane', commands: [command('working-plane', 'Working plane', 'layers', 'view'), command('snap-settings', 'Snap settings', 'magnet', 'view')] }, { label: '2D geometry', commands: [command('draft-line', 'Line', 'minus', 'create'), command('draft-wire', 'Polyline', 'route', 'create'), command('draft-arc', 'Arc', 'circle', 'create'), command('draft-text', 'Text', 'type', 'create')] }, { label: 'Modify', commands: [command('move', 'Move', 'move', 'edit'), command('rotate', 'Rotate', 'rotate', 'edit'), command('offset', 'Offset', 'copy', 'edit'), command('array', 'Array', 'repeat', 'create')] }, ], }, BIM: { id: 'BIM', category: 'Engineering', description: 'Architectural and building information modeling', taskTitle: 'BIM task', taskSummary: 'Coordinate building objects and IFC metadata.', objectType: 'Arch::Component', groups: [{ label: 'Architecture', commands: [command('wall', 'Wall', 'square', 'create'), command('structure', 'Structure', 'box', 'create'), command('window', 'Window', 'panels-top-left', 'create'), command('space', 'Space', 'maximize', 'create')] }, { label: 'Documentation', commands: [command('ifc-export', 'Export IFC', 'upload', 'export'), command('schedule', 'Create schedule', 'table', 'create')] }], }, TechDraw: { id: 'TechDraw', category: 'Documentation', description: 'Production drawings, views and annotations', taskTitle: 'TechDraw task', taskSummary: 'Compose a page from projected views and dimensions.', objectType: 'TechDraw::DrawPage', groups: [{ label: 'Pages', commands: [command('new-page', 'Create page', 'file-plus', 'create'), command('template', 'Page template', 'file-text', 'edit')] }, { label: 'Views', commands: [command('view-part', 'Insert view', 'eye', 'create'), command('section-view', 'Section view', 'scissors', 'create'), command('detail-view', 'Detail view', 'zoom-in', 'create')] }, { label: 'Annotations', commands: [command('dimension', 'Dimension', 'ruler', 'create'), command('datum-symbol', 'Datum symbol', 'crosshair', 'create'), command('annotation', 'Annotation', 'type', 'create')] }], }, Spreadsheet: { id: 'Spreadsheet', category: 'Utilities', description: 'Parameters, expressions and schedules', taskTitle: 'Spreadsheet task', taskSummary: 'Edit cells and bind expressions to model parameters.', objectType: 'Spreadsheet::Sheet', groups: [{ label: 'Cells', commands: [command('new-sheet', 'Create spreadsheet', 'file-plus', 'create'), command('set-alias', 'Set alias', 'tag', 'edit'), command('insert-row', 'Insert row', 'rows-3', 'edit')] }, { label: 'Expressions', commands: [command('expression', 'Expression editor', 'code-2', 'edit'), command('bind-property', 'Bind property', 'link', 'edit')] }, { label: 'Formatting', commands: [command('format-cells', 'Format cells', 'paintbrush', 'edit'), command('freeze', 'Freeze panes', 'pin', 'view')] }], }, Assembly: { id: 'Assembly', category: 'Engineering', description: 'Components, constraints and motion studies', taskTitle: 'Assembly task', taskSummary: 'Arrange components and validate assembly constraints.', objectType: 'Assembly::AssemblyObject', groups: [{ label: 'Components', commands: [command('insert-component', 'Insert component', 'file-plus', 'create'), command('ground-component', 'Ground component', 'anchor', 'edit'), command('explode-view', 'Exploded view', 'split', 'view')] }, { label: 'Constraints', commands: [command('coincident', 'Coincident', 'circle-dot', 'create'), command('concentric', 'Concentric', 'target', 'create'), command('distance', 'Distance', 'ruler', 'create'), command('angle', 'Angle', 'protractor', 'create')] }, { label: 'Analysis', commands: [command('solve-assembly', 'Solve assembly', 'circle-check', 'inspect'), command('interference', 'Interference check', 'triangle-alert', 'inspect')] }], }, CAM: { id: 'CAM', category: 'Engineering', description: 'Manufacturing jobs, toolpaths and simulation', taskTitle: 'CAM task', taskSummary: 'Define a job, generate toolpaths and inspect simulation.', objectType: 'Path::Job', groups: [{ label: 'Job', commands: [command('new-job', 'Create job', 'file-plus', 'create'), command('stock', 'Stock setup', 'box', 'edit'), command('tools', 'Tool controller', 'settings-2', 'edit')] }, { label: 'Toolpath', commands: [command('profile-path', 'Profile', 'route', 'create'), command('pocket-path', 'Pocket', 'arrow-down', 'create'), command('contour-path', 'Contour', 'repeat', 'create')] }, { label: 'Output', commands: [command('simulate', 'Simulate', 'play', 'inspect'), command('post-process', 'Post process', 'download', 'export')] }], }, FEM: { id: 'FEM', category: 'Engineering', description: 'Analysis, materials, meshing and results', taskTitle: 'FEM task', taskSummary: 'Prepare a model, solve it and inspect result fields.', objectType: 'Fem::FemAnalysis', groups: [{ label: 'Analysis', commands: [command('new-analysis', 'Create analysis', 'file-plus', 'create'), command('material', 'Material', 'layers', 'edit'), command('constraint', 'Constraint', 'lock', 'create')] }, { label: 'Mesh', commands: [command('mesh', 'Create mesh', 'grid-3x3', 'create'), command('mesh-check', 'Check mesh', 'circle-check', 'inspect')] }, { label: 'Results', commands: [command('solve', 'Solve', 'play', 'inspect'), command('results', 'Result fields', 'activity', 'inspect'), command('export-results', 'Export results', 'download', 'export')] }], }, Mesh: { id: 'Mesh', category: 'Utilities', description: 'Mesh import, repair and conversion', taskTitle: 'Mesh task', taskSummary: 'Inspect topology and repair imported triangulations.', objectType: 'Mesh::Feature', groups: [{ label: 'Import', commands: [command('mesh-import', 'Import mesh', 'upload', 'create'), command('mesh-export', 'Export mesh', 'download', 'export')] }, { label: 'Repair', commands: [command('analyze-mesh', 'Analyze mesh', 'search', 'inspect'), command('repair-mesh', 'Repair mesh', 'wand-sparkles', 'edit'), command('fill-holes', 'Fill holes', 'circle-dot', 'edit')] }, { label: 'Conversion', commands: [command('shape-from-mesh', 'Shape from mesh', 'box', 'create'), command('mesh-from-shape', 'Mesh from shape', 'triangle', 'create')] }], }, Surface: { id: 'Surface', category: 'Modeling', description: 'Curves, surfaces and surface operations', taskTitle: 'Surface task', taskSummary: 'Create and trim parametric surface geometry.', objectType: 'Part::Feature', groups: [{ label: 'Curves', commands: [command('bspline', 'B-spline', 'spline', 'create'), command('bezier', 'Bezier curve', 'route', 'create'), command('helix-curve', 'Helix', 'rotate', 'create')] }, { label: 'Surfaces', commands: [command('fill-surface', 'Fill', 'square', 'create'), command('loft-surface', 'Loft', 'route', 'create'), command('sweep-surface', 'Sweep', 'git-branch', 'create')] }, { label: 'Modify', commands: [command('trim-surface', 'Trim', 'scissors', 'edit'), command('offset-surface', 'Offset', 'copy', 'edit')] }], }, Inspection: { id: 'Inspection', category: 'Utilities', description: 'Measurements, sections and model validation', taskTitle: 'Inspection task', taskSummary: 'Measure geometry and validate model dependencies.', objectType: 'Part::Feature', groups: [{ label: 'Measure', commands: [command('measure-distance', 'Distance', 'ruler', 'inspect'), command('measure-angle', 'Angle', 'protractor', 'inspect'), command('measure-area', 'Area', 'square', 'inspect')] }, { label: 'Review', commands: [command('section', 'Section', 'scissors', 'inspect'), command('check-dependencies', 'Check dependencies', 'circle-check', 'inspect'), command('report', 'Generate report', 'file-text', 'export')] }], }, } export const pinnedWorkbenches: WorkbenchId[] = ['Part Design', 'Part', 'Sketcher', 'Draft', 'TechDraw', 'Spreadsheet'] export const menuDefinitions = { File: [ { label: 'New document', shortcut: 'Ctrl+N', command: 'new-document' }, { label: 'Open...', shortcut: 'Ctrl+O', command: 'open' }, { label: 'Save', shortcut: 'Ctrl+S', command: 'save' }, { label: 'Save as...', command: 'save-as' }, { label: 'Import...', command: 'import' }, { label: 'Export...', command: 'export' }, { label: 'Close document', shortcut: 'Ctrl+W', command: 'close' }, ], Edit: [{ label: 'Undo', shortcut: 'Ctrl+Z', command: 'undo' }, { label: 'Redo', shortcut: 'Ctrl+Y', command: 'redo' }, { label: 'Cut', shortcut: 'Ctrl+X', command: 'cut' }, { label: 'Copy', shortcut: 'Ctrl+C', command: 'copy' }, { label: 'Paste', shortcut: 'Ctrl+V', command: 'paste' }, { label: 'Preferences', command: 'preferences' }], View: [{ label: 'Standard views', command: 'standard-views' }, { label: 'Axonometric', shortcut: '0', command: 'axonometric' }, { label: 'Fit all', shortcut: 'V, F', command: 'fit-all' }, { label: 'Panels', command: 'panels' }, { label: 'Fullscreen', shortcut: 'F11', command: 'fullscreen' }], Tools: [{ label: 'Customize...', command: 'customize' }, { label: 'Edit parameters...', command: 'parameters' }, { label: 'Dependency graph', command: 'dependency-graph' }, { label: 'Project settings', command: 'project-settings' }], Macro: [{ label: 'Macros...', command: 'macros' }, { label: 'Record macro', command: 'record-macro' }, { label: 'Stop recording', command: 'stop-macro' }, { label: 'Execute macro', command: 'execute-macro' }], Windows: [{ label: 'Tile documents', command: 'tile' }, { label: 'Cascade documents', command: 'cascade' }, { label: 'Next document', shortcut: 'Ctrl+Tab', command: 'next-document' }, { label: 'Close all documents', command: 'close-all' }], Help: [{ label: 'Help contents', shortcut: 'F1', command: 'help' }, { label: 'Keyboard shortcuts', command: 'shortcuts' }, { label: 'Diagnostics', command: 'diagnostics' }, { label: 'About BitBybit CAD', command: 'about' }], } as const export type MenuName = keyof typeof menuDefinitions