Loupedeck Plugin Documentation

CadFlow

Hardware-driven AutoCAD workflow for macOS

A middleware plugin that bridges the Loupedeck console with AutoCAD 2027 on macOS — replacing keyboard-heavy command entry with tactile buttons, rotary encoder panning, and a structured 60+ command hierarchy.

macOS (Apple Silicon) .NET 8 C# Loupedeck SDK AutoCAD 2027 AppleScript IPC osascript
60+
CAD Operations
8
Slots per Tool
3
AppleScript modes
60ms
Nudge idle reset

Three-Layer Architecture

Physical input travels through three distinct layers before reaching AutoCAD — from Loupedeck hardware events down to osascript execution.

01
Loupedeck Hardware
Button / Encoder
02
CadFlowPlugin & App
Entry & Lifecycle
03
Action System
CadToolFolder / Icons
04
AcadSend Bridge
AppleScript Builder
05
AutoCAD 2027
osascript execution
1
Plugin Entry & Lifecycle
Registers the assembly with the Loupedeck service. Detects when AutoCAD is the frontmost application.
  • CadFlowPlugin bootstraps logging & resources
  • CadFlowApplication watches bundle ID com.autodesk.autocad2027
  • Auto-activates CadFlow profile on focus
  • PluginLog and PluginResources helpers
2
Action & Adjustment Handlers
Manages the stateful device UI — folders, button grids, and dials — and translates user intent into CAD commands.
  • Hierarchical CadToolFolder groups
  • 8-slot CtxBtn grid per active tool
  • ToolContext state machine tracks active folder
  • Procedural BitmapBuilder pixel-art icons
3
IPC Bridge — AcadSend
Low-level execution engine. Generates AppleScript strings dynamically and fires them via /usr/bin/osascript.
  • Blocking Send() for tool buttons (3000ms timeout)
  • Non-blocking SendAsync() for encoder input
  • Three script templates: Keystroke, KeyCode, Shortcut
  • Writes .scpt temp file, executes, cleans up

Plugin Infrastructure

The three foundational classes that bootstrap and manage the plugin's lifecycle, application detection, and tool state.

CadFlowPlugin
src/CadFlowPlugin.cs
Entry Point
Primary entry point. Inherits the Loupedeck SDK Plugin base class. Registers the assembly with the service and initialises shared utilities in its constructor.
UsesApplicationApiOnly→ false
HasNoApplication→ false
Load() / Unload()→ lifecycle hooks
CadFlowApplication
src/CadFlowApplication.cs
App Detection
Inherits ClientApplication. Provides application-specific awareness so the Loupedeck service can automatically switch to the CadFlow profile when AutoCAD becomes the frontmost window.
GetBundleName()→ com.autodesk.autocad2027
GetProcessName()→ ""
GetApplicationStatus()→ Unknown
ToolContext
src/Context/ToolContext.cs
State Machine
Static state machine. Tracks which CadToolFolder is currently open on the console. Enables the Confirm and Cancel slots to know their context at any time.
ToolContext.Current→ active folder or null
ToolContext.IsActive→ bool
Activate(folder) / Deactivate(folder)→ void
HELPERS   PluginLog — wraps SDK logging with Info / Error / Warn methods.   PluginResources — wraps Assembly.GetManifestResourceStream() for loading embedded SVG icons.

AcadSend

Static utility class that generates AppleScript strings and executes them via /usr/bin/osascript — the gateway from C# into AutoCAD 2027.

1
Command String
Raw CAD cmd
2
Sanitise()
Escape & lowercase
3
Script Template
Keystroke / KeyCode / Shortcut
4
Write .scpt
Temp file via GetTempFileName
5
osascript
/usr/bin/ execution
6
AutoCAD 2027
Keystroke received
Type Signature Description
Blocking Send(string command) Types command + Enter into AutoCAD. Waits up to 3000ms for osascript to exit. Used for all tool folder button presses.
Non-blocking SendAsync(string command) Fires script and returns immediately. Used by NudgeEngine for high-frequency rotary encoder input — prevents UI lag.
Key Codes SendEnter() / SendEscape() / SendTab() Sends raw macOS key codes: Enter=36, Escape=53, Tab=48. Used for slot 7 (Confirm) and slot 6 (Cancel) grid tiles.
Modifier Keys SendShortcut(string key, string modifiers) Sends a keystroke with modifier(s). E.g. Cmd+Z for Undo, Cmd+Shift+Z for Redo.
Mode Toggles SendToggle(string sysVar) ORTHOMODE→Cmd+L   POLARMODE→Cmd+U   OSMODE→F3   AUTOSNAP→Cmd+Shift+T. All work mid-command inside AutoCAD.
Command Sanitisation

Before any command is injected, Sanitise() converts to lowercase, escapes backslashes and double-quotes, and strips newlines — ensuring the string is valid inside an AppleScript keystroke block.

NudgeEngine

Velocity-scaled, non-blocking X/Y viewport panning. Handles high-frequency encoder input with delta accumulation to prevent missed events when osascript is busy.

