mirror of
https://github.com/cryinkfly/Autodesk-Fusion-360-for-Linux.git
synced 2025-11-01 19:06:08 +01:00
346 lines
21 KiB
Python
346 lines
21 KiB
Python
#!/usr/bin/env python3
|
|
|
|
####################################################################################################
|
|
# Name: Autodesk Fusion 360 - Speechtoolkit (Linux & Windows) #
|
|
# Description: With this file you can controll Autodesk Fusion 360 via voice assistant. #
|
|
# Author: Steve Zabka #
|
|
# Author URI: https://cryinkfly.com #
|
|
# License: MIT #
|
|
# Copyright (c) 2020-2022 #
|
|
# Time/Date: 10:15/09.02.2022 #
|
|
# Version: 0.0.1 #
|
|
####################################################################################################
|
|
|
|
import argparse
|
|
import os
|
|
import queue
|
|
import sounddevice as sd
|
|
import vosk
|
|
import sys
|
|
import json
|
|
import subprocess
|
|
|
|
|
|
q = queue.Queue()
|
|
|
|
def int_or_str(text):
|
|
"""Helper function for argument parsing."""
|
|
try:
|
|
return int(text)
|
|
except ValueError:
|
|
return text
|
|
|
|
def callback(indata, frames, time, status):
|
|
"""This is called (from a separate thread) for each audio block."""
|
|
if status:
|
|
print(status, file=sys.stderr)
|
|
q.put(bytes(indata))
|
|
|
|
parser = argparse.ArgumentParser(add_help=False)
|
|
parser.add_argument(
|
|
'-l', '--list-devices', action='store_true',
|
|
help='show list of audio devices and exit')
|
|
args, remaining = parser.parse_known_args()
|
|
if args.list_devices:
|
|
print(sd.query_devices())
|
|
parser.exit(0)
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
parents=[parser])
|
|
parser.add_argument(
|
|
'-f', '--filename', type=str, metavar='FILENAME',
|
|
help='audio file to store recording to')
|
|
parser.add_argument(
|
|
'-m', '--model', type=str, metavar='MODEL_PATH',
|
|
help='Path to the model')
|
|
parser.add_argument(
|
|
'-d', '--device', type=int_or_str,
|
|
help='input device (numeric ID or substring)')
|
|
parser.add_argument(
|
|
'-r', '--samplerate', type=int, help='sampling rate')
|
|
args = parser.parse_args(remaining)
|
|
|
|
try:
|
|
if args.model is None:
|
|
args.model = "model"
|
|
if not os.path.exists(args.model):
|
|
print ("Please download a model for your language from https://alphacephei.com/vosk/models")
|
|
print ("and unpack as 'model' in the current folder.")
|
|
parser.exit(0)
|
|
if args.samplerate is None:
|
|
device_info = sd.query_devices(args.device, 'input')
|
|
# soundfile expects an int, sounddevice provides a float:
|
|
args.samplerate = int(device_info['default_samplerate'])
|
|
|
|
model = vosk.Model(args.model)
|
|
|
|
if args.filename:
|
|
dump_fn = open(args.filename, "wb")
|
|
else:
|
|
dump_fn = None
|
|
|
|
with sd.RawInputStream(samplerate=args.samplerate, blocksize = 8000, device=args.device, dtype='int16', channels=1, callback=callback):
|
|
print('#' * 80)
|
|
print('Press Ctrl+C to stop the recording')
|
|
print('#' * 80)
|
|
|
|
rec = vosk.KaldiRecognizer(model, args.samplerate)
|
|
while True:
|
|
data = q.get()
|
|
if rec.AcceptWaveform(data):
|
|
|
|
# Get JSON
|
|
vc = json.loads(rec.Result())
|
|
|
|
# Here you get more informations about the shortcut configuration in Autodesk Fusion 360:
|
|
# - https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-F0491540-0324-470A-B651-2238D0EFAC30
|
|
# - https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-E8541F92-A2DA-4CBF-A708-5374679B3F35
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
# Controll Autodesk Fusion 360 via voice assistant - Shortcuts:
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# System Keyboard Shortcuts:
|
|
|
|
if vc['text'] == "fusion new project":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+n"])
|
|
# Command: File > New Design
|
|
if vc['text'] == "fusion open project":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+o"])
|
|
# Command: File > Open
|
|
if vc['text'] == "fusion save project":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+s"])
|
|
# Command: File > Save (Version)
|
|
if vc['text'] == "fusion recovery save project":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+shift+s"])
|
|
# Command: Recovery Save
|
|
if vc['text'] == "fusion new tab":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+tab"])
|
|
# Command: Cycle open document tabs
|
|
if vc['text'] == "fusion refresh data panel":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "F5"])
|
|
# Command: Refresh data panel
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# General Keyboard Shortcuts:
|
|
|
|
if vc['text'] == "fusion four view ports":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+1"])
|
|
# Command: Display 4 viewports
|
|
if vc['text'] == "fusion for view ports":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+1"])
|
|
# Command: Display 4 viewports
|
|
if vc['text'] == "fusion visual style four":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+4"])
|
|
# Command: Visual Styles (Shaded)
|
|
if vc['text'] == "fusion visual style for":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+4"])
|
|
# Command: Visual Styles (Shaded)
|
|
if vc['text'] == "fusion visual style five":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+5"])
|
|
# Command: Visual Styles (Shaded with hidden edges)
|
|
if vc['text'] == "fusion visual style six":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+6"])
|
|
# Command: Visual Styles (Shaded with visible edges only)
|
|
if vc['text'] == "fusion visual style seven":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+7"])
|
|
# Command: Visual Styles (Wireframe)
|
|
if vc['text'] == "fusion visual style eight":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+8"])
|
|
# Command: Visual Styles (Wireframe with hidden edges)
|
|
if vc['text'] == "fusion visual style nine":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+9"])
|
|
# Command: Visual Styles (Wireframe with visible edges only)
|
|
if vc['text'] == "fusion fullscreen":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+shift+f"])
|
|
# Command: Full-screen mode
|
|
if vc['text'] == "fusion view cube":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+v"])
|
|
# Command: Show/hide ViewCube
|
|
if vc['text'] == "fusion view browser":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+b"])
|
|
# Command: Show/hide browser
|
|
if vc['text'] == "fusion view activity":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+a"])
|
|
# Command: Show/hide activity
|
|
if vc['text'] == "fusion view terminal":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+c"])
|
|
# Command: Show/hide text commands (Terminal)
|
|
if vc['text'] == "fusion view toolbar":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+shift+w"])
|
|
# Command: Show/hide toolbar
|
|
if vc['text'] == "fusion view navigation bar":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+n"])
|
|
# Command: Show/hide navigation bar
|
|
if vc['text'] == "fusion view data panel":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+p"])
|
|
# Command: Show/hide data panel
|
|
if vc['text'] == "fusion view reset":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+alt+r"])
|
|
# Command: Reset to default layout
|
|
if vc['text'] == "fusion toolbox":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "s"])
|
|
# Command: Toolbox (Current workspace) | For examble: Design Workspace, Sketch Environment, ...
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Cube Keyboard Shortcuts:
|
|
|
|
if vc['text'] == "fusion cube home":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/cube_view_home.sh"])
|
|
# Command: Switch the view of your model - Home
|
|
if vc['text'] == "fusion cube left":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/cube_view_left.sh"])
|
|
# Command: Switch the view of your model - Left
|
|
if vc['text'] == "fusion cube right":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/cube_view_right.sh"])
|
|
# Command: Switch the view of your model - Right
|
|
if vc['text'] == "fusion cube top":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/cube_view_top.sh"])
|
|
# Command: Switch the view of your model - Top
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Design Workspace Shortcuts:
|
|
|
|
if vc['text'] == "fusion appearance":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "a"])
|
|
# Command: Appearance
|
|
if vc['text'] == "fusion as built joint":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+j"])
|
|
# Command: As-built Joint
|
|
if vc['text'] == "fusion compute all":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+b"])
|
|
# Command: Compute All
|
|
if vc['text'] == "fusion delete":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "Delete"])
|
|
# Command: Delete
|
|
if vc['text'] == "fusion extrude":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "e"])
|
|
# Command: Extrude
|
|
if vc['text'] == "fusion freeform selection":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "2"])
|
|
# Command: Freeform Selection
|
|
if vc['text'] == "fusion hole":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "h"])
|
|
# Command: Hole
|
|
if vc['text'] == "fusion joint":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "j"])
|
|
# Command: Joint
|
|
if vc['text'] == "fusion measure":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "i"])
|
|
# Command: Measure
|
|
if vc['text'] == "fusion model fillet":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "f"])
|
|
# Command: Model Fillet
|
|
if vc['text'] == "fusion move":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "m"])
|
|
# Command: Move
|
|
if vc['text'] == "fusion paint selection":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "3"])
|
|
# Command: Paint Selection
|
|
if vc['text'] == "fusion press pull":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "q"])
|
|
# Command: Press Pull
|
|
if vc['text'] == "fusion scripts and add ins":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+s"])
|
|
# Command: Scripts and Add-ins
|
|
if vc['text'] == "fusion toggle component color cycling":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+n"])
|
|
# Command: Toggle Component Color Cycling
|
|
if vc['text'] == "fusion toggle visibility":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "v"])
|
|
# Command: Toggle Visibility
|
|
if vc['text'] == "fusion window selection":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "1"])
|
|
# Command: Window Selection
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Sketch Environment Shortcuts:
|
|
|
|
if vc['text'] == "fusion two point rectangle":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "r"])
|
|
# Command: 2-point Rectangle
|
|
if vc['text'] == "fusion center diameter circle":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "c"])
|
|
# Command: Center Diameter Circle
|
|
if vc['text'] == "fusion line":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "l"])
|
|
# KeCommand: Line
|
|
if vc['text'] == "fusion normal construction":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "x"])
|
|
# Command: Normal / Construction
|
|
if vc['text'] == "fusion offset":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "o"])
|
|
# Command: Offset
|
|
if vc['text'] == "fusion project":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "p"])
|
|
# Command: Project (New Sketch)
|
|
if vc['text'] == "fusion sketch dimension":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "d"])
|
|
# Command: Sketch Dimension
|
|
if vc['text'] == "fusion trim":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "t"])
|
|
# Command: Trim
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Canvas Selection Shortcuts:
|
|
|
|
if vc['text'] == "fusion copy":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+c"])
|
|
# Command: Copy
|
|
if vc['text'] == "fusion cut":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+x"])
|
|
# Command: Cut
|
|
if vc['text'] == "fusion paste":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+v"])
|
|
# Command: Paste
|
|
if vc['text'] == "fusion redo":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+y"])
|
|
# Command: Redo
|
|
if vc['text'] == "fusion undo":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "ctrl+z"])
|
|
# Command: Undo
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Direct Mesh Editing Shortcuts:
|
|
|
|
if vc['text'] == "fusion expand to face group":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "alt+g"])
|
|
# Command: Expand To Face Group
|
|
if vc['text'] == "fusion expand to connected":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "alt+c"])
|
|
# Command: Expand To Connected
|
|
if vc['text'] == "fusion grow selection":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+up"])
|
|
# Command: Grow Selection
|
|
if vc['text'] == "fusion shrink selection":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "shift+down"])
|
|
# Command: Shrink Selection
|
|
if vc['text'] == "fusion invert":
|
|
subprocess.run(["/home/steve/.config/fusion-360/scripts/speechtoolkit/keypress.sh", "alt+n"])
|
|
# Command: Invert
|
|
|
|
# --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Still in Progress!
|
|
|
|
|
|
|
|
|
|
else:
|
|
print(rec.PartialResult())
|
|
if dump_fn is not None:
|
|
dump_fn.write(data)
|
|
|
|
except KeyboardInterrupt:
|
|
print('\nDone')
|
|
parser.exit(0)
|
|
except Exception as e:
|
|
parser.exit(type(e).__name__ + ': ' + str(e))
|