Velocity Formula
velocity = sign(raw) × (FineScale + TurboCoeff × |raw|^Exponent)
FineScale 0.6 Base movement per encoder tick
TurboCoeff 1.5 Multiplier for fast spin velocity
Exponent 1.65 Non-linear acceleration curve
MaxDelta 12 Hard clamp on raw input diff
IdleResetMs 60ms Gap that wipes stale accumulators
Delta Accumulation Model
1FeedX() / FeedY() called on each encoder tick from the SDK
2Velocity added to _accumX / _accumY float accumulators
3Integer part truncated → drained into _pendingDx / _pendingDy
4TryFire() acquires Interlocked CAS lock and dispatches one osascript call
5Excess deltas accumulate while in-flight; flushed when the process exits
660ms idle gap resets all accumulators so stale values never fire
AutoCAD Pan Command
'_-pan 0,0 {dx},{dy} \n
The leading apostrophe makes _-pan a transparent command — it works inside other active AutoCAD commands without cancelling them. Sent via an inline AppleScript -e flag (no temp .scpt file) for maximum speed.

NudgeXAdjustment and NudgeYAdjustment are two PluginDynamicAdjustment subclasses — one per axis — that forward encoder diffs to NudgeEngine.Instance.FeedX/Y().

Tool Folders & Commands

CAD operations are organized into hierarchical CadToolFolder groups, each exposing an 8-button contextual grid on the Loupedeck device.

8-Slot Button Grid (CtxBtn)
0 Sub-cmd
1 Sub-cmd
2 Sub-cmd
3 Sub-cmd
4 Sub-cmd
5 Sub-cmd
6 ← Cancel
Escape
7 ✓ Enter
Confirm
Slots 0–5: context sub-commands (varies by tool)
Slot 6: Escape / cancel & close folder
Slot 7: Enter / confirm current command
Procedural Icon Engine
Every tile is rendered at runtime using BitmapBuilder.FillRectangle() on a 60-unit virtual canvas. Icons are computed from the tile's label string — no external image assets required.
✓ Confirm ← Cancel ⇥ TAB ⇄ Toggle
Tool Group Hierarchy
CAD Draw
6 tools
Line · Polyline · Circle · Arc · Rectangle · Polygon
Geometry creation. TAB modifiers cycle between angle/length fields. @ operator references previous coordinates.
CAD Modify
9 tools
Move · Copy · Rotate · Scale · Trim · Extend · Fillet · Mirror · Offset
Object transformation. Axis-locking, Fence/Crossing selection modes, copy-mode toggle flags.
CAD Precision
4 tools
DimLinear · DimAligned · DimAngular · Align
Dimensioning and exact placement. Manages complex multi-step command sequences per folder.
CAD Advanced
4 tools
Array (Rect · Polar · Path) · Text · MText
Complex entities requiring multi-parameter strings rather than simple flag options.

Quick Ring & Shortcuts

Context-free actions available regardless of which tool folder is active — Undo/Redo, viewport shortcuts, and mode toggles.

QuickRingFolder
Circular menu providing rapid viewport and drawing operations.
Zoom Extents_zoom e
Zoom Window_zoom w
Zoom Previous_zoom p
Layer Manager_layer
Scale Objects_scale
Regen_regen
Undo / Redo
PluginDynamicCommand implementations. Always available.
Undo
+ Z
Redo
+ + Z
Mode Toggles
Via SendToggle() — work mid-command inside AutoCAD.
ORTHOMODE + L
POLARMODE + U
OSMODE F3
AUTOSNAP + + T

Package & Distribution

Plugin manifest, bundled SVG icons, and the build pipeline for packaging and installing the plugin via the Loupedeck CLI.

LoupedeckPackage.yaml
src/package/metadata/LoupedeckPackage.yaml
PackageName:Loupedeck.MyPlugin
DisplayName:CadFlow
Version:1.0.0
ApplicationTarget:com.autodesk.autocad2027
ProfileScope:Auto-activate on AutoCAD focus
DllName:CadFlow.dll
SVG Action Icons
Embedded in bin/Debug/actionicons/ — loaded via PluginResources, shown in the Loupedeck app UI (not on-device).
Line
Polyline
Circle
Arc
Rect
Polygon
Move
Copy
Rotate
Scale
Trim
Fillet
Offset
Mirror
Array
Dim
Align
Text
Build & Install Pipeline
01
dotnet build
Compiles CadFlow.dll
02
Package
Zip metadata + DLLs + icons + profiles
03
logiplugintool
Loupedeck CLI for install/debug
04
Enable Plugin
Loupedeck app → Marketplace → Local
05
Open AutoCAD
Profile auto-activates on app focus

Glossary

Core terms used throughout the CadFlow codebase and Loupedeck SDK integration.

PluginDynamicFolderLoupedeck SDK base class for folders that populate a button grid dynamically at runtime.
PluginDynamicAdjustmentSDK base class for dial/encoder adjustments. Used for NudgeXAdjustment and NudgeYAdjustment.
ClientApplicationSDK class that links a plugin to a specific macOS app bundle ID, enabling auto-profile switching.
CtxBtnLightweight struct holding Label, Cmd (AutoCAD string or special tag), and IsToggle flag per slot.
ToolContextStatic class tracking which CadToolFolder is open. Enables Confirm/Cancel buttons to know their state.
AcadSendStatic utility that generates and executes AppleScript to inject keystrokes into AutoCAD 2027.
NudgeEngineSingleton handling velocity-scaled encoder input with delta accumulation and async fire-and-forget dispatch.
osascriptmacOS CLI tool that executes AppleScript. CadFlow calls it via System.Diagnostics.Process.
_-panAutoCAD's transparent pan command. The leading apostrophe allows use inside any active command.
BitmapBuilderLoupedeck SDK class for drawing on-device icons. CadFlow uses FillRectangle() exclusively for pixel-art tiles.
logiplugintoolLoupedeck CLI utility for packaging, installing, and debugging local plugins during development.
DefaultProfile20.lp5Pre-configured .lp5 profile bundled with the plugin to map all CadFlow actions on first install.