From 40e2dd84e6bf651a5f97463b5df39d3b5729eac3 Mon Sep 17 00:00:00 2001 From: InTostor Date: Mon, 6 Jun 2022 17:14:45 +0800 Subject: [PATCH 1/4] started f360 driver development --- .gitignore | 1 + f360-script/External controls/.env | 1 + .../External controls/.vscode/launch.json | 20 ++ .../External controls/.vscode/settings.json | 5 + .../External controls.manifest | 13 ++ .../External controls/External controls.py | 73 +++++++ .../__pycache__/config.cpython-39.pyc | Bin 0 -> 365 bytes .../External controls/commands/__init__.py | 30 +++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 586 bytes .../commands/commandDialog/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 214 bytes .../__pycache__/entry.cpython-39.pyc | Bin 0 -> 3687 bytes .../commands/commandDialog/entry.py | 158 ++++++++++++++ .../commandDialog/resources/16x16.png | Bin 0 -> 415 bytes .../commandDialog/resources/32x32.png | Bin 0 -> 701 bytes .../commandDialog/resources/64x64.png | Bin 0 -> 1077 bytes .../commands/paletteSend/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 212 bytes .../__pycache__/entry.cpython-39.pyc | Bin 0 -> 3541 bytes .../commands/paletteSend/entry.py | 149 ++++++++++++++ .../commands/paletteSend/resources/16x16.png | Bin 0 -> 474 bytes .../commands/paletteSend/resources/32x32.png | Bin 0 -> 1067 bytes .../commands/paletteSend/resources/64x64.png | Bin 0 -> 1972 bytes .../commands/paletteShow/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 212 bytes .../__pycache__/entry.cpython-39.pyc | Bin 0 -> 4580 bytes .../commands/paletteShow/entry.py | 193 ++++++++++++++++++ .../commands/paletteShow/resources/16x16.png | Bin 0 -> 340 bytes .../commands/paletteShow/resources/32x32.png | Bin 0 -> 587 bytes .../commands/paletteShow/resources/64x64.png | Bin 0 -> 1165 bytes .../paletteShow/resources/html/index.html | 39 ++++ .../resources/html/static/palette.js | 48 +++++ f360-script/External controls/config.py | 21 ++ .../__pycache__/joystickapi.cpython-39.pyc | Bin 0 -> 3238 bytes .../lib/__pycache__/logger.cpython-39.pyc | Bin 0 -> 1438 bytes .../lib/fusion360utils/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 263 bytes .../__pycache__/event_utils.cpython-39.pyc | Bin 0 -> 2938 bytes .../__pycache__/general_utils.cpython-39.pyc | Bin 0 -> 1716 bytes .../lib/fusion360utils/event_utils.py | 88 ++++++++ .../lib/fusion360utils/general_utils.py | 64 ++++++ .../External controls/lib/joystickapi.py | 114 +++++++++++ f360-script/External controls/lib/logger.py | 28 +++ img/operating-graph.png | Bin 0 -> 4421966 bytes 44 files changed, 1047 insertions(+) create mode 100644 f360-script/External controls/.env create mode 100644 f360-script/External controls/.vscode/launch.json create mode 100644 f360-script/External controls/.vscode/settings.json create mode 100644 f360-script/External controls/External controls.manifest create mode 100644 f360-script/External controls/External controls.py create mode 100644 f360-script/External controls/__pycache__/config.cpython-39.pyc create mode 100644 f360-script/External controls/commands/__init__.py create mode 100644 f360-script/External controls/commands/__pycache__/__init__.cpython-39.pyc create mode 100644 f360-script/External controls/commands/commandDialog/__init__.py create mode 100644 f360-script/External controls/commands/commandDialog/__pycache__/__init__.cpython-39.pyc create mode 100644 f360-script/External controls/commands/commandDialog/__pycache__/entry.cpython-39.pyc create mode 100644 f360-script/External controls/commands/commandDialog/entry.py create mode 100644 f360-script/External controls/commands/commandDialog/resources/16x16.png create mode 100644 f360-script/External controls/commands/commandDialog/resources/32x32.png create mode 100644 f360-script/External controls/commands/commandDialog/resources/64x64.png create mode 100644 f360-script/External controls/commands/paletteSend/__init__.py create mode 100644 f360-script/External controls/commands/paletteSend/__pycache__/__init__.cpython-39.pyc create mode 100644 f360-script/External controls/commands/paletteSend/__pycache__/entry.cpython-39.pyc create mode 100644 f360-script/External controls/commands/paletteSend/entry.py create mode 100644 f360-script/External controls/commands/paletteSend/resources/16x16.png create mode 100644 f360-script/External controls/commands/paletteSend/resources/32x32.png create mode 100644 f360-script/External controls/commands/paletteSend/resources/64x64.png create mode 100644 f360-script/External controls/commands/paletteShow/__init__.py create mode 100644 f360-script/External controls/commands/paletteShow/__pycache__/__init__.cpython-39.pyc create mode 100644 f360-script/External controls/commands/paletteShow/__pycache__/entry.cpython-39.pyc create mode 100644 f360-script/External controls/commands/paletteShow/entry.py create mode 100644 f360-script/External controls/commands/paletteShow/resources/16x16.png create mode 100644 f360-script/External controls/commands/paletteShow/resources/32x32.png create mode 100644 f360-script/External controls/commands/paletteShow/resources/64x64.png create mode 100644 f360-script/External controls/commands/paletteShow/resources/html/index.html create mode 100644 f360-script/External controls/commands/paletteShow/resources/html/static/palette.js create mode 100644 f360-script/External controls/config.py create mode 100644 f360-script/External controls/lib/__pycache__/joystickapi.cpython-39.pyc create mode 100644 f360-script/External controls/lib/__pycache__/logger.cpython-39.pyc create mode 100644 f360-script/External controls/lib/fusion360utils/__init__.py create mode 100644 f360-script/External controls/lib/fusion360utils/__pycache__/__init__.cpython-39.pyc create mode 100644 f360-script/External controls/lib/fusion360utils/__pycache__/event_utils.cpython-39.pyc create mode 100644 f360-script/External controls/lib/fusion360utils/__pycache__/general_utils.cpython-39.pyc create mode 100644 f360-script/External controls/lib/fusion360utils/event_utils.py create mode 100644 f360-script/External controls/lib/fusion360utils/general_utils.py create mode 100644 f360-script/External controls/lib/joystickapi.py create mode 100644 f360-script/External controls/lib/logger.py create mode 100644 img/operating-graph.png diff --git a/.gitignore b/.gitignore index e43b0f9..c120690 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.vscode/* \ No newline at end of file diff --git a/f360-script/External controls/.env b/f360-script/External controls/.env new file mode 100644 index 0000000..e28bd05 --- /dev/null +++ b/f360-script/External controls/.env @@ -0,0 +1 @@ +PYTHONPATH=C:/Users/gena0/AppData/Local/Autodesk/webdeploy/production/525fe9b2ece26c4d179982b11ecdfb713cb5058f/Api/Python/packages diff --git a/f360-script/External controls/.vscode/launch.json b/f360-script/External controls/.vscode/launch.json new file mode 100644 index 0000000..1c69300 --- /dev/null +++ b/f360-script/External controls/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + "version": "0.2.0", + "configurations": [{ + "name": "Python: Attach", + "type": "python", + "request": "attach", + "pathMappings": [{ + "localRoot": "${workspaceRoot}", + "remoteRoot": "${workspaceRoot}" + }], + "osx": { + "filePath": "${file}" + }, + "windows": { + "filePath": "${file}" + }, + "port": 9000, + "host": "localhost" + }] +} \ No newline at end of file diff --git a/f360-script/External controls/.vscode/settings.json b/f360-script/External controls/.vscode/settings.json new file mode 100644 index 0000000..bae1447 --- /dev/null +++ b/f360-script/External controls/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python.autoComplete.extraPaths": ["C:/Users/gena0/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Python/defs"], + "python.analysis.extraPaths": ["C:/Users/gena0/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Python/defs"], + "python.pythonPath": "C:/Users/gena0/AppData/Local/Autodesk/webdeploy/production/525fe9b2ece26c4d179982b11ecdfb713cb5058f/Python/python.exe" +} \ No newline at end of file diff --git a/f360-script/External controls/External controls.manifest b/f360-script/External controls/External controls.manifest new file mode 100644 index 0000000..377ab05 --- /dev/null +++ b/f360-script/External controls/External controls.manifest @@ -0,0 +1,13 @@ +{ + "autodeskProduct": "Fusion360", + "type": "addin", + "id": "0afdf698-8eed-4eaa-ac5c-d6ae17db8147", + "author": "InTostor", + "description": { + "": "" + }, + "version": "0.1", + "runOnStartup": true, + "supportedOS": "windows|mac", + "editEnabled": true +} \ No newline at end of file diff --git a/f360-script/External controls/External controls.py b/f360-script/External controls/External controls.py new file mode 100644 index 0000000..7ddc4b4 --- /dev/null +++ b/f360-script/External controls/External controls.py @@ -0,0 +1,73 @@ +# started experiments with f360 driver-script + + +# There is a lot of code copied from stackoverflow, autodesk forums, etc. +# windows only yet + + +import adsk.fusion, adsk.core, traceback +import math + +from .lib import joystickapi +from .lib import fusion360utils as futil +import msvcrt +import time +import inspect, os, sys + + + + +def run(context): + + ui = None + app = adsk.core.Application.get() + ui = app.userInterface + ui.messageBox('bruh it started') + + + num = joystickapi.joyGetNumDevs() + ret, caps, startinfo = False, None, None + for id in range(num): + ret, caps = joystickapi.joyGetDevCaps(id) + if ret: + ui.messageBox(str("gamepad detected: " + caps.szPname)) + ret, startinfo = joystickapi.joyGetPosEx(id) + break + else: + ui.messageBox(str("no gamepad detected")) + + + while True: + run = ret + ret, info = joystickapi.joyGetPosEx(id) + if ret: + axisXYZRUV = [info.dwXpos-startinfo.dwXpos, info.dwYpos-startinfo.dwYpos, info.dwZpos-startinfo.dwZpos, + info.dwRpos-startinfo.dwRpos, info.dwUpos-startinfo.dwUpos, info.dwVpos-startinfo.dwVpos] + + futil.log(str(axisXYZRUV)) + + + deg = axisXYZRUV[0]/2000 #Angle of one step - degree + + + + + app: adsk.core.Application = adsk.core.Application.get() + ui = app.userInterface + # viewport + vp: adsk.core.Viewport = app.activeViewport + cam: adsk.core.Camera = vp.camera + vecUp: adsk.core.Vector3D = cam.upVector + target: adsk.core.Point3D = cam.target + # matrix3d + mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() + rad = math.radians(deg) + mat.setToRotation(rad, vecUp, target) + # update camera + cam.isSmoothTransition = False + eye: adsk.core.Point3D = vp.camera.eye + eye.transformBy(mat) + cam.eye = eye + vp.camera = cam + vp.refresh() + adsk.doEvents() diff --git a/f360-script/External controls/__pycache__/config.cpython-39.pyc b/f360-script/External controls/__pycache__/config.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6911d723abc77614040d3b076455a613eec9036a GIT binary patch literal 365 zcmYk2&q@O^5XO`4pRTPv2tGisy|{uPA|l4_Dm`>9Y7d4&NKM+V?rxS%3i=veMX*O- zDOXRvfe3=rJ*WfoGr@2)(b(|MI|`KErg+rUN`HX}seW3T^(m>!V)bl@J8ztA&CH-M+F{5o(@=O{dSt@!PwxP83 zqWE-tZrzfbg$<@$%Yx_9Hbq+1B4BKmW|A@6B2hF*SVACcvwtxhk>sX!bW8KRgqgqa zH&nIZc8#xT|8O$aveMxk!goVbmJv5Ryi`0-i+Mjc(K+MwlPWfnqqg;t)CXd%&rvpIXyZ$zIogY{$Xr=%F literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/__init__.py b/f360-script/External controls/commands/__init__.py new file mode 100644 index 0000000..0499301 --- /dev/null +++ b/f360-script/External controls/commands/__init__.py @@ -0,0 +1,30 @@ +# Here you define the commands that will be added to your add-in. + +# TODO Import the modules corresponding to the commands you created. +# If you want to add an additional command, duplicate one of the existing directories and import it here. +# You need to use aliases (import "entry" as "my_module") assuming you have the default module named "entry". +from .commandDialog import entry as commandDialog +from .paletteShow import entry as paletteShow +from .paletteSend import entry as paletteSend + +# TODO add your imported modules to this list. +# Fusion will automatically call the start() and stop() functions. +commands = [ + commandDialog, + paletteShow, + paletteSend +] + + +# Assumes you defined a "start" function in each of your modules. +# The start function will be run when the add-in is started. +def start(): + for command in commands: + command.start() + + +# Assumes you defined a "stop" function in each of your modules. +# The stop function will be run when the add-in is stopped. +def stop(): + for command in commands: + command.stop() \ No newline at end of file diff --git a/f360-script/External controls/commands/__pycache__/__init__.cpython-39.pyc b/f360-script/External controls/commands/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..923bc4d0fdf42b4035e9ffcdeabf90b2666e17b0 GIT binary patch literal 586 zcmbVJ%}T^D5T5jBTYnb3=*h!gd$EGxK}1}46}*VJcquC-Y(g!zNlmiog5G=rpFofM zO1*mW4MbRQ(p`VfPMFCz(`LRe6WVSs1KP*)j2?LaZ#MaBE+&WQ`UnF9MhYlN0%VRI z#Lfb{h+P64xWnDdO+4l>_X!f8dCbSX#aaW1f_H+AB2xQY7&RGT@?-Xkk@MDLFn}pJi<~+f$+Dz^>Dt$ZDl;W@uqaJIg?Re2?ClLNHCH;$xS-o{ zx2pQo(D*{qG8b9g9UIBGzWD*2ld;aF=1#4&;txd;2EOv^@Qq|#pDcQK-2Udq(!>~$l M`3}J~^OnNk3owm(i~s-t literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/commandDialog/__init__.py b/f360-script/External controls/commands/commandDialog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/f360-script/External controls/commands/commandDialog/__pycache__/__init__.cpython-39.pyc b/f360-script/External controls/commands/commandDialog/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c69504c95b9bbabf280e4970cfcf039fe5aa0213 GIT binary patch literal 214 zcmYe~<>g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=*XRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&{-&Tz?0%*juWiI30B%PfhH*DI*J#bJ}1 QpHiBWY6o)EXCP((0Q$N+r~m)} literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/commandDialog/__pycache__/entry.cpython-39.pyc b/f360-script/External controls/commands/commandDialog/__pycache__/entry.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd81118b85e732ef110382bc107875ce879d058a GIT binary patch literal 3687 zcmaJ@-EZT@5$BQ=MNuD?Wy`+L9Ggp%C`iti21tv;HH~b^h?=u(*q19p93arzwT?Q8 z6qYNWZOA|$@>HNNeJj!fq{sXV{Zsa}Pxl`b1qyU#Nm>3#Dq)Aav&-S`%x``>ezE9i z@cZ}Q{_B5zN7Md=gUi1x48DdIJ4Dl{M#(_)h~*Y5sk>M9V*D-g|VJR^a(SebJ>W{~&agR(~+PUn$M|O0!1S zLG$pE<`%sTnh%ub*J{ljdKWYwD$PeqbC2E!&BvGCdXGK;O^uQRt>(T%FSXwpAZtXH zj>d5igvE&g-1b8l8)zex+i}kA@NKr)GLtz)FX*BbmF{iOh^Jjxw8?|4HNTLsb5Avi0QU zcQNDfMvsO5Ujfe*ohfa56xt;PebSb2tG+ zGysta(8{FHv7nzt=)f8~?Hd!FKb`2)+)N|d#NgjdjHIuCMA|inBZu)SiZvALC~l#+ zjRJU0<3$vC5Ynb>zy#Z2HIqL;tqa0iAR&q21uiidDKM4W6Y&r&nX!mQzk^;}2BGN% zqW*?SY-s!=(EUWD>GNLP1^T@BVS*vCDv$gVIzpQgp#w3JxB860DYd@QH!+!}86;V1 z(hRj`K(oT?XOUdNLrx#4by}q8F9TMVs7-SdePYZ^m6A)!N?9yJ`Z<3!F6map>J430 ztliM9i(5Bzx5b^gPWeCIK3ltBsx+p+xn;WA7 z=O4X8&umNbxy&E?gE8v_;b<(*9QDcz)F8hOqOL!fr*T}n%a`FTX#l12680cB6tBu+ z+G(McSgt`L;&(TrlQbXIgf#roNEZFB2#y(KA02mvER2DF;*=$21>)|H2jUqEd*ao1 zI0d1k@oQ;zBhI9w_Lf*HCG@d*dLTGt9vG%{G0iJ#hwOxP$AT?5CspuAI9*W3-U6cP z0WVe4QzXvlbW?RHePxfcQ*u61Xs+KyCBm&+W|hi9wkKUI3;#U06sJkP|iB zj-|E}^Dl8wOkL3dD`R#o3-~H5`6IL#b5GODhMlPx4k?kcu}YG^T5}}@5dN43Dg|CZ z=l`bwQi4hbLxElITj%D)=x5I})SQ@DSxhoNYH!VROW4!g#KI&}@U$+&vzbI7fhYe2 zzREuXahCrc?m>mdC+=DK=^_70Db#77xWF$6Hok!Z!Nwn>_#6cuS(=Dr>97-sLX2gA z;v?w{VFVX0K(CfnUgg{P&c%26H#lse31b-duKV@(Fu|aujo>GC1mP9PGmNPhs}w zT(8*Nq`>d0Fv?Klb%y^2;7dAIXaRuXIfrc3eUavIdTvFi3alLI^7%F(>gu_Y-77q1 z6mVt9=P3;+W9gyQI?qu{luxh24x{rIXz9&f)-6b8huAvDnJeeUtz4WN@7wF=hEmtjvE48mUJyTn)h?H(->Q z&tVVu%JIIId8m~JLD$D}QyM)c_!p=yj-i}t;RSUB6=0Ia1t{O3!uwv8oSsu}G+J%d zPf7|!2uo=AJ_=QOsHy`~P?{rOypm==3PRxA0IIAZlUe@|DooJZoz77(V4V)f`a#_T zs(ezFgIrH9tn^Y<5U4{bp~zI0)7ga@89^nTtg67Kxw2S*xRvX3WT`drViu#T9D2#^ zDgY1hHT&rhF3AD=3S%CB3c@CKQtlATTqPzk4buV%PuDa}d(Ey??p9VRcEzbI{SWTF Bw(bA` literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/commandDialog/entry.py b/f360-script/External controls/commands/commandDialog/entry.py new file mode 100644 index 0000000..e00314c --- /dev/null +++ b/f360-script/External controls/commands/commandDialog/entry.py @@ -0,0 +1,158 @@ +import adsk.core +import os +from ...lib import fusion360utils as futil +from ... import config +app = adsk.core.Application.get() +ui = app.userInterface + + +# TODO *** Specify the command identity information. *** +CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_cmdDialog' +CMD_NAME = 'Command Dialog Sample' +CMD_Description = 'A Fusion 360 Add-in Command with a dialog' + +# Specify that the command will be promoted to the panel. +IS_PROMOTED = True + +# TODO *** Define the location where the command button will be created. *** +# This is done by specifying the workspace, the tab, and the panel, and the +# command it will be inserted beside. Not providing the command to position it +# will insert it at the end. +WORKSPACE_ID = 'FusionSolidEnvironment' +PANEL_ID = 'SolidScriptsAddinsPanel' +COMMAND_BESIDE_ID = 'ScriptsManagerCommand' + +# Resource location for command icons, here we assume a sub folder in this directory named "resources". +ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '') + +# Local list of event handlers used to maintain a reference so +# they are not released and garbage collected. +local_handlers = [] + + +# Executed when add-in is run. +def start(): + # Create a command Definition. + cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER) + + # Define an event handler for the command created event. It will be called when the button is clicked. + futil.add_handler(cmd_def.commandCreated, command_created) + + # ******** Add a button into the UI so the user can run the command. ******** + # Get the target workspace the button will be created in. + workspace = ui.workspaces.itemById(WORKSPACE_ID) + + # Get the panel the button will be created in. + panel = workspace.toolbarPanels.itemById(PANEL_ID) + + # Create the button command control in the UI after the specified existing command. + control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False) + + # Specify if the command is promoted to the main toolbar. + control.isPromoted = IS_PROMOTED + + +# Executed when add-in is stopped. +def stop(): + # Get the various UI elements for this command + workspace = ui.workspaces.itemById(WORKSPACE_ID) + panel = workspace.toolbarPanels.itemById(PANEL_ID) + command_control = panel.controls.itemById(CMD_ID) + command_definition = ui.commandDefinitions.itemById(CMD_ID) + + # Delete the button command control + if command_control: + command_control.deleteMe() + + # Delete the command definition + if command_definition: + command_definition.deleteMe() + + +# Function that is called when a user clicks the corresponding button in the UI. +# This defines the contents of the command dialog and connects to the command related events. +def command_created(args: adsk.core.CommandCreatedEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Created Event') + + # https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs + inputs = args.command.commandInputs + + # TODO Define the dialog for your command by adding different inputs to the command. + + # Create a simple text box input. + inputs.addTextBoxCommandInput('text_box', 'Some Text', 'Enter some text.', 1, False) + + # Create a value input field and set the default using 1 unit of the default length unit. + defaultLengthUnits = app.activeProduct.unitsManager.defaultLengthUnits + default_value = adsk.core.ValueInput.createByString('1') + inputs.addValueInput('value_input', 'Some Value', defaultLengthUnits, default_value) + + # TODO Connect to the events that are needed by this command. + futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers) + futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers) + futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers) + futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers) + futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers) + + +# This event handler is called when the user clicks the OK button in the command dialog or +# is immediately called after the created event not command inputs were created for the dialog. +def command_execute(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Execute Event') + + # TODO ******************************** Your code here ******************************** + + # Get a reference to your command's inputs. + inputs = args.command.commandInputs + text_box: adsk.core.TextBoxCommandInput = inputs.itemById('text_box') + value_input: adsk.core.ValueCommandInput = inputs.itemById('value_input') + + # Do something interesting + text = text_box.text + expression = value_input.expression + msg = f'Your text: {text}
Your value: {expression}' + ui.messageBox(msg) + + +# This event handler is called when the command needs to compute a new preview in the graphics window. +def command_preview(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Preview Event') + inputs = args.command.commandInputs + + +# This event handler is called when the user changes anything in the command dialog +# allowing you to modify values of other inputs based on that change. +def command_input_changed(args: adsk.core.InputChangedEventArgs): + changed_input = args.input + inputs = args.inputs + + # General logging for debug. + futil.log(f'{CMD_NAME} Input Changed Event fired from a change to {changed_input.id}') + + +# This event handler is called when the user interacts with any of the inputs in the dialog +# which allows you to verify that all of the inputs are valid and enables the OK button. +def command_validate_input(args: adsk.core.ValidateInputsEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Validate Input Event') + + inputs = args.inputs + + # Verify the validity of the input values. This controls if the OK button is enabled or not. + valueInput = inputs.itemById('value_input') + if valueInput.value >= 0: + inputs.areInputsValid = True + else: + inputs.areInputsValid = False + + +# This event handler is called when the command terminates. +def command_destroy(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Destroy Event') + + global local_handlers + local_handlers = [] diff --git a/f360-script/External controls/commands/commandDialog/resources/16x16.png b/f360-script/External controls/commands/commandDialog/resources/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..03babdc056577fea50543b03d15c480d88c89f4c GIT binary patch literal 415 zcmV;Q0bu@#P)KA9k4D0+<1qc$SunL_18+0mJ|no~1oAf13dfUQ*u%01+5>;@Y z)*+9ui?QG#{8m7wjtRZ_7;GpXT!7Xr);$MsL(ih)&$~U6?q5HKp5f86w1-XuNy<+m ziM)=y6Z(%>u-E%a+b3{!z~(0Dcce}w4hGl2o zy!Y*!_hU9;+cvg|2T^S6rX^)vFJ%&8b=}+Q=c_!Rn^p=y6@XDMWu{S-Z=yr$0lx7w zfD`uQ?@^2g>JWm^v+>X~-24*Dhu;%x1PJ3R3<2zK=m1JqAmKlP zDq$QUjH_f1xeXV70tRP!SLksYasu2n+8vPyj)4_;EL;NEjmh{7Ku(s5R3S27}iUf9JR=g?(3!*!+J;9 zUT_wma2h1zM_2-vG0C{tdN&M9fIR<@GLZ?KsX8NH3l#%YA*w1m9+ieEZyG*X{=mcA zg}c6U`{&Ev_0^}zWO8K~#>XH6%#Gg_#E1M#R{@vf?{50-efxleXHSKVola*wo6X)d z8jW}Cohn3AUOuU6$P8U52s$Vhi^5#D+huOKD3{A%Bm@GUJ3(B1fPzC}jX=PKBo-VW zYmdg`k<&K@gTY(B2UHi5Sa5Xo;xPa=P^;C17+}rfd7M|WX0wUWXe0>a^LgjFMu4T3 zZdzI#m(ql7{{(Pf(=;p=3qdfQPNU!Ni&-Ec;l0VQVd$nMB~UMA+;&^(-TY>OoXuuc zo|31bhs6KCB90w|u j%CBTHsr;pz&*%6H8=VB7i~>0q00000NkvXXu0mjfNzF8J literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/commandDialog/resources/64x64.png b/f360-script/External controls/commands/commandDialog/resources/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..dd285fd1c9a47ff154e426da5c90fcdd96239c2c GIT binary patch literal 1077 zcmV-51j_q~P)ZWvYv= zx{iE7uCu6eC_iv#i2_oDd_h3U2V4qV&?G1gA|e+p8iVi7XYZ_c_iU3VU16PXXWqN@ z?9A+XW-u7wA!GJIvj_0lmLWfkSW_)^9A4)TT$bSUz1i%S7VI6)LtqJ=8o~!!779c@B##BTgKfaKCsQSSY zAccGkt0L(1Lpl@8Fq*{WXiOky8UVIrog(z;+3p6e^Q)*IlOQF4q|v1DB@vW}_)E#( zW#It8o*>2aBUgl60hr{=hFlRc1)%ABk_a@l6JcTy^uuVr2ILV3#z|jJ6o3Lx!p^A!-OI|=a6RemBQsf0#sW1)tPT4Ix zkR~snQVxss^n(T}KLGR-*Gp8@6~)9QFAXXJ>=krSq_yp|#KaFHA;LB-TdMiT9*rRd zR$H8sqo0b7oe9Te3KX&(b;MNus$f&v&$~x}+qY-nP2f7Lz?1|%4t?D)7bTX)8G~s7-qHr9GAI)?)||C*KA=q`RM9orn&+0o z9fdtUs1`&8>>W@cl?$!_VyEbvf<6Td zj*eLOZ)|J~U1tg)c3J%}LYYN4K0apMKPrHU6Cxtzd_}*})fg4&^9vK_6Qq_w#!N^a zNfV!r=98iw?{L_M_4Re;u)~n91tdgBJ&#A%+kP0a1PEM5s+~4ErMXZ!A(A!?rO)P; z4eVklA;M+V$qOjGF+z{SDdh=`X_7a(3}!))77YxQeSe)Wz6@qz+T?Y>+KZE>U~L&J vE37Vqb%eDUVC!9AE-Lr>yytoP90u?YjV+lgrL2(V00000NkvXXu0mjf+LYiK literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteSend/__init__.py b/f360-script/External controls/commands/paletteSend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/f360-script/External controls/commands/paletteSend/__pycache__/__init__.cpython-39.pyc b/f360-script/External controls/commands/paletteSend/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01a32545552f8c5783f2b0a43819c2d2a01120af GIT binary patch literal 212 zcmYe~<>g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=bXRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&}zIHn*mC$*#`H8?ddB_=*TGcU6wK3=b& V@)n0pZhlH>PO2TqNuPn30RVtWI`9Ah literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteSend/__pycache__/entry.cpython-39.pyc b/f360-script/External controls/commands/paletteSend/__pycache__/entry.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5ab94ac043b1b449706df8a0d1f178e1cae5d88 GIT binary patch literal 3541 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 literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteSend/resources/64x64.png b/f360-script/External controls/commands/paletteSend/resources/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..ed1ae276ca4eb5a06999f3e340cabec2f571653a GIT binary patch literal 1972 zcmV;l2TS;gP)P|5NA&mlJKR z&5-rUiU3anqGn@N%V=cMnVd%X^-719(I87e8jm4u9|9^6O=}qzGU=Q~`SnUiTFZdE zsVdSpPXZtt1raL(28T|CZD(jOBOrqG$y3nn1SkOe_ue0-ZOe@%Q@WaeV0vZ-P18fO zXgQ#&QC6r0t~s~OKOh7chUeU&;vsyP??8Zf4-ini{mujk*NIbAARqz%9|9PLdjuT+ zb1nb4m_2Rt8jUZ1bk3iJAtU$@@Q47r^H#mmBBl%k_|pKV_7DBK!B-!C@$_9O*WZ?1 z1Dx95z9HOU;bmi}8nCf7&A&!#a_Ua)Kk>oY;;kqFUO^go2--i!a0CeRY0yt6PEU`UHf}8X z{8Hfd#Og*syrTzzF^ zO$}Ibe-Ox5$T_eypc+af5?xSZt(}Jkjx?&V*3Ng*H}2^D`tC1^Tmn2va3P>NN+c4| z0Sp1(?H_1TYvbF`&)smx?ymdpHXV1}8e^d>S>S3xShrfh^gKM77-;%t&z>ExUr^J) zV}Oo-0=z|V_>Ezb$>d@^9*@(}-Vwl!;4pyE85s%RNena{*t_SBrklPrKk@gUJiOGo zzBRz^JU}v;ylNUCZ<0`iAs0bLry+F(4n95599>cO>E#<(INDe0ohJ@?>0AB<+>?ioZ`s-cWzkKTFrx#Xj+o{Ilw-$Yo zJX}N(^_#Z=0z>4!oVheDhr`29^~WFI*R!joy-SR}akLk?WiE#V-x|=|)WZ10SWew3 z0@hu(-qrY6tZrdOZSDN__Xir6^t1>}Tq%4zH8LfS9XOO|ec~HE_q4Qk;Y5P(A+YJg zHx(T7`zA?IvgzyJmwcV-3nNof8+yN&XzknYOhSPOf+Qi#g2}#agkLUB!T4p^|74<7 ziPYTF(%#hvtiaqr>6`^ZE;3$(q6^TB@XLiM7{3Dh`XmX+jp0#1anu0eGYj~I5Hj)% zV|m^zU%MJsUjt9|?in{Sv%f+TkOs6u0ua6y6oSBtfH2Xv8dlfB;csIvlU{zf$qYE+uHe4ILzlm8Xc=>3nhx%Ih;eqayJ~#Htl`WrXy+7+#-zpES_cON`j^UvIsI@Z)fQym<6 zq&ua}jh#uI8#)3^0u#U#Fb8PXF7a!CRX`)q0MsGJiDQ;15gL%Oeb(5@3jC36*&S`! zy8D^0K60eNPJre7vyUx0|05uUBw!ktMQVVdB11t37J$oUAM+&`wG?!u^HvC|<~3@_ z{%@gJM9gznVy=Q)V!E~g8e)#lr+^vcozIvy2#Wv>NdV@LDn;zI_X+zD5N7}O;^$gc z)YgF_2@qN5k3H__y#3DS%ml54gS72)Q6+=>+Z2!_XdowV z&-ZmtYI9>}y_}DC^oS*w#g`Kgb?+_pR4ZCFePR04^L=~n)aNH&N}U@zhD>pe&O3Ef zt^W|UG{8#TF{Cf^NXKXJ2zxuCVOts!>;eihbIl>s_+|6^lFq|b9s&VirS5s;P>7nx zGDycW6yZEn?+~y@K-B!SCUo|>eo-A&E9@y$A?vWOZ1z76&6OwtiJT<>0000g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=bXRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&}zIHn*mC$*#`H8>-`JSILqGcU6wK3=b& V@)n0pZhlH>PO2TqNuPn30RV$AI|l#& literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteShow/__pycache__/entry.cpython-39.pyc b/f360-script/External controls/commands/paletteShow/__pycache__/entry.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6e754a287537dd32eca8b93136a63dc2867ac3c GIT binary patch literal 4580 zcmaJ^TW=f372X?{%d03#^4;>jZr~HBz0Sfe-*`+8cK}qcJ%$ecL>^a~0&Kb8< z$}8~s&tLxQ{^6#g{0lp0KUwJf5}x>TRZ)mS)If2PU)9lMUw3q(5j`-v8OKx=kc}YQ zwHym%g=B(UH|OM3g=&7@FN}&~#VOH}Uv_4w;uc+y>2ksd+%|z&fvy*Fp3CnRS-P8=(1ssC!E7&F|3m&F^$* zYpN(8_G2#!-~Y+IKKFtcG-f*r54{dZ7I8V{UY82BxM)q zZG7d)#{j{EXBD1!7aFek>PX`{H+Y7dW8*~O*^xC={2b4ZH5JDJRJ=4+Pt>96mqDHZ zSsQA8Wi&ffc$KJQ{Y2+;L%lUm6fm;ZT(2z%t?!9yJ2^yy9(tk2!PK#sa|wCe=R69h zT4AnkHCh`DVc~DHzO^Q1P-@Uvz9;-q6gF13o2~Wj&BofU$Q+`>L;==n9l=`$l! z*(#&pIU;7#eyg1-^2ZT-7WZ7Vy5(`&ef)BRh~j74yC3iE)K}N=03{wp!GX)9NnzSf zy}7n2PX@r?EDBpm0cWCI|Tdwzd4VSyiyOG=V z!p?HN&m%(PXQ#p$04~>eHkJVy8)3Y>_JUIux`918{?pVd@zY)cUc~ZK02X_BxA#(H zV(v1257AMCM$xKz*(mBoy`r4E3^n#-sErC^MOB76+aKzwY_QLVMj}gism)rE&A@K#8aCIlxq%JPtHKts zxrI#?n+i0-N?#Rxw^QF-+uxUtvIxb9-lDY(Tf(_-;M^%{5`Uj!7#){_SY*=$rLU5v zhJQ9<9`)8iiZ4NV|5i54#T|->AZHSto7->7Ra3Mw3c&J_La)Bb94F-RdiC ztjbu_(X2j1D$f$_OZ|+_;<<@Vnn`aCuB_N8Q0+7ZZ2BBreHW=Oh}v#237)u?XLw|x z2T_O3fy6Fj7hsvNNS3~!?LMbd`=ko?ft&|egy?uV9ZnVO0j`CRo|=hWg>DO;7@0`X zD*C)Cb?2;sz$(Bat??}gKd^@G8^}o`%Te{bYAjxy+6f3`n7xBt8D{T-By`|EQJe&lB~C#~%4F7Lg#8?k zgdrk|Bx*l{$$K0~AA*X+&xFyA7!~t73BfhaOo+vmGg|qd^&pbR5i^sQXl$>3ywUuK zJ%aUXI(r}Yk~TnEyolwWfzF2~M%w_EHB-&2mTIWl#qYn(LRrP{qE=B&jp0AfAs*u& z^RqsMek}H$z?47269f9-ybSy2PJwZE zdI}u9cnV-3{X_+c`?T787NxlqTrk)pip9LZdwAkv#or~W86|DaiJZZA5 z=q7M}RnMyoM}TH?7}KpEP<;+YvGSL${wD|*jm-6t0ftVpr{bF@KxEL*`j($d&8`oD z*oK%MzzIK9POzUrr@Ydzhbs8CcJR^-Ml9stkc>ff{E=)vD z>eSVfu$?%1ehssb&1jo?&ndAFA<%8M2WA*p^){A?EB3&|dS}IUs$Ck#P|zY9q_Hb= z=lwwm%zEDrBW}l77-K?xAe9eJm4mH%nCxmFL8Kf|8rp{*o9xMtsErOnXr%=_g26`p zVH5<>F=7xd0`AJg1GfBVF!S)>QF6kE%Lk9(lvSw*EuQ5^bPrOUwe)0VX=`O^Z;;vk z*nZEhEnEmzVfZmrxfx(10+#~ZQ<$zahA6<1;ULm#!i1M4lu7oRf}DK{)?=SRBlHgC zvOW^|)O3%d7Yqvvp@-42upm<(%8N~&QQl`E8oHKaPho~rO#jlt132YLFF6SNEpGBV zY<@47!-(jhRA~1Z11Idmed%J1Y{G=U!4uoiAVU^`{i+jgqLPkI)tC&$O-ul%*7%5ql)1rl4kjZp*GvnD zD4dQU*@_a@3R4{dNqX)K9^XQptkkWC-H7x9`Uv3_qk}ET+7gX`M?fglq(<`9P2&z+ Zfbyp7>$YJS)+Os|wNPEGn$=2m@qhgV%ZLB~ literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteShow/entry.py b/f360-script/External controls/commands/paletteShow/entry.py new file mode 100644 index 0000000..f48c1c4 --- /dev/null +++ b/f360-script/External controls/commands/paletteShow/entry.py @@ -0,0 +1,193 @@ +import json +import adsk.core +import os +from ...lib import fusion360utils as futil +from ... import config +from datetime import datetime + +app = adsk.core.Application.get() +ui = app.userInterface + +# TODO ********************* Change these names ********************* +CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_PalleteShow' +CMD_NAME = 'Show My Palette' +CMD_Description = 'A Fusion 360 Add-in Palette' +PALETTE_NAME = 'My Palette Sample' +IS_PROMOTED = False + +# Using "global" variables by referencing values from /config.py +PALETTE_ID = config.sample_palette_id + +# Specify the full path to the local html. You can also use a web URL +# such as 'https://www.autodesk.com/' +PALETTE_URL = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', 'html', 'index.html') + +# The path function builds a valid OS path. This fixes it to be a valid local URL. +PALETTE_URL = PALETTE_URL.replace('\\', '/') + +# Set a default docking behavior for the palette +PALETTE_DOCKING = adsk.core.PaletteDockingStates.PaletteDockStateRight + +# TODO *** Define the location where the command button will be created. *** +# This is done by specifying the workspace, the tab, and the panel, and the +# command it will be inserted beside. Not providing the command to position it +# will insert it at the end. +WORKSPACE_ID = 'FusionSolidEnvironment' +PANEL_ID = 'SolidScriptsAddinsPanel' +COMMAND_BESIDE_ID = 'ScriptsManagerCommand' + +# Resource location for command icons, here we assume a sub folder in this directory named "resources". +ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '') + +# Local list of event handlers used to maintain a reference so +# they are not released and garbage collected. +local_handlers = [] + + +# Executed when add-in is run. +def start(): + # Create a command Definition. + cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER) + + # Add command created handler. The function passed here will be executed when the command is executed. + futil.add_handler(cmd_def.commandCreated, command_created) + + # ******** Add a button into the UI so the user can run the command. ******** + # Get the target workspace the button will be created in. + workspace = ui.workspaces.itemById(WORKSPACE_ID) + + # Get the panel the button will be created in. + panel = workspace.toolbarPanels.itemById(PANEL_ID) + + # Create the button command control in the UI after the specified existing command. + control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False) + + # Specify if the command is promoted to the main toolbar. + control.isPromoted = IS_PROMOTED + + +# Executed when add-in is stopped. +def stop(): + # Get the various UI elements for this command + workspace = ui.workspaces.itemById(WORKSPACE_ID) + panel = workspace.toolbarPanels.itemById(PANEL_ID) + command_control = panel.controls.itemById(CMD_ID) + command_definition = ui.commandDefinitions.itemById(CMD_ID) + palette = ui.palettes.itemById(PALETTE_ID) + + # Delete the button command control + if command_control: + command_control.deleteMe() + + # Delete the command definition + if command_definition: + command_definition.deleteMe() + + # Delete the Palette + if palette: + palette.deleteMe() + + +# Event handler that is called when the user clicks the command button in the UI. +# To have a dialog, you create the desired command inputs here. If you don't need +# a dialog, don't create any inputs and the execute event will be immediately fired. +# You also need to connect to any command related events here. +def command_created(args: adsk.core.CommandCreatedEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Command created event.') + + # Create the event handlers you will need for this instance of the command + futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers) + futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers) + + +# Because no command inputs are being added in the command created event, the execute +# event is immediately fired. +def command_execute(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Command execute event.') + + palettes = ui.palettes + palette = palettes.itemById(PALETTE_ID) + if palette is None: + palette = palettes.add( + id=PALETTE_ID, + name=PALETTE_NAME, + htmlFileURL=PALETTE_URL, + isVisible=True, + showCloseButton=True, + isResizable=True, + width=650, + height=600, + useNewWebBrowser=True + ) + futil.add_handler(palette.closed, palette_closed) + futil.add_handler(palette.navigatingURL, palette_navigating) + futil.add_handler(palette.incomingFromHTML, palette_incoming) + futil.log(f'{CMD_NAME}: Created a new palette: ID = {palette.id}, Name = {palette.name}') + + if palette.dockingState == adsk.core.PaletteDockingStates.PaletteDockStateFloating: + palette.dockingState = PALETTE_DOCKING + + palette.isVisible = True + + +# Use this to handle a user closing your palette. +def palette_closed(args: adsk.core.UserInterfaceGeneralEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Palette was closed.') + + +# Use this to handle a user navigating to a new page in your palette. +def palette_navigating(args: adsk.core.NavigationEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Palette navigating event.') + + # Get the URL the user is navigating to: + url = args.navigationURL + + log_msg = f"User is attempting to navigate to {url}\n" + futil.log(log_msg, adsk.core.LogLevels.InfoLogLevel) + + # Check if url is an external site and open in user's default browser. + if url.startswith("http"): + args.launchExternally = True + + +# Use this to handle events sent from javascript in your palette. +def palette_incoming(html_args: adsk.core.HTMLEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Palette incoming event.') + + message_data: dict = json.loads(html_args.data) + message_action = html_args.action + + log_msg = f"Event received from {html_args.firingEvent.sender.name}\n" + log_msg += f"Action: {message_action}\n" + log_msg += f"Data: {message_data}" + futil.log(log_msg, adsk.core.LogLevels.InfoLogLevel) + + # TODO ******** Your palette reaction code here ******** + + # Read message sent from palette javascript and react appropriately. + if message_action == 'messageFromPalette': + arg1 = message_data.get('arg1', 'arg1 not sent') + arg2 = message_data.get('arg2', 'arg2 not sent') + + msg = 'An event has been fired from the html to Fusion with the following data:
' + msg += f'Action: {message_action}
arg1: {arg1}
arg2: {arg2}' + ui.messageBox(msg) + + # Return value. + now = datetime.now() + currentTime = now.strftime('%H:%M:%S') + html_args.returnData = f'OK - {currentTime}' + + +# This event handler is called when the command terminates. +def command_destroy(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Command destroy event.') + + global local_handlers + local_handlers = [] diff --git a/f360-script/External controls/commands/paletteShow/resources/16x16.png b/f360-script/External controls/commands/paletteShow/resources/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b8e5705f6c5544667a8ea92580d82360687e34 GIT binary patch literal 340 zcmV-a0jvIrP);xMdD{U>TEPR43wo$aQ@EP(1mX;P~ zGMS&mVj&Yl2)nu6z&(fijR%Z?9^LX80KK9p&PP|bbJNd{_XGe@6m=ZHR1n8;C)o46 zsleJCo9A=E3%>6bXl>BOa5-Kn3r|DQDp(8xC&;uxN(DH9NEO#F8;$V8*$-ie6DXw- zsr*+GspPKz-6#+#_`X+JkZBSjx!L_HOG*0$wG)))H<7JCJ literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteShow/resources/32x32.png b/f360-script/External controls/commands/paletteShow/resources/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a61a47e4710bdc2aedde29ee1f9f4f0b25d8c82a GIT binary patch literal 587 zcmV-R0<`^!P)do&Mr37>Z`J(s>*sC z{uEW5lPmy5Q8X}Nppp-uDs>t_R9Y#xw=v&xdUjzq8Nfa*I{-wZJ0Rum5b275DAx9; zAbh+3?!X|?C+C0s3qY{8f0g0ez)sSn$Cz4c8X!cV55O1b z+Uqxigl}EH)&TTv!$|~S;sI`4xjYCU_}2ivMd(mZaP`u~)&!{v)ELuKgsMzj128Ky z#^5w^66OGio`eD5?T7a*$JOzB)jy9n!+EC8H1eyTM=s&=hE1=F2 z78efB9>8nu1rT6+>FAODdx2(b7T5;F0Q0~h;2`xoF^ByEz5-ti^&4%@ix)AkgeD&1 Z=Wl;YQq&g|YVQC5002ovPDHLkV1iU;1q1*9 literal 0 HcmV?d00001 diff --git a/f360-script/External controls/commands/paletteShow/resources/64x64.png b/f360-script/External controls/commands/paletteShow/resources/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd5dfcb2d51b5651ff4fcc8a4f757af32a172a5 GIT binary patch literal 1165 zcmV;81akX{P)% z&x;&I6vscc+pd`ng1BxNLQoO|akDB}6N3aJNOV0Y2oeY$)=NSlC&i2Zh2SY5@nQrC zFIn=)32v$-uuq`Rozv} z7{k*H4?roU00o=@PDG!Z2m@RLE&#?DW4!2w0(Jl&UcB_{r{mJD3ap&^$OC=^9syef zc)(7e73hG@>N+1Uzq2*y%GEzASF{YYcg+E`2yOL&UQEC=FbnMP`#$|%e_-J7^`ye@ z`w)8iEbtJb8~{uKGl19g`#kRV1_lmaPbzwTA3~dF2yNaXfJmTX54d>gO7$9+jK~8N zk?}A{003Wqd8R^@#*YL68ygStgJ2xGln!rt8qb>^lnsB$7=zKxY>v!S(yk-{fNp4a zC|Q*t0Apxudo0)`gaGKKhJav}m;LtktA zoISR=O%=<9eF&KB5EwQ-mgS8bH|#>d80RD?jr;1C=bh$q!8f1$n|a@o0QV{&jaxoY zU0CGlU3wLe#=XD4>ok|!?`Pj1SqLob>T!2&Pq~DLBke_s=EQXB8Rvsh| zII?u8_(YD#O5RG@hJZHcKxY!rYPHzh+)T)HP~RM&l)TJOO@dhjteiS2%Ilm2?L8ps z1e^9yC?p^$7d;@z@qkH00S_<@_JBeJq%-jQ^&8xO@L)i;XZLR2d-wPVR4oTesbZaA z76HS?$Fh1SL2ClY^?)=;b@->tmkZD1iqB5U)d>nDK^-lJT?mkt(TfKc3eV$;tYy4H zA@#RTIUo&^2P_W=kptT8Hl0oO(520#YCF@=JRQ z&*O>_b%N1m$qWMKUU-r9fBsI$>Rvgl-wo#FfW^hvMR}b!SA{vistS->1ttkmiq+V%V3>hT?T2e2S{0PD)Aj;SDADeBfsz!li;DnSIXCD9LPz68o2%D8~dLF zo<;DE35NzA1Gl5kz!L&A&;x!3{sQKJXDU{(Z1jP3;2xo^8lDgk09{};x?U$dOV}g? zzy_g>-RK%+j6o?iMR=faC*h&Ot#fq^LhR*T;6LDzF-FG(#D}Ln!hgPL#>dcv|GZCh fcv>~F + + + + Title + + + +
+ +

Fusion 360 Palette Sample

+ +

+ +

Send Data to HTML Event Handler

+
+ +

+ +
+ +

HTML Event Response Value:

+
Response
+ +

Message from "Send to Palette" Command

+
+

Message from Fusion

+

+
+ +
+ + diff --git a/f360-script/External controls/commands/paletteShow/resources/html/static/palette.js b/f360-script/External controls/commands/paletteShow/resources/html/static/palette.js new file mode 100644 index 0000000..dacdafc --- /dev/null +++ b/f360-script/External controls/commands/paletteShow/resources/html/static/palette.js @@ -0,0 +1,48 @@ +function getDateString() { + const today = new Date(); + const date = `${today.getDate()}/${today.getMonth() + 1}/${today.getFullYear()}`; + const time = `${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}`; + return `Date: ${date}, Time: ${time}`; +} + +function sendInfoToFusion() { + const args = { + arg1: document.getElementById("sampleData").value, + arg2: getDateString() + }; + + // Send the data to Fusion as a JSON string. The return value is a Promise. + adsk.fusionSendData("messageFromPalette", JSON.stringify(args)).then((result) => + document.getElementById("returnValue").innerHTML = `${result}` + ); + +} + +function updateMessage(messageString) { + // Message is sent from the add-in as a JSON string. + const messageData = JSON.parse(messageString); + + // Update a paragraph with the data passed in. + document.getElementById("fusionMessage").innerHTML = + `Your text: ${messageData.myText}
` + + `Your expression: ${messageData.myExpression}
` + + `Your value: ${messageData.myValue}`; +} + +window.fusionJavaScriptHandler = { + handle: function (action, data) { + try { + if (action === "updateMessage") { + updateMessage(data); + } else if (action === "debugger") { + debugger; + } else { + return `Unexpected command type: ${action}`; + } + } catch (e) { + console.log(e); + console.log(`Exception caught with command: ${action}, data: ${data}`); + } + return "OK"; + }, +}; diff --git a/f360-script/External controls/config.py b/f360-script/External controls/config.py new file mode 100644 index 0000000..774f687 --- /dev/null +++ b/f360-script/External controls/config.py @@ -0,0 +1,21 @@ +# Application Global Variables +# This module serves as a way to share variables across different +# modules (global variables). + +import os + +# Flag that indicates to run in Debug mode or not. When running in Debug mode +# more information is written to the Text Command window. Generally, it's useful +# to set this to True while developing an add-in and set it to False when you +# are ready to distribute it. +DEBUG = True + +# Gets the name of the add-in from the name of the folder the py file is in. +# This is used when defining unique internal names for various UI elements +# that need a unique name. It's also recommended to use a company name as +# part of the ID to better ensure the ID is unique. +ADDIN_NAME = os.path.basename(os.path.dirname(__file__)) +COMPANY_NAME = 'ACME' + +# Palettes +sample_palette_id = f'{COMPANY_NAME}_{ADDIN_NAME}_palette_id' \ No newline at end of file diff --git a/f360-script/External controls/lib/__pycache__/joystickapi.cpython-39.pyc b/f360-script/External controls/lib/__pycache__/joystickapi.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..440ae37adb476e2a3b9db6e300d17b88b70d00bf GIT binary patch literal 3238 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 I?~GX9cW`x)An*dkwcxY#%UK&fW6X?2SA zsW+`0RG-wQ?72U!z2KZpYmnQM4WF?MrL2&Na1w}_Od?A~wylL7=`iX?S{2KkW>etX zFoW?B^4fJbEl%FJAs*sHF-dznI?Ti*9g97gWW+8^lZ0q;;f{_wUn(tTEc)Xl%%U`b z1TqtQQ5?^XIFZ~1#X$m-4s8fG!X;y?MU;p*9SovmARO$_&e}ALWCk_%qHG&%B3mj% z`jp>2sBHEk@F3kC&$NGhshDYn!?;Ivpf84U28L6mrF(IS+T1pd#O={ z{3qR@&?Js<61SGl;V>M^L=H$Q;4!*f_w?QRV?AN{{M@NASp@oH(yMMZ5)I349~cy<{$>6A0i%8Hq$DE^MR3 zDcqt&>5)d4Wbs7wQzNttw-F6P90cC(*t*f#*d()fA`3p8hf;}85e(9b&}eeyj&RDT zl9bHiU3y)k@dE-f6lKaMFzY>MCsVRTyW3WCBY|idPHjnV=A_#J*iO4df}aMBO~8<+XxgnIBD% zO-9;K+JDK+Mg0A}zq$VSC##KJ8|XydT-z9pzLA++yPwJ-th}}{&QhiA?tCD=h53;* zKKmS-f4sYfymmLSYj=Ljv`OGf$Um7$WBWLcdXM{VFSd@e2qc$N0yplACiyZ{D;0Pf z!dO?2uC(}hewH`6xdd8>cH*Oqzlml^UsM~^CCah;*EY#Jt#ivouU?4p!T?l2mdb0b zLt&wN3taQnlYadLUFYh9Z{ESU?H4#Z#OGj#RVbI-=;x*knw_N_V zw>#gvB5y)+f%2mH0T48p+-+q%&os#qXA%W9QGD6)+_X!63t*3B<1J2pcEV;-b zC5OaM9pw>Ayqm{T8?r;&GwtBg)jRGrSh1POeX2MvR%X0M}zmL8h#*FEn2;{$%rqfzUF#xiXD56wU$O6yQotc|IzuBbKiV3VgzuX=FRVUXN_Tl64978 zhs~cz(WV4{JQ_BCCPna=c+1vwn@4FN?v;{g^UCXxSNYa&mEnEffb%x5y$*Pt$8hq1 z(;rEv`3~YChwnn59qOtRRit^=?}Tn^CX7ik;VM%6BBX1jN>9WH6pWH$f(Dxv0aJm! z58J!|V#$iUq?D|vrPE*vX`KbS>-oyG`fF&n-qcoby9%#DN^IRcSq1uVeIMVx_kjkN z{~X&~=61=_MKQ6tDwtJFBqo^v{HI`1<7?ZZyPRpvS`tcwzE&RjH6TDbail|9F17}q+`TIr4KYQP;W z=fb!~KbK-HxeyBALa8!Wd3Nyh_&c|~U$$?p(1|qmPGj>lLUdRI<&gzXZ;5^Y2mh}2 zcTbLu(59D(B6-}~o6nymHtD@k$qY)}+gn)0g*p45Vf}@{=6vx4lz$lX_BbCDrgv~* zg)S1w06du$?9)$2QY_ko7)NA23jp=q+1M2VI z1}-X+nHaXssX8C6`#2h_i%EbM>xDd~=K*>MjD-o@K=Wk)5Cp)!B0R8u`d*Pg!t1vy zs=qHGdsF8MAkIUWq9_?rLhiz+$!Bw!r%NWVUnNeVY3e+!std^(01%A|oQ~_*gkqI0aZYZpLCX4xG~zRsTfnH4 zOcgM1w|(6KWe?=r?odXw1In^8IgA7(mI7?Mcd6r<_jP&yYh27DpLyQV_^?y=NYFKC ztA?kSXncuv1Bk0zolL|ynVh*8#&nk0k+_(+V3E6cjg_bBLVth;i1v~^MAK&Zq>OyY zKZg^8A0Tm?eiBAhBPctx-+AZ)W%P$2xjIg27YFryEUp3bBC#nj5-!Yy)re%*g5K&u z0V9z@fchgmBO2dS-9~~bxaOcp6-=rhc^4Y1T{Koomib}?*Mj!p`^alw%@kiq@l6vn Y%npzmgint + returns integer value of axis + """ + osn=None + supportedOS=['nt'] + + + axIndex=["X","Y","Z","R","U","V"] + + def __init__(self,id=0): + """ + initializing joystick. Throws "Unsopported os" if os not supported + """ + self.osn=os.name + + if self.osn not in self.supportedOS: + raise Exception("Unsupported os") + + self.id=id + ret, caps=joystickapi.joyGetDevCaps(id) + + self.ManufacturerId = caps.wMid + self.ProductId = caps.wPid + self.ProductName = caps.szPname + self.NumButtons = caps.wNumButtons + self.PeriodMin = caps.wPeriodMin + self.PeriodMax = caps.wPeriodMax + self.Caps = caps.wCaps + self.MaxAxes = caps.wMaxAxes + self.NumAxes = caps.wNumAxes + self.MaxButtons = caps.wMaxButtons + + self.rangeX=[caps.wXmin,caps.wXmax] + self.rangeY=[caps.wYmin,caps.wYmax] + self.rangeZ=[caps.wZmin,caps.wZmax] + + self.rangeR=[caps.wRmin,caps.wRmax] + self.rangeU=[caps.wUmin,caps.wUmax] + self.rangeV=[caps.wVmin,caps.wVmax] + + self.ranges=[ self.rangeX, self.rangeY, self.rangeZ, self.rangeR, self.rangeU, self.rangeV] + + + + def getAxesRaw(self) -> list: + out=[] + ret, io = joystickapi.joyGetPosEx(self.id) + if ret: + # X Y Z R U V POV + axes = [ + io.dwXpos, + io.dwYpos, + io.dwZpos, + io.dwRpos, + io.dwUpos, + io.dwVpos, + io.dwPOV + ] + + return axes + #else: + # raise Exception("Joystick read error") + + + + + + + def getAxisRaw(self,axis: str) -> int: + """Returns value of defined axis + + axes: + + dwXpos + Current X-coordinate. + + dwYpos + Current Y-coordinate. + + dwZpos + Current Z-coordinate. + + dwRpos + Current position of the rudder or fourth joystick axis. + + dwUpos + Current fifth axis position. + + dwVpos + Current sixth axis position. + + dwPOV + Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. + + source: https://docs.microsoft.com/en-us/previous-versions/dd757112(v=vs.85) + """ + out=0 + availableAxes = ["dwXpos","dwYpos","dwZpos","dwRpos","dwUpos","dwVpos","dwPOV"] + if axis in availableAxes or axis=="list": + axes = self.getAxesRaw() + return axes[availableAxes.index(axis)] + else: + raise Exception("Axis doesnt exists") + + + + def getAxes(self) -> list: + axesRaw = self.getAxesRaw() + out=[] + + + for i in range(0,len(axesRaw)): + out.append(int(correctAxis(axesRaw[i-1],self.ranges[i-1],0.05))) + + return out + + + + + + + +joy = Joystick() + +def run(context): +# This section executes once on script start + ui = None + app = adsk.core.Application.get() + ui = app.userInterface + futil.log(str("Joystick driver v"+"/version/"+" started")) + futil.log("START") + + + # this found there https://github.com/Rabbid76/python_windows_joystickapi + + numOfJoysticks = joystickapi.joyGetNumDevs() + ret, caps, startinfo = False, None, None + for id in range(numOfJoysticks): + ret, caps = joystickapi.joyGetDevCaps(id) + if ret: + ui.messageBox(str("Using gamepad: " + caps.szPname)) + ret, startinfo = joystickapi.joyGetPosEx(id) + break + else: + ui.messageBox(str("no gamepad detected")) + + +# This section executes once on script start + + +# Loop starts + + while True: + + + + futil.log(str(joy.getAxes())) + + deg = 0 #joy.getAxes()["V"]/52428 + + + app: adsk.core.Application = adsk.core.Application.get() + ui = app.userInterface + # viewport + vp: adsk.core.Viewport = app.activeViewport + cam: adsk.core.Camera = vp.camera + vecUp: adsk.core.Vector3D = adsk.core.Vector3D.create(0,0,10000000) + + + target: adsk.core.Point3D = cam.target + # matrix3d + mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() + + mat.setToRotation(math.radians(deg), vecUp, target) + # update camera + cam.isSmoothTransition = False + + eye: adsk.core.Point3D = vp.camera.eye + eye.transformBy(mat) + cam.eye = eye + + # zoom = cam.viewExtents + + # if axisXYZRUV[0]>1024 or axisXYZRUV[0]<-1024: + # zoom = zoom - (axisXYZRUV[0]/10000)*(zoom/100) + + # if zoom<0: + # zoom=0.001 + + + + #futil.log(str(axisXYZRUV[0])+"|||||"+str(cam.viewExtents)) + # cam.viewExtents = zoom + vp.camera = cam + vp.refresh() + + adsk.doEvents() diff --git a/f360-script/External controls/External controls.py b/f360-script/External controls/External controls.py index 7ddc4b4..d36a17f 100644 --- a/f360-script/External controls/External controls.py +++ b/f360-script/External controls/External controls.py @@ -18,7 +18,7 @@ def run(context): - +# This section executes once on script start ui = None app = adsk.core.Application.get() ui = app.userInterface @@ -35,7 +35,10 @@ def run(context): break else: ui.messageBox(str("no gamepad detected")) - +# This section executes once on script start + + +# Loop starts while True: run = ret @@ -47,7 +50,7 @@ def run(context): futil.log(str(axisXYZRUV)) - deg = axisXYZRUV[0]/2000 #Angle of one step - degree + deg = axisXYZRUV[5]/2000 #Angle of one step - degree diff --git a/f360-script/commands/__init__.py b/f360-script/commands/__init__.py new file mode 100644 index 0000000..0499301 --- /dev/null +++ b/f360-script/commands/__init__.py @@ -0,0 +1,30 @@ +# Here you define the commands that will be added to your add-in. + +# TODO Import the modules corresponding to the commands you created. +# If you want to add an additional command, duplicate one of the existing directories and import it here. +# You need to use aliases (import "entry" as "my_module") assuming you have the default module named "entry". +from .commandDialog import entry as commandDialog +from .paletteShow import entry as paletteShow +from .paletteSend import entry as paletteSend + +# TODO add your imported modules to this list. +# Fusion will automatically call the start() and stop() functions. +commands = [ + commandDialog, + paletteShow, + paletteSend +] + + +# Assumes you defined a "start" function in each of your modules. +# The start function will be run when the add-in is started. +def start(): + for command in commands: + command.start() + + +# Assumes you defined a "stop" function in each of your modules. +# The stop function will be run when the add-in is stopped. +def stop(): + for command in commands: + command.stop() \ No newline at end of file diff --git a/f360-script/commands/__pycache__/__init__.cpython-39.pyc b/f360-script/commands/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..923bc4d0fdf42b4035e9ffcdeabf90b2666e17b0 GIT binary patch literal 586 zcmbVJ%}T^D5T5jBTYnb3=*h!gd$EGxK}1}46}*VJcquC-Y(g!zNlmiog5G=rpFofM zO1*mW4MbRQ(p`VfPMFCz(`LRe6WVSs1KP*)j2?LaZ#MaBE+&WQ`UnF9MhYlN0%VRI z#Lfb{h+P64xWnDdO+4l>_X!f8dCbSX#aaW1f_H+AB2xQY7&RGT@?-Xkk@MDLFn}pJi<~+f$+Dz^>Dt$ZDl;W@uqaJIg?Re2?ClLNHCH;$xS-o{ zx2pQo(D*{qG8b9g9UIBGzWD*2ld;aF=1#4&;txd;2EOv^@Qq|#pDcQK-2Udq(!>~$l M`3}J~^OnNk3owm(i~s-t literal 0 HcmV?d00001 diff --git a/f360-script/commands/commandDialog/__init__.py b/f360-script/commands/commandDialog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/f360-script/commands/commandDialog/__pycache__/__init__.cpython-39.pyc b/f360-script/commands/commandDialog/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c69504c95b9bbabf280e4970cfcf039fe5aa0213 GIT binary patch literal 214 zcmYe~<>g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=*XRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&{-&Tz?0%*juWiI30B%PfhH*DI*J#bJ}1 QpHiBWY6o)EXCP((0Q$N+r~m)} literal 0 HcmV?d00001 diff --git a/f360-script/commands/commandDialog/__pycache__/entry.cpython-39.pyc b/f360-script/commands/commandDialog/__pycache__/entry.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd81118b85e732ef110382bc107875ce879d058a GIT binary patch literal 3687 zcmaJ@-EZT@5$BQ=MNuD?Wy`+L9Ggp%C`iti21tv;HH~b^h?=u(*q19p93arzwT?Q8 z6qYNWZOA|$@>HNNeJj!fq{sXV{Zsa}Pxl`b1qyU#Nm>3#Dq)Aav&-S`%x``>ezE9i z@cZ}Q{_B5zN7Md=gUi1x48DdIJ4Dl{M#(_)h~*Y5sk>M9V*D-g|VJR^a(SebJ>W{~&agR(~+PUn$M|O0!1S zLG$pE<`%sTnh%ub*J{ljdKWYwD$PeqbC2E!&BvGCdXGK;O^uQRt>(T%FSXwpAZtXH zj>d5igvE&g-1b8l8)zex+i}kA@NKr)GLtz)FX*BbmF{iOh^Jjxw8?|4HNTLsb5Avi0QU zcQNDfMvsO5Ujfe*ohfa56xt;PebSb2tG+ zGysta(8{FHv7nzt=)f8~?Hd!FKb`2)+)N|d#NgjdjHIuCMA|inBZu)SiZvALC~l#+ zjRJU0<3$vC5Ynb>zy#Z2HIqL;tqa0iAR&q21uiidDKM4W6Y&r&nX!mQzk^;}2BGN% zqW*?SY-s!=(EUWD>GNLP1^T@BVS*vCDv$gVIzpQgp#w3JxB860DYd@QH!+!}86;V1 z(hRj`K(oT?XOUdNLrx#4by}q8F9TMVs7-SdePYZ^m6A)!N?9yJ`Z<3!F6map>J430 ztliM9i(5Bzx5b^gPWeCIK3ltBsx+p+xn;WA7 z=O4X8&umNbxy&E?gE8v_;b<(*9QDcz)F8hOqOL!fr*T}n%a`FTX#l12680cB6tBu+ z+G(McSgt`L;&(TrlQbXIgf#roNEZFB2#y(KA02mvER2DF;*=$21>)|H2jUqEd*ao1 zI0d1k@oQ;zBhI9w_Lf*HCG@d*dLTGt9vG%{G0iJ#hwOxP$AT?5CspuAI9*W3-U6cP z0WVe4QzXvlbW?RHePxfcQ*u61Xs+KyCBm&+W|hi9wkKUI3;#U06sJkP|iB zj-|E}^Dl8wOkL3dD`R#o3-~H5`6IL#b5GODhMlPx4k?kcu}YG^T5}}@5dN43Dg|CZ z=l`bwQi4hbLxElITj%D)=x5I})SQ@DSxhoNYH!VROW4!g#KI&}@U$+&vzbI7fhYe2 zzREuXahCrc?m>mdC+=DK=^_70Db#77xWF$6Hok!Z!Nwn>_#6cuS(=Dr>97-sLX2gA z;v?w{VFVX0K(CfnUgg{P&c%26H#lse31b-duKV@(Fu|aujo>GC1mP9PGmNPhs}w zT(8*Nq`>d0Fv?Klb%y^2;7dAIXaRuXIfrc3eUavIdTvFi3alLI^7%F(>gu_Y-77q1 z6mVt9=P3;+W9gyQI?qu{luxh24x{rIXz9&f)-6b8huAvDnJeeUtz4WN@7wF=hEmtjvE48mUJyTn)h?H(->Q z&tVVu%JIIId8m~JLD$D}QyM)c_!p=yj-i}t;RSUB6=0Ia1t{O3!uwv8oSsu}G+J%d zPf7|!2uo=AJ_=QOsHy`~P?{rOypm==3PRxA0IIAZlUe@|DooJZoz77(V4V)f`a#_T zs(ezFgIrH9tn^Y<5U4{bp~zI0)7ga@89^nTtg67Kxw2S*xRvX3WT`drViu#T9D2#^ zDgY1hHT&rhF3AD=3S%CB3c@CKQtlATTqPzk4buV%PuDa}d(Ey??p9VRcEzbI{SWTF Bw(bA` literal 0 HcmV?d00001 diff --git a/f360-script/commands/commandDialog/entry.py b/f360-script/commands/commandDialog/entry.py new file mode 100644 index 0000000..e00314c --- /dev/null +++ b/f360-script/commands/commandDialog/entry.py @@ -0,0 +1,158 @@ +import adsk.core +import os +from ...lib import fusion360utils as futil +from ... import config +app = adsk.core.Application.get() +ui = app.userInterface + + +# TODO *** Specify the command identity information. *** +CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_cmdDialog' +CMD_NAME = 'Command Dialog Sample' +CMD_Description = 'A Fusion 360 Add-in Command with a dialog' + +# Specify that the command will be promoted to the panel. +IS_PROMOTED = True + +# TODO *** Define the location where the command button will be created. *** +# This is done by specifying the workspace, the tab, and the panel, and the +# command it will be inserted beside. Not providing the command to position it +# will insert it at the end. +WORKSPACE_ID = 'FusionSolidEnvironment' +PANEL_ID = 'SolidScriptsAddinsPanel' +COMMAND_BESIDE_ID = 'ScriptsManagerCommand' + +# Resource location for command icons, here we assume a sub folder in this directory named "resources". +ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '') + +# Local list of event handlers used to maintain a reference so +# they are not released and garbage collected. +local_handlers = [] + + +# Executed when add-in is run. +def start(): + # Create a command Definition. + cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER) + + # Define an event handler for the command created event. It will be called when the button is clicked. + futil.add_handler(cmd_def.commandCreated, command_created) + + # ******** Add a button into the UI so the user can run the command. ******** + # Get the target workspace the button will be created in. + workspace = ui.workspaces.itemById(WORKSPACE_ID) + + # Get the panel the button will be created in. + panel = workspace.toolbarPanels.itemById(PANEL_ID) + + # Create the button command control in the UI after the specified existing command. + control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False) + + # Specify if the command is promoted to the main toolbar. + control.isPromoted = IS_PROMOTED + + +# Executed when add-in is stopped. +def stop(): + # Get the various UI elements for this command + workspace = ui.workspaces.itemById(WORKSPACE_ID) + panel = workspace.toolbarPanels.itemById(PANEL_ID) + command_control = panel.controls.itemById(CMD_ID) + command_definition = ui.commandDefinitions.itemById(CMD_ID) + + # Delete the button command control + if command_control: + command_control.deleteMe() + + # Delete the command definition + if command_definition: + command_definition.deleteMe() + + +# Function that is called when a user clicks the corresponding button in the UI. +# This defines the contents of the command dialog and connects to the command related events. +def command_created(args: adsk.core.CommandCreatedEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Created Event') + + # https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs + inputs = args.command.commandInputs + + # TODO Define the dialog for your command by adding different inputs to the command. + + # Create a simple text box input. + inputs.addTextBoxCommandInput('text_box', 'Some Text', 'Enter some text.', 1, False) + + # Create a value input field and set the default using 1 unit of the default length unit. + defaultLengthUnits = app.activeProduct.unitsManager.defaultLengthUnits + default_value = adsk.core.ValueInput.createByString('1') + inputs.addValueInput('value_input', 'Some Value', defaultLengthUnits, default_value) + + # TODO Connect to the events that are needed by this command. + futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers) + futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers) + futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers) + futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers) + futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers) + + +# This event handler is called when the user clicks the OK button in the command dialog or +# is immediately called after the created event not command inputs were created for the dialog. +def command_execute(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Execute Event') + + # TODO ******************************** Your code here ******************************** + + # Get a reference to your command's inputs. + inputs = args.command.commandInputs + text_box: adsk.core.TextBoxCommandInput = inputs.itemById('text_box') + value_input: adsk.core.ValueCommandInput = inputs.itemById('value_input') + + # Do something interesting + text = text_box.text + expression = value_input.expression + msg = f'Your text: {text}
Your value: {expression}' + ui.messageBox(msg) + + +# This event handler is called when the command needs to compute a new preview in the graphics window. +def command_preview(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Preview Event') + inputs = args.command.commandInputs + + +# This event handler is called when the user changes anything in the command dialog +# allowing you to modify values of other inputs based on that change. +def command_input_changed(args: adsk.core.InputChangedEventArgs): + changed_input = args.input + inputs = args.inputs + + # General logging for debug. + futil.log(f'{CMD_NAME} Input Changed Event fired from a change to {changed_input.id}') + + +# This event handler is called when the user interacts with any of the inputs in the dialog +# which allows you to verify that all of the inputs are valid and enables the OK button. +def command_validate_input(args: adsk.core.ValidateInputsEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Validate Input Event') + + inputs = args.inputs + + # Verify the validity of the input values. This controls if the OK button is enabled or not. + valueInput = inputs.itemById('value_input') + if valueInput.value >= 0: + inputs.areInputsValid = True + else: + inputs.areInputsValid = False + + +# This event handler is called when the command terminates. +def command_destroy(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME} Command Destroy Event') + + global local_handlers + local_handlers = [] diff --git a/f360-script/commands/commandDialog/resources/16x16.png b/f360-script/commands/commandDialog/resources/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..03babdc056577fea50543b03d15c480d88c89f4c GIT binary patch literal 415 zcmV;Q0bu@#P)KA9k4D0+<1qc$SunL_18+0mJ|no~1oAf13dfUQ*u%01+5>;@Y z)*+9ui?QG#{8m7wjtRZ_7;GpXT!7Xr);$MsL(ih)&$~U6?q5HKp5f86w1-XuNy<+m ziM)=y6Z(%>u-E%a+b3{!z~(0Dcce}w4hGl2o zy!Y*!_hU9;+cvg|2T^S6rX^)vFJ%&8b=}+Q=c_!Rn^p=y6@XDMWu{S-Z=yr$0lx7w zfD`uQ?@^2g>JWm^v+>X~-24*Dhu;%x1PJ3R3<2zK=m1JqAmKlP zDq$QUjH_f1xeXV70tRP!SLksYasu2n+8vPyj)4_;EL;NEjmh{7Ku(s5R3S27}iUf9JR=g?(3!*!+J;9 zUT_wma2h1zM_2-vG0C{tdN&M9fIR<@GLZ?KsX8NH3l#%YA*w1m9+ieEZyG*X{=mcA zg}c6U`{&Ev_0^}zWO8K~#>XH6%#Gg_#E1M#R{@vf?{50-efxleXHSKVola*wo6X)d z8jW}Cohn3AUOuU6$P8U52s$Vhi^5#D+huOKD3{A%Bm@GUJ3(B1fPzC}jX=PKBo-VW zYmdg`k<&K@gTY(B2UHi5Sa5Xo;xPa=P^;C17+}rfd7M|WX0wUWXe0>a^LgjFMu4T3 zZdzI#m(ql7{{(Pf(=;p=3qdfQPNU!Ni&-Ec;l0VQVd$nMB~UMA+;&^(-TY>OoXuuc zo|31bhs6KCB90w|u j%CBTHsr;pz&*%6H8=VB7i~>0q00000NkvXXu0mjfNzF8J literal 0 HcmV?d00001 diff --git a/f360-script/commands/commandDialog/resources/64x64.png b/f360-script/commands/commandDialog/resources/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..dd285fd1c9a47ff154e426da5c90fcdd96239c2c GIT binary patch literal 1077 zcmV-51j_q~P)ZWvYv= zx{iE7uCu6eC_iv#i2_oDd_h3U2V4qV&?G1gA|e+p8iVi7XYZ_c_iU3VU16PXXWqN@ z?9A+XW-u7wA!GJIvj_0lmLWfkSW_)^9A4)TT$bSUz1i%S7VI6)LtqJ=8o~!!779c@B##BTgKfaKCsQSSY zAccGkt0L(1Lpl@8Fq*{WXiOky8UVIrog(z;+3p6e^Q)*IlOQF4q|v1DB@vW}_)E#( zW#It8o*>2aBUgl60hr{=hFlRc1)%ABk_a@l6JcTy^uuVr2ILV3#z|jJ6o3Lx!p^A!-OI|=a6RemBQsf0#sW1)tPT4Ix zkR~snQVxss^n(T}KLGR-*Gp8@6~)9QFAXXJ>=krSq_yp|#KaFHA;LB-TdMiT9*rRd zR$H8sqo0b7oe9Te3KX&(b;MNus$f&v&$~x}+qY-nP2f7Lz?1|%4t?D)7bTX)8G~s7-qHr9GAI)?)||C*KA=q`RM9orn&+0o z9fdtUs1`&8>>W@cl?$!_VyEbvf<6Td zj*eLOZ)|J~U1tg)c3J%}LYYN4K0apMKPrHU6Cxtzd_}*})fg4&^9vK_6Qq_w#!N^a zNfV!r=98iw?{L_M_4Re;u)~n91tdgBJ&#A%+kP0a1PEM5s+~4ErMXZ!A(A!?rO)P; z4eVklA;M+V$qOjGF+z{SDdh=`X_7a(3}!))77YxQeSe)Wz6@qz+T?Y>+KZE>U~L&J vE37Vqb%eDUVC!9AE-Lr>yytoP90u?YjV+lgrL2(V00000NkvXXu0mjf+LYiK literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteSend/__init__.py b/f360-script/commands/paletteSend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/f360-script/commands/paletteSend/__pycache__/__init__.cpython-39.pyc b/f360-script/commands/paletteSend/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01a32545552f8c5783f2b0a43819c2d2a01120af GIT binary patch literal 212 zcmYe~<>g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=bXRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&}zIHn*mC$*#`H8?ddB_=*TGcU6wK3=b& V@)n0pZhlH>PO2TqNuPn30RVtWI`9Ah literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteSend/__pycache__/entry.cpython-39.pyc b/f360-script/commands/paletteSend/__pycache__/entry.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5ab94ac043b1b449706df8a0d1f178e1cae5d88 GIT binary patch literal 3541 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 literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteSend/resources/64x64.png b/f360-script/commands/paletteSend/resources/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..ed1ae276ca4eb5a06999f3e340cabec2f571653a GIT binary patch literal 1972 zcmV;l2TS;gP)P|5NA&mlJKR z&5-rUiU3anqGn@N%V=cMnVd%X^-719(I87e8jm4u9|9^6O=}qzGU=Q~`SnUiTFZdE zsVdSpPXZtt1raL(28T|CZD(jOBOrqG$y3nn1SkOe_ue0-ZOe@%Q@WaeV0vZ-P18fO zXgQ#&QC6r0t~s~OKOh7chUeU&;vsyP??8Zf4-ini{mujk*NIbAARqz%9|9PLdjuT+ zb1nb4m_2Rt8jUZ1bk3iJAtU$@@Q47r^H#mmBBl%k_|pKV_7DBK!B-!C@$_9O*WZ?1 z1Dx95z9HOU;bmi}8nCf7&A&!#a_Ua)Kk>oY;;kqFUO^go2--i!a0CeRY0yt6PEU`UHf}8X z{8Hfd#Og*syrTzzF^ zO$}Ibe-Ox5$T_eypc+af5?xSZt(}Jkjx?&V*3Ng*H}2^D`tC1^Tmn2va3P>NN+c4| z0Sp1(?H_1TYvbF`&)smx?ymdpHXV1}8e^d>S>S3xShrfh^gKM77-;%t&z>ExUr^J) zV}Oo-0=z|V_>Ezb$>d@^9*@(}-Vwl!;4pyE85s%RNena{*t_SBrklPrKk@gUJiOGo zzBRz^JU}v;ylNUCZ<0`iAs0bLry+F(4n95599>cO>E#<(INDe0ohJ@?>0AB<+>?ioZ`s-cWzkKTFrx#Xj+o{Ilw-$Yo zJX}N(^_#Z=0z>4!oVheDhr`29^~WFI*R!joy-SR}akLk?WiE#V-x|=|)WZ10SWew3 z0@hu(-qrY6tZrdOZSDN__Xir6^t1>}Tq%4zH8LfS9XOO|ec~HE_q4Qk;Y5P(A+YJg zHx(T7`zA?IvgzyJmwcV-3nNof8+yN&XzknYOhSPOf+Qi#g2}#agkLUB!T4p^|74<7 ziPYTF(%#hvtiaqr>6`^ZE;3$(q6^TB@XLiM7{3Dh`XmX+jp0#1anu0eGYj~I5Hj)% zV|m^zU%MJsUjt9|?in{Sv%f+TkOs6u0ua6y6oSBtfH2Xv8dlfB;csIvlU{zf$qYE+uHe4ILzlm8Xc=>3nhx%Ih;eqayJ~#Htl`WrXy+7+#-zpES_cON`j^UvIsI@Z)fQym<6 zq&ua}jh#uI8#)3^0u#U#Fb8PXF7a!CRX`)q0MsGJiDQ;15gL%Oeb(5@3jC36*&S`! zy8D^0K60eNPJre7vyUx0|05uUBw!ktMQVVdB11t37J$oUAM+&`wG?!u^HvC|<~3@_ z{%@gJM9gznVy=Q)V!E~g8e)#lr+^vcozIvy2#Wv>NdV@LDn;zI_X+zD5N7}O;^$gc z)YgF_2@qN5k3H__y#3DS%ml54gS72)Q6+=>+Z2!_XdowV z&-ZmtYI9>}y_}DC^oS*w#g`Kgb?+_pR4ZCFePR04^L=~n)aNH&N}U@zhD>pe&O3Ef zt^W|UG{8#TF{Cf^NXKXJ2zxuCVOts!>;eihbIl>s_+|6^lFq|b9s&VirS5s;P>7nx zGDycW6yZEn?+~y@K-B!SCUo|>eo-A&E9@y$A?vWOZ1z76&6OwtiJT<>0000g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=bXRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&}zIHn*mC$*#`H8>-`JSILqGcU6wK3=b& V@)n0pZhlH>PO2TqNuPn30RV$AI|l#& literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteShow/__pycache__/entry.cpython-39.pyc b/f360-script/commands/paletteShow/__pycache__/entry.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6e754a287537dd32eca8b93136a63dc2867ac3c GIT binary patch literal 4580 zcmaJ^TW=f372X?{%d03#^4;>jZr~HBz0Sfe-*`+8cK}qcJ%$ecL>^a~0&Kb8< z$}8~s&tLxQ{^6#g{0lp0KUwJf5}x>TRZ)mS)If2PU)9lMUw3q(5j`-v8OKx=kc}YQ zwHym%g=B(UH|OM3g=&7@FN}&~#VOH}Uv_4w;uc+y>2ksd+%|z&fvy*Fp3CnRS-P8=(1ssC!E7&F|3m&F^$* zYpN(8_G2#!-~Y+IKKFtcG-f*r54{dZ7I8V{UY82BxM)q zZG7d)#{j{EXBD1!7aFek>PX`{H+Y7dW8*~O*^xC={2b4ZH5JDJRJ=4+Pt>96mqDHZ zSsQA8Wi&ffc$KJQ{Y2+;L%lUm6fm;ZT(2z%t?!9yJ2^yy9(tk2!PK#sa|wCe=R69h zT4AnkHCh`DVc~DHzO^Q1P-@Uvz9;-q6gF13o2~Wj&BofU$Q+`>L;==n9l=`$l! z*(#&pIU;7#eyg1-^2ZT-7WZ7Vy5(`&ef)BRh~j74yC3iE)K}N=03{wp!GX)9NnzSf zy}7n2PX@r?EDBpm0cWCI|Tdwzd4VSyiyOG=V z!p?HN&m%(PXQ#p$04~>eHkJVy8)3Y>_JUIux`918{?pVd@zY)cUc~ZK02X_BxA#(H zV(v1257AMCM$xKz*(mBoy`r4E3^n#-sErC^MOB76+aKzwY_QLVMj}gism)rE&A@K#8aCIlxq%JPtHKts zxrI#?n+i0-N?#Rxw^QF-+uxUtvIxb9-lDY(Tf(_-;M^%{5`Uj!7#){_SY*=$rLU5v zhJQ9<9`)8iiZ4NV|5i54#T|->AZHSto7->7Ra3Mw3c&J_La)Bb94F-RdiC ztjbu_(X2j1D$f$_OZ|+_;<<@Vnn`aCuB_N8Q0+7ZZ2BBreHW=Oh}v#237)u?XLw|x z2T_O3fy6Fj7hsvNNS3~!?LMbd`=ko?ft&|egy?uV9ZnVO0j`CRo|=hWg>DO;7@0`X zD*C)Cb?2;sz$(Bat??}gKd^@G8^}o`%Te{bYAjxy+6f3`n7xBt8D{T-By`|EQJe&lB~C#~%4F7Lg#8?k zgdrk|Bx*l{$$K0~AA*X+&xFyA7!~t73BfhaOo+vmGg|qd^&pbR5i^sQXl$>3ywUuK zJ%aUXI(r}Yk~TnEyolwWfzF2~M%w_EHB-&2mTIWl#qYn(LRrP{qE=B&jp0AfAs*u& z^RqsMek}H$z?47269f9-ybSy2PJwZE zdI}u9cnV-3{X_+c`?T787NxlqTrk)pip9LZdwAkv#or~W86|DaiJZZA5 z=q7M}RnMyoM}TH?7}KpEP<;+YvGSL${wD|*jm-6t0ftVpr{bF@KxEL*`j($d&8`oD z*oK%MzzIK9POzUrr@Ydzhbs8CcJR^-Ml9stkc>ff{E=)vD z>eSVfu$?%1ehssb&1jo?&ndAFA<%8M2WA*p^){A?EB3&|dS}IUs$Ck#P|zY9q_Hb= z=lwwm%zEDrBW}l77-K?xAe9eJm4mH%nCxmFL8Kf|8rp{*o9xMtsErOnXr%=_g26`p zVH5<>F=7xd0`AJg1GfBVF!S)>QF6kE%Lk9(lvSw*EuQ5^bPrOUwe)0VX=`O^Z;;vk z*nZEhEnEmzVfZmrxfx(10+#~ZQ<$zahA6<1;ULm#!i1M4lu7oRf}DK{)?=SRBlHgC zvOW^|)O3%d7Yqvvp@-42upm<(%8N~&QQl`E8oHKaPho~rO#jlt132YLFF6SNEpGBV zY<@47!-(jhRA~1Z11Idmed%J1Y{G=U!4uoiAVU^`{i+jgqLPkI)tC&$O-ul%*7%5ql)1rl4kjZp*GvnD zD4dQU*@_a@3R4{dNqX)K9^XQptkkWC-H7x9`Uv3_qk}ET+7gX`M?fglq(<`9P2&z+ Zfbyp7>$YJS)+Os|wNPEGn$=2m@qhgV%ZLB~ literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteShow/entry.py b/f360-script/commands/paletteShow/entry.py new file mode 100644 index 0000000..f48c1c4 --- /dev/null +++ b/f360-script/commands/paletteShow/entry.py @@ -0,0 +1,193 @@ +import json +import adsk.core +import os +from ...lib import fusion360utils as futil +from ... import config +from datetime import datetime + +app = adsk.core.Application.get() +ui = app.userInterface + +# TODO ********************* Change these names ********************* +CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_PalleteShow' +CMD_NAME = 'Show My Palette' +CMD_Description = 'A Fusion 360 Add-in Palette' +PALETTE_NAME = 'My Palette Sample' +IS_PROMOTED = False + +# Using "global" variables by referencing values from /config.py +PALETTE_ID = config.sample_palette_id + +# Specify the full path to the local html. You can also use a web URL +# such as 'https://www.autodesk.com/' +PALETTE_URL = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', 'html', 'index.html') + +# The path function builds a valid OS path. This fixes it to be a valid local URL. +PALETTE_URL = PALETTE_URL.replace('\\', '/') + +# Set a default docking behavior for the palette +PALETTE_DOCKING = adsk.core.PaletteDockingStates.PaletteDockStateRight + +# TODO *** Define the location where the command button will be created. *** +# This is done by specifying the workspace, the tab, and the panel, and the +# command it will be inserted beside. Not providing the command to position it +# will insert it at the end. +WORKSPACE_ID = 'FusionSolidEnvironment' +PANEL_ID = 'SolidScriptsAddinsPanel' +COMMAND_BESIDE_ID = 'ScriptsManagerCommand' + +# Resource location for command icons, here we assume a sub folder in this directory named "resources". +ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '') + +# Local list of event handlers used to maintain a reference so +# they are not released and garbage collected. +local_handlers = [] + + +# Executed when add-in is run. +def start(): + # Create a command Definition. + cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER) + + # Add command created handler. The function passed here will be executed when the command is executed. + futil.add_handler(cmd_def.commandCreated, command_created) + + # ******** Add a button into the UI so the user can run the command. ******** + # Get the target workspace the button will be created in. + workspace = ui.workspaces.itemById(WORKSPACE_ID) + + # Get the panel the button will be created in. + panel = workspace.toolbarPanels.itemById(PANEL_ID) + + # Create the button command control in the UI after the specified existing command. + control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False) + + # Specify if the command is promoted to the main toolbar. + control.isPromoted = IS_PROMOTED + + +# Executed when add-in is stopped. +def stop(): + # Get the various UI elements for this command + workspace = ui.workspaces.itemById(WORKSPACE_ID) + panel = workspace.toolbarPanels.itemById(PANEL_ID) + command_control = panel.controls.itemById(CMD_ID) + command_definition = ui.commandDefinitions.itemById(CMD_ID) + palette = ui.palettes.itemById(PALETTE_ID) + + # Delete the button command control + if command_control: + command_control.deleteMe() + + # Delete the command definition + if command_definition: + command_definition.deleteMe() + + # Delete the Palette + if palette: + palette.deleteMe() + + +# Event handler that is called when the user clicks the command button in the UI. +# To have a dialog, you create the desired command inputs here. If you don't need +# a dialog, don't create any inputs and the execute event will be immediately fired. +# You also need to connect to any command related events here. +def command_created(args: adsk.core.CommandCreatedEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Command created event.') + + # Create the event handlers you will need for this instance of the command + futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers) + futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers) + + +# Because no command inputs are being added in the command created event, the execute +# event is immediately fired. +def command_execute(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Command execute event.') + + palettes = ui.palettes + palette = palettes.itemById(PALETTE_ID) + if palette is None: + palette = palettes.add( + id=PALETTE_ID, + name=PALETTE_NAME, + htmlFileURL=PALETTE_URL, + isVisible=True, + showCloseButton=True, + isResizable=True, + width=650, + height=600, + useNewWebBrowser=True + ) + futil.add_handler(palette.closed, palette_closed) + futil.add_handler(palette.navigatingURL, palette_navigating) + futil.add_handler(palette.incomingFromHTML, palette_incoming) + futil.log(f'{CMD_NAME}: Created a new palette: ID = {palette.id}, Name = {palette.name}') + + if palette.dockingState == adsk.core.PaletteDockingStates.PaletteDockStateFloating: + palette.dockingState = PALETTE_DOCKING + + palette.isVisible = True + + +# Use this to handle a user closing your palette. +def palette_closed(args: adsk.core.UserInterfaceGeneralEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Palette was closed.') + + +# Use this to handle a user navigating to a new page in your palette. +def palette_navigating(args: adsk.core.NavigationEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Palette navigating event.') + + # Get the URL the user is navigating to: + url = args.navigationURL + + log_msg = f"User is attempting to navigate to {url}\n" + futil.log(log_msg, adsk.core.LogLevels.InfoLogLevel) + + # Check if url is an external site and open in user's default browser. + if url.startswith("http"): + args.launchExternally = True + + +# Use this to handle events sent from javascript in your palette. +def palette_incoming(html_args: adsk.core.HTMLEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Palette incoming event.') + + message_data: dict = json.loads(html_args.data) + message_action = html_args.action + + log_msg = f"Event received from {html_args.firingEvent.sender.name}\n" + log_msg += f"Action: {message_action}\n" + log_msg += f"Data: {message_data}" + futil.log(log_msg, adsk.core.LogLevels.InfoLogLevel) + + # TODO ******** Your palette reaction code here ******** + + # Read message sent from palette javascript and react appropriately. + if message_action == 'messageFromPalette': + arg1 = message_data.get('arg1', 'arg1 not sent') + arg2 = message_data.get('arg2', 'arg2 not sent') + + msg = 'An event has been fired from the html to Fusion with the following data:
' + msg += f'Action: {message_action}
arg1: {arg1}
arg2: {arg2}' + ui.messageBox(msg) + + # Return value. + now = datetime.now() + currentTime = now.strftime('%H:%M:%S') + html_args.returnData = f'OK - {currentTime}' + + +# This event handler is called when the command terminates. +def command_destroy(args: adsk.core.CommandEventArgs): + # General logging for debug. + futil.log(f'{CMD_NAME}: Command destroy event.') + + global local_handlers + local_handlers = [] diff --git a/f360-script/commands/paletteShow/resources/16x16.png b/f360-script/commands/paletteShow/resources/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b8e5705f6c5544667a8ea92580d82360687e34 GIT binary patch literal 340 zcmV-a0jvIrP);xMdD{U>TEPR43wo$aQ@EP(1mX;P~ zGMS&mVj&Yl2)nu6z&(fijR%Z?9^LX80KK9p&PP|bbJNd{_XGe@6m=ZHR1n8;C)o46 zsleJCo9A=E3%>6bXl>BOa5-Kn3r|DQDp(8xC&;uxN(DH9NEO#F8;$V8*$-ie6DXw- zsr*+GspPKz-6#+#_`X+JkZBSjx!L_HOG*0$wG)))H<7JCJ literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteShow/resources/32x32.png b/f360-script/commands/paletteShow/resources/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a61a47e4710bdc2aedde29ee1f9f4f0b25d8c82a GIT binary patch literal 587 zcmV-R0<`^!P)do&Mr37>Z`J(s>*sC z{uEW5lPmy5Q8X}Nppp-uDs>t_R9Y#xw=v&xdUjzq8Nfa*I{-wZJ0Rum5b275DAx9; zAbh+3?!X|?C+C0s3qY{8f0g0ez)sSn$Cz4c8X!cV55O1b z+Uqxigl}EH)&TTv!$|~S;sI`4xjYCU_}2ivMd(mZaP`u~)&!{v)ELuKgsMzj128Ky z#^5w^66OGio`eD5?T7a*$JOzB)jy9n!+EC8H1eyTM=s&=hE1=F2 z78efB9>8nu1rT6+>FAODdx2(b7T5;F0Q0~h;2`xoF^ByEz5-ti^&4%@ix)AkgeD&1 Z=Wl;YQq&g|YVQC5002ovPDHLkV1iU;1q1*9 literal 0 HcmV?d00001 diff --git a/f360-script/commands/paletteShow/resources/64x64.png b/f360-script/commands/paletteShow/resources/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd5dfcb2d51b5651ff4fcc8a4f757af32a172a5 GIT binary patch literal 1165 zcmV;81akX{P)% z&x;&I6vscc+pd`ng1BxNLQoO|akDB}6N3aJNOV0Y2oeY$)=NSlC&i2Zh2SY5@nQrC zFIn=)32v$-uuq`Rozv} z7{k*H4?roU00o=@PDG!Z2m@RLE&#?DW4!2w0(Jl&UcB_{r{mJD3ap&^$OC=^9syef zc)(7e73hG@>N+1Uzq2*y%GEzASF{YYcg+E`2yOL&UQEC=FbnMP`#$|%e_-J7^`ye@ z`w)8iEbtJb8~{uKGl19g`#kRV1_lmaPbzwTA3~dF2yNaXfJmTX54d>gO7$9+jK~8N zk?}A{003Wqd8R^@#*YL68ygStgJ2xGln!rt8qb>^lnsB$7=zKxY>v!S(yk-{fNp4a zC|Q*t0Apxudo0)`gaGKKhJav}m;LtktA zoISR=O%=<9eF&KB5EwQ-mgS8bH|#>d80RD?jr;1C=bh$q!8f1$n|a@o0QV{&jaxoY zU0CGlU3wLe#=XD4>ok|!?`Pj1SqLob>T!2&Pq~DLBke_s=EQXB8Rvsh| zII?u8_(YD#O5RG@hJZHcKxY!rYPHzh+)T)HP~RM&l)TJOO@dhjteiS2%Ilm2?L8ps z1e^9yC?p^$7d;@z@qkH00S_<@_JBeJq%-jQ^&8xO@L)i;XZLR2d-wPVR4oTesbZaA z76HS?$Fh1SL2ClY^?)=;b@->tmkZD1iqB5U)d>nDK^-lJT?mkt(TfKc3eV$;tYy4H zA@#RTIUo&^2P_W=kptT8Hl0oO(520#YCF@=JRQ z&*O>_b%N1m$qWMKUU-r9fBsI$>Rvgl-wo#FfW^hvMR}b!SA{vistS->1ttkmiq+V%V3>hT?T2e2S{0PD)Aj;SDADeBfsz!li;DnSIXCD9LPz68o2%D8~dLF zo<;DE35NzA1Gl5kz!L&A&;x!3{sQKJXDU{(Z1jP3;2xo^8lDgk09{};x?U$dOV}g? zzy_g>-RK%+j6o?iMR=faC*h&Ot#fq^LhR*T;6LDzF-FG(#D}Ln!hgPL#>dcv|GZCh fcv>~F + + + + Title + + + +
+ +

Fusion 360 Palette Sample

+ +

+ +

Send Data to HTML Event Handler

+
+ +

+ +
+ +

HTML Event Response Value:

+
Response
+ +

Message from "Send to Palette" Command

+
+

Message from Fusion

+

+
+ +
+ + diff --git a/f360-script/commands/paletteShow/resources/html/static/palette.js b/f360-script/commands/paletteShow/resources/html/static/palette.js new file mode 100644 index 0000000..dacdafc --- /dev/null +++ b/f360-script/commands/paletteShow/resources/html/static/palette.js @@ -0,0 +1,48 @@ +function getDateString() { + const today = new Date(); + const date = `${today.getDate()}/${today.getMonth() + 1}/${today.getFullYear()}`; + const time = `${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}`; + return `Date: ${date}, Time: ${time}`; +} + +function sendInfoToFusion() { + const args = { + arg1: document.getElementById("sampleData").value, + arg2: getDateString() + }; + + // Send the data to Fusion as a JSON string. The return value is a Promise. + adsk.fusionSendData("messageFromPalette", JSON.stringify(args)).then((result) => + document.getElementById("returnValue").innerHTML = `${result}` + ); + +} + +function updateMessage(messageString) { + // Message is sent from the add-in as a JSON string. + const messageData = JSON.parse(messageString); + + // Update a paragraph with the data passed in. + document.getElementById("fusionMessage").innerHTML = + `Your text: ${messageData.myText}
` + + `Your expression: ${messageData.myExpression}
` + + `Your value: ${messageData.myValue}`; +} + +window.fusionJavaScriptHandler = { + handle: function (action, data) { + try { + if (action === "updateMessage") { + updateMessage(data); + } else if (action === "debugger") { + debugger; + } else { + return `Unexpected command type: ${action}`; + } + } catch (e) { + console.log(e); + console.log(`Exception caught with command: ${action}, data: ${data}`); + } + return "OK"; + }, +}; diff --git a/f360-script/config.py b/f360-script/config.py new file mode 100644 index 0000000..ad5c982 --- /dev/null +++ b/f360-script/config.py @@ -0,0 +1,22 @@ +# Application Global Variables +# This module serves as a way to share variables across different +# modules (global variables). + +import os + +# Flag that indicates to run in Debug mode or not. When running in Debug mode +# more information is written to the Text Command window. Generally, it's useful +# to set this to True while developing an add-in and set it to False when you +# are ready to distribute it. +DEBUG = True +VERSION = "0.1b" + +# Gets the name of the add-in from the name of the folder the py file is in. +# This is used when defining unique internal names for various UI elements +# that need a unique name. It's also recommended to use a company name as +# part of the ID to better ensure the ID is unique. +ADDIN_NAME = os.path.basename(os.path.dirname(__file__)) +COMPANY_NAME = 'ACME' + +# Palettes +sample_palette_id = f'{COMPANY_NAME}_{ADDIN_NAME}_palette_id' \ No newline at end of file diff --git a/f360-script/lib/__pycache__/conversions.cpython-39.pyc b/f360-script/lib/__pycache__/conversions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c5f7f3385b845ed0c68f7200ebfd36117e3b3b5 GIT binary patch literal 970 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 int: + """Corrects axis value (its hard to explain what it does) returns 20bit int (-2^19 ; 2^19) + Parameters + ---------- + value: int + value to correct + + range: list + range of axis ( [from,to] ) + + deadzone: float + zone (from center) where value will be always zero + + + """ + out=0 + + + + out=scale(value,rang[0],rang[1],-524287,524287) + if out<-524287*deadzone or out>+524287*deadzone: + out=out + else: + out=0 + + return out \ No newline at end of file diff --git a/f360-script/lib/fusion360utils/__init__.py b/f360-script/lib/fusion360utils/__init__.py new file mode 100644 index 0000000..56e95d5 --- /dev/null +++ b/f360-script/lib/fusion360utils/__init__.py @@ -0,0 +1,2 @@ +from .general_utils import * +from .event_utils import * diff --git a/f360-script/lib/fusion360utils/__pycache__/__init__.cpython-39.pyc b/f360-script/lib/fusion360utils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcdf4aa6709f93e90847e3c9447fa4132baea468 GIT binary patch literal 263 zcmYe~<>g`kf*+IqCRzdM#~=IdZ~=4R%l>pPZ~139}G I?~GX9cW`x)An*dkwcxY#%UK&fW6X?2SA zsW+`0RG-wQ?72U!z2KZpYmnQM4WF?MrL2&Na1w}_Od?A~wylL7=`iX?S{2KkW>etX zFoW?B^4fJbEl%FJAs*sHF-dznI?Ti*9g97gWW+8^lZ0q;;f{_wUn(tTEc)Xl%%U`b z1TqtQQ5?^XIFZ~1#X$m-4s8fG!X;y?MU;p*9SovmARO$_&e}ALWCk_%qHG&%B3mj% z`jp>2sBHEk@F3kC&$NGhshDYn!?;Ivpf84U28L6mrF(IS+T1pd#O={ z{3qR@&?Js<61SGl;V>M^L=H$Q;4!*f_w?QRV?AN{{M@NASp@oH(yMMZ5)I349~cy<{$>6A0i%8Hq$DE^MR3 zDcqt&>5)d4Wbs7wQzNttw-F6P90cC(*t*f#*d()fA`3p8hf;}85e(9b&}eeyj&RDT zl9bHiU3y)k@dE-f6lKaMFzY>MCsVRTyW3WCBY|idPHjnV=A_#J*iO4df}aMBO~8<+XxgnIBD% zO-9;K+JDK+Mg0A}zq$VSC##KJ8|XydT-z9pzLA++yPwJ-th}}{&QhiA?tCD=h53;* zKKmS-f4sYfymmLSYj=Ljv`OGf$Um7$WBWLcdXM{VFSd@e2qc$N0yplACiyZ{D;0Pf z!dO?2uC(}hewH`6xdd8>cH*Oqzlml^UsM~^CCah;*EY#Jt#ivouU?4p!T?l2mdb0b zLt&wN3taQnlYadLUFYh9Z{ESU?H4#Z#OGj#RVbI-=;x*knw_N_V zw>#gvB5y)+f%2mH0T48p+-+q%&os#qXA%W9QGD6)+_X!63t*3B<1J2pcEV;-b zC5OaM9pw>Ayqm{T8?r;&GwtBg)jRGrSh1POeX2MvR%X0M}zmL8h#*FEn2;{$%rqfzUF#xiXD56wU$O6yQotc|IzuBbKiV3VgzuX=FRVUXN_Tl64978 zhs~cz(WV4{JQ_BCCPna=c+1vwn@4FN?v;{g^UCXxSNYa&mEnEffb%x5y$*Pt$8hq1 z(;rEv`3~YChwnn59qOtRRit^=?}Tn^CX7ik;VM%6BBX1jN>9WH6pWH$f(Dxv0aJm! z58J!|V#$iUq?D|vrPE*vX`KbS>-oyG`fF&n-qcoby9%#DN^IRcSq1uVeIMVx_kjkN z{~X&~=61=_MKQ6tDwtJFBqo^v{HI`1<7?ZZyPRpvS`tcwzE&RjH6TDbail|9F17}q+`TIr4KYQP;W z=fb!~KbK-HxeyBALa8!Wd3Nyh_&c|~U$$?p(1|qmPGj>lLUdRI<&gzXZ;5^Y2mh}2 zcTbLu(59D(B6-}~o6nymHtD@k$qY)}+gn)0g*p45Vf}@{=6vx4lz$lX_BbCDrgv~* zg)S1w06du$?9)$2QY_ko7)NA23jp=q+1M2VI z1}-X+nHaXssX8C6`#2h_i%EbM>xDd~=K*>MjD-o@K=Wk)5Cp)!B0R8u`d*Pg!t1vy zs=qHGdsF8MAkIUWq9_?rLhiz+$!Bw!r%NWVUnNeVY3e+!std^(01%A|oQ~_*gkqI0aZYZpLCX4xG~zRsTfnH4 zOcgM1w|(6KWe?=r?odXw1In^8IgA7(mI7?Mcd6r<_jP&yYh27DpLyQV_^?y=NYFKC ztA?kSXncuv1Bk0zolL|ynVh*8#&nk0k+_(+V3E6cjg_bBLVth;i1v~^MAK&Zq>OyY zKZg^8A0Tm?eiBAhBPctx-+AZ)W%P$2xjIg27YFryEUp3bBC#nj5-!Yy)re%*g5K&u z0V9z@fchgmBO2dS-9~~bxaOcp6-=rhc^4Y1T{Koomib}?*Mj!p`^alw%@kiq@l6vn Y%npzmg Date: Tue, 7 Jun 2022 20:14:24 +0800 Subject: [PATCH 3/4] yaw and zoom now working --- f360-script/.env | 1 - f360-script/External controls.manifest | 13 - f360-script/External controls.py | 253 ------------------ .../External controls/.vscode/settings.json | 11 +- .../External controls/External controls.py | 244 +++++++++++++++-- .../__pycache__/config.cpython-39.pyc | Bin 365 -> 386 bytes f360-script/External controls/config.py | 1 + .../__pycache__/conversions.cpython-39.pyc | Bin .../lib/conversions.py | 0 f360-script/commands/__init__.py | 30 --- .../__pycache__/__init__.cpython-39.pyc | Bin 586 -> 0 bytes .../commands/commandDialog/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 214 -> 0 bytes .../__pycache__/entry.cpython-39.pyc | Bin 3687 -> 0 bytes f360-script/commands/commandDialog/entry.py | 158 ----------- .../commandDialog/resources/16x16.png | Bin 415 -> 0 bytes .../commandDialog/resources/32x32.png | Bin 701 -> 0 bytes .../commandDialog/resources/64x64.png | Bin 1077 -> 0 bytes f360-script/commands/paletteSend/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 212 -> 0 bytes .../__pycache__/entry.cpython-39.pyc | Bin 3541 -> 0 bytes f360-script/commands/paletteSend/entry.py | 149 ----------- .../commands/paletteSend/resources/16x16.png | Bin 474 -> 0 bytes .../commands/paletteSend/resources/32x32.png | Bin 1067 -> 0 bytes .../commands/paletteSend/resources/64x64.png | Bin 1972 -> 0 bytes f360-script/commands/paletteShow/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 212 -> 0 bytes .../__pycache__/entry.cpython-39.pyc | Bin 4580 -> 0 bytes f360-script/commands/paletteShow/entry.py | 193 ------------- .../commands/paletteShow/resources/16x16.png | Bin 340 -> 0 bytes .../commands/paletteShow/resources/32x32.png | Bin 587 -> 0 bytes .../commands/paletteShow/resources/64x64.png | Bin 1165 -> 0 bytes .../paletteShow/resources/html/index.html | 39 --- .../resources/html/static/palette.js | 48 ---- f360-script/config.py | 22 -- .../__pycache__/joystickapi.cpython-39.pyc | Bin 3238 -> 0 bytes .../lib/__pycache__/logger.cpython-39.pyc | Bin 1438 -> 0 bytes f360-script/lib/fusion360utils/__init__.py | 2 - .../__pycache__/__init__.cpython-39.pyc | Bin 263 -> 0 bytes .../__pycache__/event_utils.cpython-39.pyc | Bin 2938 -> 0 bytes .../__pycache__/general_utils.cpython-39.pyc | Bin 1716 -> 0 bytes f360-script/lib/fusion360utils/event_utils.py | 88 ------ .../lib/fusion360utils/general_utils.py | 64 ----- f360-script/lib/joystickapi.py | 114 -------- f360-script/lib/logger.py | 28 -- 45 files changed, 230 insertions(+), 1228 deletions(-) delete mode 100644 f360-script/.env delete mode 100644 f360-script/External controls.manifest delete mode 100644 f360-script/External controls.py rename f360-script/{ => External controls}/lib/__pycache__/conversions.cpython-39.pyc (100%) rename f360-script/{ => External controls}/lib/conversions.py (100%) delete mode 100644 f360-script/commands/__init__.py delete mode 100644 f360-script/commands/__pycache__/__init__.cpython-39.pyc delete mode 100644 f360-script/commands/commandDialog/__init__.py delete mode 100644 f360-script/commands/commandDialog/__pycache__/__init__.cpython-39.pyc delete mode 100644 f360-script/commands/commandDialog/__pycache__/entry.cpython-39.pyc delete mode 100644 f360-script/commands/commandDialog/entry.py delete mode 100644 f360-script/commands/commandDialog/resources/16x16.png delete mode 100644 f360-script/commands/commandDialog/resources/32x32.png delete mode 100644 f360-script/commands/commandDialog/resources/64x64.png delete mode 100644 f360-script/commands/paletteSend/__init__.py delete mode 100644 f360-script/commands/paletteSend/__pycache__/__init__.cpython-39.pyc delete mode 100644 f360-script/commands/paletteSend/__pycache__/entry.cpython-39.pyc delete mode 100644 f360-script/commands/paletteSend/entry.py delete mode 100644 f360-script/commands/paletteSend/resources/16x16.png delete mode 100644 f360-script/commands/paletteSend/resources/32x32.png delete mode 100644 f360-script/commands/paletteSend/resources/64x64.png delete mode 100644 f360-script/commands/paletteShow/__init__.py delete mode 100644 f360-script/commands/paletteShow/__pycache__/__init__.cpython-39.pyc delete mode 100644 f360-script/commands/paletteShow/__pycache__/entry.cpython-39.pyc delete mode 100644 f360-script/commands/paletteShow/entry.py delete mode 100644 f360-script/commands/paletteShow/resources/16x16.png delete mode 100644 f360-script/commands/paletteShow/resources/32x32.png delete mode 100644 f360-script/commands/paletteShow/resources/64x64.png delete mode 100644 f360-script/commands/paletteShow/resources/html/index.html delete mode 100644 f360-script/commands/paletteShow/resources/html/static/palette.js delete mode 100644 f360-script/config.py delete mode 100644 f360-script/lib/__pycache__/joystickapi.cpython-39.pyc delete mode 100644 f360-script/lib/__pycache__/logger.cpython-39.pyc delete mode 100644 f360-script/lib/fusion360utils/__init__.py delete mode 100644 f360-script/lib/fusion360utils/__pycache__/__init__.cpython-39.pyc delete mode 100644 f360-script/lib/fusion360utils/__pycache__/event_utils.cpython-39.pyc delete mode 100644 f360-script/lib/fusion360utils/__pycache__/general_utils.cpython-39.pyc delete mode 100644 f360-script/lib/fusion360utils/event_utils.py delete mode 100644 f360-script/lib/fusion360utils/general_utils.py delete mode 100644 f360-script/lib/joystickapi.py delete mode 100644 f360-script/lib/logger.py diff --git a/f360-script/.env b/f360-script/.env deleted file mode 100644 index e28bd05..0000000 --- a/f360-script/.env +++ /dev/null @@ -1 +0,0 @@ -PYTHONPATH=C:/Users/gena0/AppData/Local/Autodesk/webdeploy/production/525fe9b2ece26c4d179982b11ecdfb713cb5058f/Api/Python/packages diff --git a/f360-script/External controls.manifest b/f360-script/External controls.manifest deleted file mode 100644 index 377ab05..0000000 --- a/f360-script/External controls.manifest +++ /dev/null @@ -1,13 +0,0 @@ -{ - "autodeskProduct": "Fusion360", - "type": "addin", - "id": "0afdf698-8eed-4eaa-ac5c-d6ae17db8147", - "author": "InTostor", - "description": { - "": "" - }, - "version": "0.1", - "runOnStartup": true, - "supportedOS": "windows|mac", - "editEnabled": true -} \ No newline at end of file diff --git a/f360-script/External controls.py b/f360-script/External controls.py deleted file mode 100644 index e6daec6..0000000 --- a/f360-script/External controls.py +++ /dev/null @@ -1,253 +0,0 @@ -# started experiments with f360 driver-script - - -# There is a lot of code copied from stackoverflow, autodesk forums, etc. -# windows only yet - - -import adsk.fusion, adsk.core, traceback -import math - -from .lib import joystickapi -from .lib.conversions import * -from .lib import fusion360utils as futil -import msvcrt -import time -import inspect, os, sys - - -# todo move to config - -# ranges, centers and deadzones of axes - -zoomRange = [-32767,32767] -yawRange = [-32767,32767] -trxRange = [-32767,32767] -tryRange = [-32767,32767] - -zoomCenter = 0 -yawCenter = 0 -trxCenter = 0 -tryCenter = 0 - -zoomDZ = [-2048,2048] -yawDZ = [-2048,2048] -trxDZ = [-2048,2048] -tryDZ = [-2048,2048] - - - - -class Joystick: - """This is wrapper class for joystick - - Attributes - ---------- - supportedOS : list - list with supported os - - - Constructor - ----------- - requires only id of joystick in system - todo: maybe in other systems name or uuid required - - Methods - ------- - getAxis(str: axis)->int - returns integer value of axis - """ - osn=None - supportedOS=['nt'] - - - axIndex=["X","Y","Z","R","U","V"] - - def __init__(self,id=0): - """ - initializing joystick. Throws "Unsopported os" if os not supported - """ - self.osn=os.name - - if self.osn not in self.supportedOS: - raise Exception("Unsupported os") - - self.id=id - ret, caps=joystickapi.joyGetDevCaps(id) - - self.ManufacturerId = caps.wMid - self.ProductId = caps.wPid - self.ProductName = caps.szPname - self.NumButtons = caps.wNumButtons - self.PeriodMin = caps.wPeriodMin - self.PeriodMax = caps.wPeriodMax - self.Caps = caps.wCaps - self.MaxAxes = caps.wMaxAxes - self.NumAxes = caps.wNumAxes - self.MaxButtons = caps.wMaxButtons - - self.rangeX=[caps.wXmin,caps.wXmax] - self.rangeY=[caps.wYmin,caps.wYmax] - self.rangeZ=[caps.wZmin,caps.wZmax] - - self.rangeR=[caps.wRmin,caps.wRmax] - self.rangeU=[caps.wUmin,caps.wUmax] - self.rangeV=[caps.wVmin,caps.wVmax] - - self.ranges=[ self.rangeX, self.rangeY, self.rangeZ, self.rangeR, self.rangeU, self.rangeV] - - - - def getAxesRaw(self) -> list: - out=[] - ret, io = joystickapi.joyGetPosEx(self.id) - if ret: - # X Y Z R U V POV - axes = [ - io.dwXpos, - io.dwYpos, - io.dwZpos, - io.dwRpos, - io.dwUpos, - io.dwVpos, - io.dwPOV - ] - - return axes - #else: - # raise Exception("Joystick read error") - - - - - - - def getAxisRaw(self,axis: str) -> int: - """Returns value of defined axis - - axes: - - dwXpos - Current X-coordinate. - - dwYpos - Current Y-coordinate. - - dwZpos - Current Z-coordinate. - - dwRpos - Current position of the rudder or fourth joystick axis. - - dwUpos - Current fifth axis position. - - dwVpos - Current sixth axis position. - - dwPOV - Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. - - source: https://docs.microsoft.com/en-us/previous-versions/dd757112(v=vs.85) - """ - out=0 - availableAxes = ["dwXpos","dwYpos","dwZpos","dwRpos","dwUpos","dwVpos","dwPOV"] - if axis in availableAxes or axis=="list": - axes = self.getAxesRaw() - return axes[availableAxes.index(axis)] - else: - raise Exception("Axis doesnt exists") - - - - def getAxes(self) -> list: - axesRaw = self.getAxesRaw() - out=[] - - - for i in range(0,len(axesRaw)): - out.append(int(correctAxis(axesRaw[i-1],self.ranges[i-1],0.05))) - - return out - - - - - - - -joy = Joystick() - -def run(context): -# This section executes once on script start - ui = None - app = adsk.core.Application.get() - ui = app.userInterface - futil.log(str("Joystick driver v"+"/version/"+" started")) - futil.log("START") - - - # this found there https://github.com/Rabbid76/python_windows_joystickapi - - numOfJoysticks = joystickapi.joyGetNumDevs() - ret, caps, startinfo = False, None, None - for id in range(numOfJoysticks): - ret, caps = joystickapi.joyGetDevCaps(id) - if ret: - ui.messageBox(str("Using gamepad: " + caps.szPname)) - ret, startinfo = joystickapi.joyGetPosEx(id) - break - else: - ui.messageBox(str("no gamepad detected")) - - -# This section executes once on script start - - -# Loop starts - - while True: - - - - futil.log(str(joy.getAxes())) - - deg = 0 #joy.getAxes()["V"]/52428 - - - app: adsk.core.Application = adsk.core.Application.get() - ui = app.userInterface - # viewport - vp: adsk.core.Viewport = app.activeViewport - cam: adsk.core.Camera = vp.camera - vecUp: adsk.core.Vector3D = adsk.core.Vector3D.create(0,0,10000000) - - - target: adsk.core.Point3D = cam.target - # matrix3d - mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() - - mat.setToRotation(math.radians(deg), vecUp, target) - # update camera - cam.isSmoothTransition = False - - eye: adsk.core.Point3D = vp.camera.eye - eye.transformBy(mat) - cam.eye = eye - - # zoom = cam.viewExtents - - # if axisXYZRUV[0]>1024 or axisXYZRUV[0]<-1024: - # zoom = zoom - (axisXYZRUV[0]/10000)*(zoom/100) - - # if zoom<0: - # zoom=0.001 - - - - #futil.log(str(axisXYZRUV[0])+"|||||"+str(cam.viewExtents)) - # cam.viewExtents = zoom - vp.camera = cam - vp.refresh() - - adsk.doEvents() diff --git a/f360-script/External controls/.vscode/settings.json b/f360-script/External controls/.vscode/settings.json index bae1447..bb38fc9 100644 --- a/f360-script/External controls/.vscode/settings.json +++ b/f360-script/External controls/.vscode/settings.json @@ -1,5 +1,12 @@ { - "python.autoComplete.extraPaths": ["C:/Users/gena0/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Python/defs"], + "python.autoComplete.extraPaths": [ + "C:\\Users\\gena0\\AppData\\Roaming\\Autodesk\\Autodesk Fusion 360\\API\\Python\\defs" + ], "python.analysis.extraPaths": ["C:/Users/gena0/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Python/defs"], - "python.pythonPath": "C:/Users/gena0/AppData/Local/Autodesk/webdeploy/production/525fe9b2ece26c4d179982b11ecdfb713cb5058f/Python/python.exe" + "python.pythonPath": "C:/Users/gena0/AppData/Local/Autodesk/webdeploy/production/525fe9b2ece26c4d179982b11ecdfb713cb5058f/Python/python.exe", + "fusion-360-helper.enabled": true, + "fusion-360-helper.python.pythonPath": "C:\\Users\\gena0\\AppData\\Local\\Autodesk\\webdeploy\\production\\eb2a69395707b2ba8a2af9d915b9a52ace64d385\\Python\\python.exe", + "fusion-360-helper.python.extraLibs": [ + "C:\\Users\\gena0\\AppData\\Roaming\\Autodesk\\Autodesk Fusion 360\\API\\Python\\defs" + ] } \ No newline at end of file diff --git a/f360-script/External controls/External controls.py b/f360-script/External controls/External controls.py index d36a17f..4bbfddb 100644 --- a/f360-script/External controls/External controls.py +++ b/f360-script/External controls/External controls.py @@ -9,68 +9,264 @@ import math from .lib import joystickapi +from .lib.conversions import * from .lib import fusion360utils as futil import msvcrt import time import inspect, os, sys +# todo move to config +# ranges, centers and deadzones of axes + +zoomRange = [-32767,32767] +yawRange = [-32767,32767] +trxRange = [-32767,32767] +tryRange = [-32767,32767] + +zoomCenter = 0 +yawCenter = 0 +trxCenter = 0 +tryCenter = 0 + +zoomDZ = [-2048,2048] +yawDZ = [-2048,2048] +trxDZ = [-2048,2048] +tryDZ = [-2048,2048] + + + + +class Joystick: + """This is wrapper class for joystick + + Attributes + ---------- + supportedOS : list + list with supported os + + + Constructor + ----------- + requires only id of joystick in system + todo: maybe in other systems name or uuid required + + Methods + ------- + getAxis(str: axis)->int + returns integer value of axis + """ + osn=None + supportedOS=['nt'] + + + axIndex=["X","Y","Z","R","U","V"] + + def __init__(self,id=0): + """ + initializing joystick. Throws "Unsopported os" if os not supported + """ + self.osn=os.name + + if self.osn not in self.supportedOS: + raise Exception("Unsupported os") + + self.id=id + ret, caps=joystickapi.joyGetDevCaps(id) + + self.ManufacturerId = caps.wMid + self.ProductId = caps.wPid + self.ProductName = caps.szPname + self.NumButtons = caps.wNumButtons + self.PeriodMin = caps.wPeriodMin + self.PeriodMax = caps.wPeriodMax + self.Caps = caps.wCaps + self.MaxAxes = caps.wMaxAxes + self.NumAxes = caps.wNumAxes + self.MaxButtons = caps.wMaxButtons + + self.rangeX=[caps.wXmin,caps.wXmax] + self.rangeY=[caps.wYmin,caps.wYmax] + self.rangeZ=[caps.wZmin,caps.wZmax] + + self.rangeR=[caps.wRmin,caps.wRmax] + self.rangeU=[caps.wUmin,caps.wUmax] + self.rangeV=[caps.wVmin,caps.wVmax] + + self.ranges=[ self.rangeX, self.rangeY, self.rangeZ, self.rangeR, self.rangeU, self.rangeV] + + + + def getAxesRaw(self) -> list: + out=[] + ret, io = joystickapi.joyGetPosEx(self.id) + if ret: + # X Y Z R U V POV + axes = [ + io.dwXpos, + io.dwYpos, + io.dwZpos, + io.dwRpos, + io.dwUpos, + io.dwVpos, + io.dwPOV + ] + + return axes + #else: + # raise Exception("Joystick read error") + + + + + + + def getAxisRaw(self,axis: str) -> int: + """Returns value of defined axis + + axes: + + dwXpos + Current X-coordinate. + + dwYpos + Current Y-coordinate. + + dwZpos + Current Z-coordinate. + + dwRpos + Current position of the rudder or fourth joystick axis. + + dwUpos + Current fifth axis position. + + dwVpos + Current sixth axis position. + + dwPOV + Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. + + source: https://docs.microsoft.com/en-us/previous-versions/dd757112(v=vs.85) + """ + out=0 + availableAxes = ["dwXpos","dwYpos","dwZpos","dwRpos","dwUpos","dwVpos","dwPOV"] + if axis in availableAxes or axis=="list": + axes = self.getAxesRaw() + return axes[availableAxes.index(axis)] + else: + raise Exception("Axis doesnt exists") + + + + def getAxes(self) -> list: + axesRaw = self.getAxesRaw() + out=[] + + + for i in range(0,len(axesRaw)): + out.append(int(correctAxis(axesRaw[i-1],self.ranges[i-1],0.05))) + + return out + + + +def transformCameraByMatrix(camera: adsk.core.Camera, matrix: adsk.core.Matrix3D): + eye: adsk.core.Point3D = camera.eye + eye.transformBy(matrix) + camera.eye = eye + + +def changeCameraZoom(camera: adsk.core.Camera,zoom): + zoomOld = camera.viewExtents + if zoom<0: + zoom=0.001 + camera.viewExtents = zoom + +numOfJoysticks = joystickapi.joyGetNumDevs() + +joy = Joystick() def run(context): # This section executes once on script start ui = None - app = adsk.core.Application.get() + app: adsk.core.Application = adsk.core.Application.get() ui = app.userInterface - ui.messageBox('bruh it started') + futil.log(str("Joystick driver v"+"/version/"+" started")) + futil.log("START") + + if numOfJoysticks==0: + raise Exception("No joystick") + + # this found there https://github.com/Rabbid76/python_windows_joystickapi - num = joystickapi.joyGetNumDevs() ret, caps, startinfo = False, None, None - for id in range(num): + for id in range(numOfJoysticks): ret, caps = joystickapi.joyGetDevCaps(id) if ret: - ui.messageBox(str("gamepad detected: " + caps.szPname)) + ui.messageBox(str("Using gamepad: " + caps.szPname)) ret, startinfo = joystickapi.joyGetPosEx(id) break else: ui.messageBox(str("no gamepad detected")) + + # This section executes once on script start # Loop starts while True: - run = ret - ret, info = joystickapi.joyGetPosEx(id) - if ret: - axisXYZRUV = [info.dwXpos-startinfo.dwXpos, info.dwYpos-startinfo.dwYpos, info.dwZpos-startinfo.dwZpos, - info.dwRpos-startinfo.dwRpos, info.dwUpos-startinfo.dwUpos, info.dwVpos-startinfo.dwVpos] + # viewport + vp: adsk.core.Viewport = app.activeViewport + cam: adsk.core.Camera = vp.camera + vecUp: adsk.core.Vector3D = cam.upVector + target: adsk.core.Point3D = cam.target - futil.log(str(axisXYZRUV)) + - deg = axisXYZRUV[5]/2000 #Angle of one step - degree + deg = (joy.getAxes()[6]/262144) + deg=deg*deg*deg + zoom = cam.viewExtents + if cam.cameraType==0: + zoom = zoom-joy.getAxes()[1]/2621*zoom/5000 + else: + zoom = zoom-joy.getAxes()[1]/26214400 + + changeCameraZoom(cam,zoom) + futil.log( str(str(joy.getAxes()) +"|"+ str(cam.viewOrientation))) - app: adsk.core.Application = adsk.core.Application.get() - ui = app.userInterface - # viewport - vp: adsk.core.Viewport = app.activeViewport - cam: adsk.core.Camera = vp.camera - vecUp: adsk.core.Vector3D = cam.upVector - target: adsk.core.Point3D = cam.target # matrix3d mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() - rad = math.radians(deg) - mat.setToRotation(rad, vecUp, target) + + mat.setToRotation(math.radians(deg), vecUp, target) # update camera cam.isSmoothTransition = False - eye: adsk.core.Point3D = vp.camera.eye - eye.transformBy(mat) - cam.eye = eye + + transformCameraByMatrix(cam,mat) + + + + + # zoom = cam.viewExtents + + # if axisXYZRUV[0]>1024 or axisXYZRUV[0]<-1024: + # zoom = zoom - (axisXYZRUV[0]/10000)*(zoom/100) + + # if zoom<0: + # zoom=0.001 + + + + #futil.log(str(axisXYZRUV[0])+"|||||"+str(cam.viewExtents)) + # cam.viewExtents = zoom vp.camera = cam vp.refresh() + adsk.doEvents() diff --git a/f360-script/External controls/__pycache__/config.cpython-39.pyc b/f360-script/External controls/__pycache__/config.cpython-39.pyc index 6911d723abc77614040d3b076455a613eec9036a..a4c67655a98a4ab879feb01a7153f8677e4be26f 100644 GIT binary patch delta 160 zcmaFM)Wpo2$ji&c00gU8<|kE6q8L(`q8L+{qnJ_|vX~dJfJxR= zwuOuf8Kc-!SfV&mIc77Yu%@yDNw&ExQJg7^!3>)0FG1${g;cQ^=ou#6nphwv%5{q= zzxWobi>p(p`z`h`*Pvief4_;7Y#DD&ydcWP2UK3fH}Q2DAIK#fY%Gi{Y$A*-%mB!8 BCA3yETJboO<<#TXyO9bb@`lUh=e z8lRb>$$5(@zxWobi>p(p`z@A&#FC6#97&1Asd_X!f8dCbSX#aaW1f_H+AB2xQY7&RGT@?-Xkk@MDLFn}pJi<~+f$+Dz^>Dt$ZDl;W@uqaJIg?Re2?ClLNHCH;$xS-o{ zx2pQo(D*{qG8b9g9UIBGzWD*2ld;aF=1#4&;txd;2EOv^@Qq|#pDcQK-2Udq(!>~$l M`3}J~^OnNk3owm(i~s-t diff --git a/f360-script/commands/commandDialog/__init__.py b/f360-script/commands/commandDialog/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/f360-script/commands/commandDialog/__pycache__/__init__.cpython-39.pyc b/f360-script/commands/commandDialog/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index c69504c95b9bbabf280e4970cfcf039fe5aa0213..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmYe~<>g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=*XRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&{-&Tz?0%*juWiI30B%PfhH*DI*J#bJ}1 QpHiBWY6o)EXCP((0Q$N+r~m)} diff --git a/f360-script/commands/commandDialog/__pycache__/entry.cpython-39.pyc b/f360-script/commands/commandDialog/__pycache__/entry.cpython-39.pyc deleted file mode 100644 index cd81118b85e732ef110382bc107875ce879d058a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3687 zcmaJ@-EZT@5$BQ=MNuD?Wy`+L9Ggp%C`iti21tv;HH~b^h?=u(*q19p93arzwT?Q8 z6qYNWZOA|$@>HNNeJj!fq{sXV{Zsa}Pxl`b1qyU#Nm>3#Dq)Aav&-S`%x``>ezE9i z@cZ}Q{_B5zN7Md=gUi1x48DdIJ4Dl{M#(_)h~*Y5sk>M9V*D-g|VJR^a(SebJ>W{~&agR(~+PUn$M|O0!1S zLG$pE<`%sTnh%ub*J{ljdKWYwD$PeqbC2E!&BvGCdXGK;O^uQRt>(T%FSXwpAZtXH zj>d5igvE&g-1b8l8)zex+i}kA@NKr)GLtz)FX*BbmF{iOh^Jjxw8?|4HNTLsb5Avi0QU zcQNDfMvsO5Ujfe*ohfa56xt;PebSb2tG+ zGysta(8{FHv7nzt=)f8~?Hd!FKb`2)+)N|d#NgjdjHIuCMA|inBZu)SiZvALC~l#+ zjRJU0<3$vC5Ynb>zy#Z2HIqL;tqa0iAR&q21uiidDKM4W6Y&r&nX!mQzk^;}2BGN% zqW*?SY-s!=(EUWD>GNLP1^T@BVS*vCDv$gVIzpQgp#w3JxB860DYd@QH!+!}86;V1 z(hRj`K(oT?XOUdNLrx#4by}q8F9TMVs7-SdePYZ^m6A)!N?9yJ`Z<3!F6map>J430 ztliM9i(5Bzx5b^gPWeCIK3ltBsx+p+xn;WA7 z=O4X8&umNbxy&E?gE8v_;b<(*9QDcz)F8hOqOL!fr*T}n%a`FTX#l12680cB6tBu+ z+G(McSgt`L;&(TrlQbXIgf#roNEZFB2#y(KA02mvER2DF;*=$21>)|H2jUqEd*ao1 zI0d1k@oQ;zBhI9w_Lf*HCG@d*dLTGt9vG%{G0iJ#hwOxP$AT?5CspuAI9*W3-U6cP z0WVe4QzXvlbW?RHePxfcQ*u61Xs+KyCBm&+W|hi9wkKUI3;#U06sJkP|iB zj-|E}^Dl8wOkL3dD`R#o3-~H5`6IL#b5GODhMlPx4k?kcu}YG^T5}}@5dN43Dg|CZ z=l`bwQi4hbLxElITj%D)=x5I})SQ@DSxhoNYH!VROW4!g#KI&}@U$+&vzbI7fhYe2 zzREuXahCrc?m>mdC+=DK=^_70Db#77xWF$6Hok!Z!Nwn>_#6cuS(=Dr>97-sLX2gA z;v?w{VFVX0K(CfnUgg{P&c%26H#lse31b-duKV@(Fu|aujo>GC1mP9PGmNPhs}w zT(8*Nq`>d0Fv?Klb%y^2;7dAIXaRuXIfrc3eUavIdTvFi3alLI^7%F(>gu_Y-77q1 z6mVt9=P3;+W9gyQI?qu{luxh24x{rIXz9&f)-6b8huAvDnJeeUtz4WN@7wF=hEmtjvE48mUJyTn)h?H(->Q z&tVVu%JIIId8m~JLD$D}QyM)c_!p=yj-i}t;RSUB6=0Ia1t{O3!uwv8oSsu}G+J%d zPf7|!2uo=AJ_=QOsHy`~P?{rOypm==3PRxA0IIAZlUe@|DooJZoz77(V4V)f`a#_T zs(ezFgIrH9tn^Y<5U4{bp~zI0)7ga@89^nTtg67Kxw2S*xRvX3WT`drViu#T9D2#^ zDgY1hHT&rhF3AD=3S%CB3c@CKQtlATTqPzk4buV%PuDa}d(Ey??p9VRcEzbI{SWTF Bw(bA` diff --git a/f360-script/commands/commandDialog/entry.py b/f360-script/commands/commandDialog/entry.py deleted file mode 100644 index e00314c..0000000 --- a/f360-script/commands/commandDialog/entry.py +++ /dev/null @@ -1,158 +0,0 @@ -import adsk.core -import os -from ...lib import fusion360utils as futil -from ... import config -app = adsk.core.Application.get() -ui = app.userInterface - - -# TODO *** Specify the command identity information. *** -CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_cmdDialog' -CMD_NAME = 'Command Dialog Sample' -CMD_Description = 'A Fusion 360 Add-in Command with a dialog' - -# Specify that the command will be promoted to the panel. -IS_PROMOTED = True - -# TODO *** Define the location where the command button will be created. *** -# This is done by specifying the workspace, the tab, and the panel, and the -# command it will be inserted beside. Not providing the command to position it -# will insert it at the end. -WORKSPACE_ID = 'FusionSolidEnvironment' -PANEL_ID = 'SolidScriptsAddinsPanel' -COMMAND_BESIDE_ID = 'ScriptsManagerCommand' - -# Resource location for command icons, here we assume a sub folder in this directory named "resources". -ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '') - -# Local list of event handlers used to maintain a reference so -# they are not released and garbage collected. -local_handlers = [] - - -# Executed when add-in is run. -def start(): - # Create a command Definition. - cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER) - - # Define an event handler for the command created event. It will be called when the button is clicked. - futil.add_handler(cmd_def.commandCreated, command_created) - - # ******** Add a button into the UI so the user can run the command. ******** - # Get the target workspace the button will be created in. - workspace = ui.workspaces.itemById(WORKSPACE_ID) - - # Get the panel the button will be created in. - panel = workspace.toolbarPanels.itemById(PANEL_ID) - - # Create the button command control in the UI after the specified existing command. - control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False) - - # Specify if the command is promoted to the main toolbar. - control.isPromoted = IS_PROMOTED - - -# Executed when add-in is stopped. -def stop(): - # Get the various UI elements for this command - workspace = ui.workspaces.itemById(WORKSPACE_ID) - panel = workspace.toolbarPanels.itemById(PANEL_ID) - command_control = panel.controls.itemById(CMD_ID) - command_definition = ui.commandDefinitions.itemById(CMD_ID) - - # Delete the button command control - if command_control: - command_control.deleteMe() - - # Delete the command definition - if command_definition: - command_definition.deleteMe() - - -# Function that is called when a user clicks the corresponding button in the UI. -# This defines the contents of the command dialog and connects to the command related events. -def command_created(args: adsk.core.CommandCreatedEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME} Command Created Event') - - # https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs - inputs = args.command.commandInputs - - # TODO Define the dialog for your command by adding different inputs to the command. - - # Create a simple text box input. - inputs.addTextBoxCommandInput('text_box', 'Some Text', 'Enter some text.', 1, False) - - # Create a value input field and set the default using 1 unit of the default length unit. - defaultLengthUnits = app.activeProduct.unitsManager.defaultLengthUnits - default_value = adsk.core.ValueInput.createByString('1') - inputs.addValueInput('value_input', 'Some Value', defaultLengthUnits, default_value) - - # TODO Connect to the events that are needed by this command. - futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers) - futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers) - futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers) - futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers) - futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers) - - -# This event handler is called when the user clicks the OK button in the command dialog or -# is immediately called after the created event not command inputs were created for the dialog. -def command_execute(args: adsk.core.CommandEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME} Command Execute Event') - - # TODO ******************************** Your code here ******************************** - - # Get a reference to your command's inputs. - inputs = args.command.commandInputs - text_box: adsk.core.TextBoxCommandInput = inputs.itemById('text_box') - value_input: adsk.core.ValueCommandInput = inputs.itemById('value_input') - - # Do something interesting - text = text_box.text - expression = value_input.expression - msg = f'Your text: {text}
Your value: {expression}' - ui.messageBox(msg) - - -# This event handler is called when the command needs to compute a new preview in the graphics window. -def command_preview(args: adsk.core.CommandEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME} Command Preview Event') - inputs = args.command.commandInputs - - -# This event handler is called when the user changes anything in the command dialog -# allowing you to modify values of other inputs based on that change. -def command_input_changed(args: adsk.core.InputChangedEventArgs): - changed_input = args.input - inputs = args.inputs - - # General logging for debug. - futil.log(f'{CMD_NAME} Input Changed Event fired from a change to {changed_input.id}') - - -# This event handler is called when the user interacts with any of the inputs in the dialog -# which allows you to verify that all of the inputs are valid and enables the OK button. -def command_validate_input(args: adsk.core.ValidateInputsEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME} Validate Input Event') - - inputs = args.inputs - - # Verify the validity of the input values. This controls if the OK button is enabled or not. - valueInput = inputs.itemById('value_input') - if valueInput.value >= 0: - inputs.areInputsValid = True - else: - inputs.areInputsValid = False - - -# This event handler is called when the command terminates. -def command_destroy(args: adsk.core.CommandEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME} Command Destroy Event') - - global local_handlers - local_handlers = [] diff --git a/f360-script/commands/commandDialog/resources/16x16.png b/f360-script/commands/commandDialog/resources/16x16.png deleted file mode 100644 index 03babdc056577fea50543b03d15c480d88c89f4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 415 zcmV;Q0bu@#P)KA9k4D0+<1qc$SunL_18+0mJ|no~1oAf13dfUQ*u%01+5>;@Y z)*+9ui?QG#{8m7wjtRZ_7;GpXT!7Xr);$MsL(ih)&$~U6?q5HKp5f86w1-XuNy<+m ziM)=y6Z(%>u-E%a+b3{!z~(0Dcce}w4hGl2o zy!Y*!_hU9;+cvg|2T^S6rX^)vFJ%&8b=}+Q=c_!Rn^p=y6@XDMWu{S-Z=yr$0lx7w zfD`uQ?@^2g>JWm^v+>X~-24*Dhu;%x1PJ3R3<2zK=m1JqAmKlP zDq$QUjH_f1xeXV70tRP!SLksYasu2n+8vPyj)4_;EL;NEjmh{7Ku(s5R3S27}iUf9JR=g?(3!*!+J;9 zUT_wma2h1zM_2-vG0C{tdN&M9fIR<@GLZ?KsX8NH3l#%YA*w1m9+ieEZyG*X{=mcA zg}c6U`{&Ev_0^}zWO8K~#>XH6%#Gg_#E1M#R{@vf?{50-efxleXHSKVola*wo6X)d z8jW}Cohn3AUOuU6$P8U52s$Vhi^5#D+huOKD3{A%Bm@GUJ3(B1fPzC}jX=PKBo-VW zYmdg`k<&K@gTY(B2UHi5Sa5Xo;xPa=P^;C17+}rfd7M|WX0wUWXe0>a^LgjFMu4T3 zZdzI#m(ql7{{(Pf(=;p=3qdfQPNU!Ni&-Ec;l0VQVd$nMB~UMA+;&^(-TY>OoXuuc zo|31bhs6KCB90w|u j%CBTHsr;pz&*%6H8=VB7i~>0q00000NkvXXu0mjfNzF8J diff --git a/f360-script/commands/commandDialog/resources/64x64.png b/f360-script/commands/commandDialog/resources/64x64.png deleted file mode 100644 index dd285fd1c9a47ff154e426da5c90fcdd96239c2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1077 zcmV-51j_q~P)ZWvYv= zx{iE7uCu6eC_iv#i2_oDd_h3U2V4qV&?G1gA|e+p8iVi7XYZ_c_iU3VU16PXXWqN@ z?9A+XW-u7wA!GJIvj_0lmLWfkSW_)^9A4)TT$bSUz1i%S7VI6)LtqJ=8o~!!779c@B##BTgKfaKCsQSSY zAccGkt0L(1Lpl@8Fq*{WXiOky8UVIrog(z;+3p6e^Q)*IlOQF4q|v1DB@vW}_)E#( zW#It8o*>2aBUgl60hr{=hFlRc1)%ABk_a@l6JcTy^uuVr2ILV3#z|jJ6o3Lx!p^A!-OI|=a6RemBQsf0#sW1)tPT4Ix zkR~snQVxss^n(T}KLGR-*Gp8@6~)9QFAXXJ>=krSq_yp|#KaFHA;LB-TdMiT9*rRd zR$H8sqo0b7oe9Te3KX&(b;MNus$f&v&$~x}+qY-nP2f7Lz?1|%4t?D)7bTX)8G~s7-qHr9GAI)?)||C*KA=q`RM9orn&+0o z9fdtUs1`&8>>W@cl?$!_VyEbvf<6Td zj*eLOZ)|J~U1tg)c3J%}LYYN4K0apMKPrHU6Cxtzd_}*})fg4&^9vK_6Qq_w#!N^a zNfV!r=98iw?{L_M_4Re;u)~n91tdgBJ&#A%+kP0a1PEM5s+~4ErMXZ!A(A!?rO)P; z4eVklA;M+V$qOjGF+z{SDdh=`X_7a(3}!))77YxQeSe)Wz6@qz+T?Y>+KZE>U~L&J vE37Vqb%eDUVC!9AE-Lr>yytoP90u?YjV+lgrL2(V00000NkvXXu0mjf+LYiK diff --git a/f360-script/commands/paletteSend/__init__.py b/f360-script/commands/paletteSend/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/f360-script/commands/paletteSend/__pycache__/__init__.cpython-39.pyc b/f360-script/commands/paletteSend/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 01a32545552f8c5783f2b0a43819c2d2a01120af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212 zcmYe~<>g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=bXRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&}zIHn*mC$*#`H8?ddB_=*TGcU6wK3=b& V@)n0pZhlH>PO2TqNuPn30RVtWI`9Ah diff --git a/f360-script/commands/paletteSend/__pycache__/entry.cpython-39.pyc b/f360-script/commands/paletteSend/__pycache__/entry.cpython-39.pyc deleted file mode 100644 index f5ab94ac043b1b449706df8a0d1f178e1cae5d88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3541 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 diff --git a/f360-script/commands/paletteSend/resources/64x64.png b/f360-script/commands/paletteSend/resources/64x64.png deleted file mode 100644 index ed1ae276ca4eb5a06999f3e340cabec2f571653a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1972 zcmV;l2TS;gP)P|5NA&mlJKR z&5-rUiU3anqGn@N%V=cMnVd%X^-719(I87e8jm4u9|9^6O=}qzGU=Q~`SnUiTFZdE zsVdSpPXZtt1raL(28T|CZD(jOBOrqG$y3nn1SkOe_ue0-ZOe@%Q@WaeV0vZ-P18fO zXgQ#&QC6r0t~s~OKOh7chUeU&;vsyP??8Zf4-ini{mujk*NIbAARqz%9|9PLdjuT+ zb1nb4m_2Rt8jUZ1bk3iJAtU$@@Q47r^H#mmBBl%k_|pKV_7DBK!B-!C@$_9O*WZ?1 z1Dx95z9HOU;bmi}8nCf7&A&!#a_Ua)Kk>oY;;kqFUO^go2--i!a0CeRY0yt6PEU`UHf}8X z{8Hfd#Og*syrTzzF^ zO$}Ibe-Ox5$T_eypc+af5?xSZt(}Jkjx?&V*3Ng*H}2^D`tC1^Tmn2va3P>NN+c4| z0Sp1(?H_1TYvbF`&)smx?ymdpHXV1}8e^d>S>S3xShrfh^gKM77-;%t&z>ExUr^J) zV}Oo-0=z|V_>Ezb$>d@^9*@(}-Vwl!;4pyE85s%RNena{*t_SBrklPrKk@gUJiOGo zzBRz^JU}v;ylNUCZ<0`iAs0bLry+F(4n95599>cO>E#<(INDe0ohJ@?>0AB<+>?ioZ`s-cWzkKTFrx#Xj+o{Ilw-$Yo zJX}N(^_#Z=0z>4!oVheDhr`29^~WFI*R!joy-SR}akLk?WiE#V-x|=|)WZ10SWew3 z0@hu(-qrY6tZrdOZSDN__Xir6^t1>}Tq%4zH8LfS9XOO|ec~HE_q4Qk;Y5P(A+YJg zHx(T7`zA?IvgzyJmwcV-3nNof8+yN&XzknYOhSPOf+Qi#g2}#agkLUB!T4p^|74<7 ziPYTF(%#hvtiaqr>6`^ZE;3$(q6^TB@XLiM7{3Dh`XmX+jp0#1anu0eGYj~I5Hj)% zV|m^zU%MJsUjt9|?in{Sv%f+TkOs6u0ua6y6oSBtfH2Xv8dlfB;csIvlU{zf$qYE+uHe4ILzlm8Xc=>3nhx%Ih;eqayJ~#Htl`WrXy+7+#-zpES_cON`j^UvIsI@Z)fQym<6 zq&ua}jh#uI8#)3^0u#U#Fb8PXF7a!CRX`)q0MsGJiDQ;15gL%Oeb(5@3jC36*&S`! zy8D^0K60eNPJre7vyUx0|05uUBw!ktMQVVdB11t37J$oUAM+&`wG?!u^HvC|<~3@_ z{%@gJM9gznVy=Q)V!E~g8e)#lr+^vcozIvy2#Wv>NdV@LDn;zI_X+zD5N7}O;^$gc z)YgF_2@qN5k3H__y#3DS%ml54gS72)Q6+=>+Z2!_XdowV z&-ZmtYI9>}y_}DC^oS*w#g`Kgb?+_pR4ZCFePR04^L=~n)aNH&N}U@zhD>pe&O3Ef zt^W|UG{8#TF{Cf^NXKXJ2zxuCVOts!>;eihbIl>s_+|6^lFq|b9s&VirS5s;P>7nx zGDycW6yZEn?+~y@K-B!SCUo|>eo-A&E9@y$A?vWOZ1z76&6OwtiJT<>0000g`kf*+IqCW7e4AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yY=bXRDad;?$yI z{q)qlL<4=tf&!Psl0^NW{KVYMymWoX(vtj?)Z%P7L&2@II5R&_!PpF_IKWfiF(t(_ zuUOx;q9nB_FEK|UIX|zYC_kq-COJPhH!&}zIHn*mC$*#`H8>-`JSILqGcU6wK3=b& V@)n0pZhlH>PO2TqNuPn30RV$AI|l#& diff --git a/f360-script/commands/paletteShow/__pycache__/entry.cpython-39.pyc b/f360-script/commands/paletteShow/__pycache__/entry.cpython-39.pyc deleted file mode 100644 index c6e754a287537dd32eca8b93136a63dc2867ac3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4580 zcmaJ^TW=f372X?{%d03#^4;>jZr~HBz0Sfe-*`+8cK}qcJ%$ecL>^a~0&Kb8< z$}8~s&tLxQ{^6#g{0lp0KUwJf5}x>TRZ)mS)If2PU)9lMUw3q(5j`-v8OKx=kc}YQ zwHym%g=B(UH|OM3g=&7@FN}&~#VOH}Uv_4w;uc+y>2ksd+%|z&fvy*Fp3CnRS-P8=(1ssC!E7&F|3m&F^$* zYpN(8_G2#!-~Y+IKKFtcG-f*r54{dZ7I8V{UY82BxM)q zZG7d)#{j{EXBD1!7aFek>PX`{H+Y7dW8*~O*^xC={2b4ZH5JDJRJ=4+Pt>96mqDHZ zSsQA8Wi&ffc$KJQ{Y2+;L%lUm6fm;ZT(2z%t?!9yJ2^yy9(tk2!PK#sa|wCe=R69h zT4AnkHCh`DVc~DHzO^Q1P-@Uvz9;-q6gF13o2~Wj&BofU$Q+`>L;==n9l=`$l! z*(#&pIU;7#eyg1-^2ZT-7WZ7Vy5(`&ef)BRh~j74yC3iE)K}N=03{wp!GX)9NnzSf zy}7n2PX@r?EDBpm0cWCI|Tdwzd4VSyiyOG=V z!p?HN&m%(PXQ#p$04~>eHkJVy8)3Y>_JUIux`918{?pVd@zY)cUc~ZK02X_BxA#(H zV(v1257AMCM$xKz*(mBoy`r4E3^n#-sErC^MOB76+aKzwY_QLVMj}gism)rE&A@K#8aCIlxq%JPtHKts zxrI#?n+i0-N?#Rxw^QF-+uxUtvIxb9-lDY(Tf(_-;M^%{5`Uj!7#){_SY*=$rLU5v zhJQ9<9`)8iiZ4NV|5i54#T|->AZHSto7->7Ra3Mw3c&J_La)Bb94F-RdiC ztjbu_(X2j1D$f$_OZ|+_;<<@Vnn`aCuB_N8Q0+7ZZ2BBreHW=Oh}v#237)u?XLw|x z2T_O3fy6Fj7hsvNNS3~!?LMbd`=ko?ft&|egy?uV9ZnVO0j`CRo|=hWg>DO;7@0`X zD*C)Cb?2;sz$(Bat??}gKd^@G8^}o`%Te{bYAjxy+6f3`n7xBt8D{T-By`|EQJe&lB~C#~%4F7Lg#8?k zgdrk|Bx*l{$$K0~AA*X+&xFyA7!~t73BfhaOo+vmGg|qd^&pbR5i^sQXl$>3ywUuK zJ%aUXI(r}Yk~TnEyolwWfzF2~M%w_EHB-&2mTIWl#qYn(LRrP{qE=B&jp0AfAs*u& z^RqsMek}H$z?47269f9-ybSy2PJwZE zdI}u9cnV-3{X_+c`?T787NxlqTrk)pip9LZdwAkv#or~W86|DaiJZZA5 z=q7M}RnMyoM}TH?7}KpEP<;+YvGSL${wD|*jm-6t0ftVpr{bF@KxEL*`j($d&8`oD z*oK%MzzIK9POzUrr@Ydzhbs8CcJR^-Ml9stkc>ff{E=)vD z>eSVfu$?%1ehssb&1jo?&ndAFA<%8M2WA*p^){A?EB3&|dS}IUs$Ck#P|zY9q_Hb= z=lwwm%zEDrBW}l77-K?xAe9eJm4mH%nCxmFL8Kf|8rp{*o9xMtsErOnXr%=_g26`p zVH5<>F=7xd0`AJg1GfBVF!S)>QF6kE%Lk9(lvSw*EuQ5^bPrOUwe)0VX=`O^Z;;vk z*nZEhEnEmzVfZmrxfx(10+#~ZQ<$zahA6<1;ULm#!i1M4lu7oRf}DK{)?=SRBlHgC zvOW^|)O3%d7Yqvvp@-42upm<(%8N~&QQl`E8oHKaPho~rO#jlt132YLFF6SNEpGBV zY<@47!-(jhRA~1Z11Idmed%J1Y{G=U!4uoiAVU^`{i+jgqLPkI)tC&$O-ul%*7%5ql)1rl4kjZp*GvnD zD4dQU*@_a@3R4{dNqX)K9^XQptkkWC-H7x9`Uv3_qk}ET+7gX`M?fglq(<`9P2&z+ Zfbyp7>$YJS)+Os|wNPEGn$=2m@qhgV%ZLB~ diff --git a/f360-script/commands/paletteShow/entry.py b/f360-script/commands/paletteShow/entry.py deleted file mode 100644 index f48c1c4..0000000 --- a/f360-script/commands/paletteShow/entry.py +++ /dev/null @@ -1,193 +0,0 @@ -import json -import adsk.core -import os -from ...lib import fusion360utils as futil -from ... import config -from datetime import datetime - -app = adsk.core.Application.get() -ui = app.userInterface - -# TODO ********************* Change these names ********************* -CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_PalleteShow' -CMD_NAME = 'Show My Palette' -CMD_Description = 'A Fusion 360 Add-in Palette' -PALETTE_NAME = 'My Palette Sample' -IS_PROMOTED = False - -# Using "global" variables by referencing values from /config.py -PALETTE_ID = config.sample_palette_id - -# Specify the full path to the local html. You can also use a web URL -# such as 'https://www.autodesk.com/' -PALETTE_URL = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', 'html', 'index.html') - -# The path function builds a valid OS path. This fixes it to be a valid local URL. -PALETTE_URL = PALETTE_URL.replace('\\', '/') - -# Set a default docking behavior for the palette -PALETTE_DOCKING = adsk.core.PaletteDockingStates.PaletteDockStateRight - -# TODO *** Define the location where the command button will be created. *** -# This is done by specifying the workspace, the tab, and the panel, and the -# command it will be inserted beside. Not providing the command to position it -# will insert it at the end. -WORKSPACE_ID = 'FusionSolidEnvironment' -PANEL_ID = 'SolidScriptsAddinsPanel' -COMMAND_BESIDE_ID = 'ScriptsManagerCommand' - -# Resource location for command icons, here we assume a sub folder in this directory named "resources". -ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '') - -# Local list of event handlers used to maintain a reference so -# they are not released and garbage collected. -local_handlers = [] - - -# Executed when add-in is run. -def start(): - # Create a command Definition. - cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER) - - # Add command created handler. The function passed here will be executed when the command is executed. - futil.add_handler(cmd_def.commandCreated, command_created) - - # ******** Add a button into the UI so the user can run the command. ******** - # Get the target workspace the button will be created in. - workspace = ui.workspaces.itemById(WORKSPACE_ID) - - # Get the panel the button will be created in. - panel = workspace.toolbarPanels.itemById(PANEL_ID) - - # Create the button command control in the UI after the specified existing command. - control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False) - - # Specify if the command is promoted to the main toolbar. - control.isPromoted = IS_PROMOTED - - -# Executed when add-in is stopped. -def stop(): - # Get the various UI elements for this command - workspace = ui.workspaces.itemById(WORKSPACE_ID) - panel = workspace.toolbarPanels.itemById(PANEL_ID) - command_control = panel.controls.itemById(CMD_ID) - command_definition = ui.commandDefinitions.itemById(CMD_ID) - palette = ui.palettes.itemById(PALETTE_ID) - - # Delete the button command control - if command_control: - command_control.deleteMe() - - # Delete the command definition - if command_definition: - command_definition.deleteMe() - - # Delete the Palette - if palette: - palette.deleteMe() - - -# Event handler that is called when the user clicks the command button in the UI. -# To have a dialog, you create the desired command inputs here. If you don't need -# a dialog, don't create any inputs and the execute event will be immediately fired. -# You also need to connect to any command related events here. -def command_created(args: adsk.core.CommandCreatedEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME}: Command created event.') - - # Create the event handlers you will need for this instance of the command - futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers) - futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers) - - -# Because no command inputs are being added in the command created event, the execute -# event is immediately fired. -def command_execute(args: adsk.core.CommandEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME}: Command execute event.') - - palettes = ui.palettes - palette = palettes.itemById(PALETTE_ID) - if palette is None: - palette = palettes.add( - id=PALETTE_ID, - name=PALETTE_NAME, - htmlFileURL=PALETTE_URL, - isVisible=True, - showCloseButton=True, - isResizable=True, - width=650, - height=600, - useNewWebBrowser=True - ) - futil.add_handler(palette.closed, palette_closed) - futil.add_handler(palette.navigatingURL, palette_navigating) - futil.add_handler(palette.incomingFromHTML, palette_incoming) - futil.log(f'{CMD_NAME}: Created a new palette: ID = {palette.id}, Name = {palette.name}') - - if palette.dockingState == adsk.core.PaletteDockingStates.PaletteDockStateFloating: - palette.dockingState = PALETTE_DOCKING - - palette.isVisible = True - - -# Use this to handle a user closing your palette. -def palette_closed(args: adsk.core.UserInterfaceGeneralEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME}: Palette was closed.') - - -# Use this to handle a user navigating to a new page in your palette. -def palette_navigating(args: adsk.core.NavigationEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME}: Palette navigating event.') - - # Get the URL the user is navigating to: - url = args.navigationURL - - log_msg = f"User is attempting to navigate to {url}\n" - futil.log(log_msg, adsk.core.LogLevels.InfoLogLevel) - - # Check if url is an external site and open in user's default browser. - if url.startswith("http"): - args.launchExternally = True - - -# Use this to handle events sent from javascript in your palette. -def palette_incoming(html_args: adsk.core.HTMLEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME}: Palette incoming event.') - - message_data: dict = json.loads(html_args.data) - message_action = html_args.action - - log_msg = f"Event received from {html_args.firingEvent.sender.name}\n" - log_msg += f"Action: {message_action}\n" - log_msg += f"Data: {message_data}" - futil.log(log_msg, adsk.core.LogLevels.InfoLogLevel) - - # TODO ******** Your palette reaction code here ******** - - # Read message sent from palette javascript and react appropriately. - if message_action == 'messageFromPalette': - arg1 = message_data.get('arg1', 'arg1 not sent') - arg2 = message_data.get('arg2', 'arg2 not sent') - - msg = 'An event has been fired from the html to Fusion with the following data:
' - msg += f'Action: {message_action}
arg1: {arg1}
arg2: {arg2}' - ui.messageBox(msg) - - # Return value. - now = datetime.now() - currentTime = now.strftime('%H:%M:%S') - html_args.returnData = f'OK - {currentTime}' - - -# This event handler is called when the command terminates. -def command_destroy(args: adsk.core.CommandEventArgs): - # General logging for debug. - futil.log(f'{CMD_NAME}: Command destroy event.') - - global local_handlers - local_handlers = [] diff --git a/f360-script/commands/paletteShow/resources/16x16.png b/f360-script/commands/paletteShow/resources/16x16.png deleted file mode 100644 index f1b8e5705f6c5544667a8ea92580d82360687e34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmV-a0jvIrP);xMdD{U>TEPR43wo$aQ@EP(1mX;P~ zGMS&mVj&Yl2)nu6z&(fijR%Z?9^LX80KK9p&PP|bbJNd{_XGe@6m=ZHR1n8;C)o46 zsleJCo9A=E3%>6bXl>BOa5-Kn3r|DQDp(8xC&;uxN(DH9NEO#F8;$V8*$-ie6DXw- zsr*+GspPKz-6#+#_`X+JkZBSjx!L_HOG*0$wG)))H<7JCJ diff --git a/f360-script/commands/paletteShow/resources/32x32.png b/f360-script/commands/paletteShow/resources/32x32.png deleted file mode 100644 index a61a47e4710bdc2aedde29ee1f9f4f0b25d8c82a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 587 zcmV-R0<`^!P)do&Mr37>Z`J(s>*sC z{uEW5lPmy5Q8X}Nppp-uDs>t_R9Y#xw=v&xdUjzq8Nfa*I{-wZJ0Rum5b275DAx9; zAbh+3?!X|?C+C0s3qY{8f0g0ez)sSn$Cz4c8X!cV55O1b z+Uqxigl}EH)&TTv!$|~S;sI`4xjYCU_}2ivMd(mZaP`u~)&!{v)ELuKgsMzj128Ky z#^5w^66OGio`eD5?T7a*$JOzB)jy9n!+EC8H1eyTM=s&=hE1=F2 z78efB9>8nu1rT6+>FAODdx2(b7T5;F0Q0~h;2`xoF^ByEz5-ti^&4%@ix)AkgeD&1 Z=Wl;YQq&g|YVQC5002ovPDHLkV1iU;1q1*9 diff --git a/f360-script/commands/paletteShow/resources/64x64.png b/f360-script/commands/paletteShow/resources/64x64.png deleted file mode 100644 index 4dd5dfcb2d51b5651ff4fcc8a4f757af32a172a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1165 zcmV;81akX{P)% z&x;&I6vscc+pd`ng1BxNLQoO|akDB}6N3aJNOV0Y2oeY$)=NSlC&i2Zh2SY5@nQrC zFIn=)32v$-uuq`Rozv} z7{k*H4?roU00o=@PDG!Z2m@RLE&#?DW4!2w0(Jl&UcB_{r{mJD3ap&^$OC=^9syef zc)(7e73hG@>N+1Uzq2*y%GEzASF{YYcg+E`2yOL&UQEC=FbnMP`#$|%e_-J7^`ye@ z`w)8iEbtJb8~{uKGl19g`#kRV1_lmaPbzwTA3~dF2yNaXfJmTX54d>gO7$9+jK~8N zk?}A{003Wqd8R^@#*YL68ygStgJ2xGln!rt8qb>^lnsB$7=zKxY>v!S(yk-{fNp4a zC|Q*t0Apxudo0)`gaGKKhJav}m;LtktA zoISR=O%=<9eF&KB5EwQ-mgS8bH|#>d80RD?jr;1C=bh$q!8f1$n|a@o0QV{&jaxoY zU0CGlU3wLe#=XD4>ok|!?`Pj1SqLob>T!2&Pq~DLBke_s=EQXB8Rvsh| zII?u8_(YD#O5RG@hJZHcKxY!rYPHzh+)T)HP~RM&l)TJOO@dhjteiS2%Ilm2?L8ps z1e^9yC?p^$7d;@z@qkH00S_<@_JBeJq%-jQ^&8xO@L)i;XZLR2d-wPVR4oTesbZaA z76HS?$Fh1SL2ClY^?)=;b@->tmkZD1iqB5U)d>nDK^-lJT?mkt(TfKc3eV$;tYy4H zA@#RTIUo&^2P_W=kptT8Hl0oO(520#YCF@=JRQ z&*O>_b%N1m$qWMKUU-r9fBsI$>Rvgl-wo#FfW^hvMR}b!SA{vistS->1ttkmiq+V%V3>hT?T2e2S{0PD)Aj;SDADeBfsz!li;DnSIXCD9LPz68o2%D8~dLF zo<;DE35NzA1Gl5kz!L&A&;x!3{sQKJXDU{(Z1jP3;2xo^8lDgk09{};x?U$dOV}g? zzy_g>-RK%+j6o?iMR=faC*h&Ot#fq^LhR*T;6LDzF-FG(#D}Ln!hgPL#>dcv|GZCh fcv>~F - - - - Title - - - -
- -

Fusion 360 Palette Sample

- -

- -

Send Data to HTML Event Handler

-
- -

- -
- -

HTML Event Response Value:

-
Response
- -

Message from "Send to Palette" Command

-
-

Message from Fusion

-

-
- -
- - diff --git a/f360-script/commands/paletteShow/resources/html/static/palette.js b/f360-script/commands/paletteShow/resources/html/static/palette.js deleted file mode 100644 index dacdafc..0000000 --- a/f360-script/commands/paletteShow/resources/html/static/palette.js +++ /dev/null @@ -1,48 +0,0 @@ -function getDateString() { - const today = new Date(); - const date = `${today.getDate()}/${today.getMonth() + 1}/${today.getFullYear()}`; - const time = `${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}`; - return `Date: ${date}, Time: ${time}`; -} - -function sendInfoToFusion() { - const args = { - arg1: document.getElementById("sampleData").value, - arg2: getDateString() - }; - - // Send the data to Fusion as a JSON string. The return value is a Promise. - adsk.fusionSendData("messageFromPalette", JSON.stringify(args)).then((result) => - document.getElementById("returnValue").innerHTML = `${result}` - ); - -} - -function updateMessage(messageString) { - // Message is sent from the add-in as a JSON string. - const messageData = JSON.parse(messageString); - - // Update a paragraph with the data passed in. - document.getElementById("fusionMessage").innerHTML = - `Your text: ${messageData.myText}
` + - `Your expression: ${messageData.myExpression}
` + - `Your value: ${messageData.myValue}`; -} - -window.fusionJavaScriptHandler = { - handle: function (action, data) { - try { - if (action === "updateMessage") { - updateMessage(data); - } else if (action === "debugger") { - debugger; - } else { - return `Unexpected command type: ${action}`; - } - } catch (e) { - console.log(e); - console.log(`Exception caught with command: ${action}, data: ${data}`); - } - return "OK"; - }, -}; diff --git a/f360-script/config.py b/f360-script/config.py deleted file mode 100644 index ad5c982..0000000 --- a/f360-script/config.py +++ /dev/null @@ -1,22 +0,0 @@ -# Application Global Variables -# This module serves as a way to share variables across different -# modules (global variables). - -import os - -# Flag that indicates to run in Debug mode or not. When running in Debug mode -# more information is written to the Text Command window. Generally, it's useful -# to set this to True while developing an add-in and set it to False when you -# are ready to distribute it. -DEBUG = True -VERSION = "0.1b" - -# Gets the name of the add-in from the name of the folder the py file is in. -# This is used when defining unique internal names for various UI elements -# that need a unique name. It's also recommended to use a company name as -# part of the ID to better ensure the ID is unique. -ADDIN_NAME = os.path.basename(os.path.dirname(__file__)) -COMPANY_NAME = 'ACME' - -# Palettes -sample_palette_id = f'{COMPANY_NAME}_{ADDIN_NAME}_palette_id' \ No newline at end of file diff --git a/f360-script/lib/__pycache__/joystickapi.cpython-39.pyc b/f360-script/lib/__pycache__/joystickapi.cpython-39.pyc deleted file mode 100644 index 440ae37adb476e2a3b9db6e300d17b88b70d00bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3238 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 I?~GX9cW`x)An*dkwcxY#%UK&fW6X?2SA zsW+`0RG-wQ?72U!z2KZpYmnQM4WF?MrL2&Na1w}_Od?A~wylL7=`iX?S{2KkW>etX zFoW?B^4fJbEl%FJAs*sHF-dznI?Ti*9g97gWW+8^lZ0q;;f{_wUn(tTEc)Xl%%U`b z1TqtQQ5?^XIFZ~1#X$m-4s8fG!X;y?MU;p*9SovmARO$_&e}ALWCk_%qHG&%B3mj% z`jp>2sBHEk@F3kC&$NGhshDYn!?;Ivpf84U28L6mrF(IS+T1pd#O={ z{3qR@&?Js<61SGl;V>M^L=H$Q;4!*f_w?QRV?AN{{M@NASp@oH(yMMZ5)I349~cy<{$>6A0i%8Hq$DE^MR3 zDcqt&>5)d4Wbs7wQzNttw-F6P90cC(*t*f#*d()fA`3p8hf;}85e(9b&}eeyj&RDT zl9bHiU3y)k@dE-f6lKaMFzY>MCsVRTyW3WCBY|idPHjnV=A_#J*iO4df}aMBO~8<+XxgnIBD% zO-9;K+JDK+Mg0A}zq$VSC##KJ8|XydT-z9pzLA++yPwJ-th}}{&QhiA?tCD=h53;* zKKmS-f4sYfymmLSYj=Ljv`OGf$Um7$WBWLcdXM{VFSd@e2qc$N0yplACiyZ{D;0Pf z!dO?2uC(}hewH`6xdd8>cH*Oqzlml^UsM~^CCah;*EY#Jt#ivouU?4p!T?l2mdb0b zLt&wN3taQnlYadLUFYh9Z{ESU?H4#Z#OGj#RVbI-=;x*knw_N_V zw>#gvB5y)+f%2mH0T48p+-+q%&os#qXA%W9QGD6)+_X!63t*3B<1J2pcEV;-b zC5OaM9pw>Ayqm{T8?r;&GwtBg)jRGrSh1POeX2MvR%X0M}zmL8h#*FEn2;{$%rqfzUF#xiXD56wU$O6yQotc|IzuBbKiV3VgzuX=FRVUXN_Tl64978 zhs~cz(WV4{JQ_BCCPna=c+1vwn@4FN?v;{g^UCXxSNYa&mEnEffb%x5y$*Pt$8hq1 z(;rEv`3~YChwnn59qOtRRit^=?}Tn^CX7ik;VM%6BBX1jN>9WH6pWH$f(Dxv0aJm! z58J!|V#$iUq?D|vrPE*vX`KbS>-oyG`fF&n-qcoby9%#DN^IRcSq1uVeIMVx_kjkN z{~X&~=61=_MKQ6tDwtJFBqo^v{HI`1<7?ZZyPRpvS`tcwzE&RjH6TDbail|9F17}q+`TIr4KYQP;W z=fb!~KbK-HxeyBALa8!Wd3Nyh_&c|~U$$?p(1|qmPGj>lLUdRI<&gzXZ;5^Y2mh}2 zcTbLu(59D(B6-}~o6nymHtD@k$qY)}+gn)0g*p45Vf}@{=6vx4lz$lX_BbCDrgv~* zg)S1w06du$?9)$2QY_ko7)NA23jp=q+1M2VI z1}-X+nHaXssX8C6`#2h_i%EbM>xDd~=K*>MjD-o@K=Wk)5Cp)!B0R8u`d*Pg!t1vy zs=qHGdsF8MAkIUWq9_?rLhiz+$!Bw!r%NWVUnNeVY3e+!std^(01%A|oQ~_*gkqI0aZYZpLCX4xG~zRsTfnH4 zOcgM1w|(6KWe?=r?odXw1In^8IgA7(mI7?Mcd6r<_jP&yYh27DpLyQV_^?y=NYFKC ztA?kSXncuv1Bk0zolL|ynVh*8#&nk0k+_(+V3E6cjg_bBLVth;i1v~^MAK&Zq>OyY zKZg^8A0Tm?eiBAhBPctx-+AZ)W%P$2xjIg27YFryEUp3bBC#nj5-!Yy)re%*g5K&u z0V9z@fchgmBO2dS-9~~bxaOcp6-=rhc^4Y1T{Koomib}?*Mj!p`^alw%@kiq@l6vn Y%npzmgint - returns integer value of axis - """ - osn=None - supportedOS=['nt'] - - - axIndex=["X","Y","Z","R","U","V"] - - def __init__(self,id=0): - """ - initializing joystick. Throws "Unsopported os" if os not supported - """ - self.osn=os.name - - if self.osn not in self.supportedOS: - raise Exception("Unsupported os") - - self.id=id - ret, caps=joystickapi.joyGetDevCaps(id) - - self.ManufacturerId = caps.wMid - self.ProductId = caps.wPid - self.ProductName = caps.szPname - self.NumButtons = caps.wNumButtons - self.PeriodMin = caps.wPeriodMin - self.PeriodMax = caps.wPeriodMax - self.Caps = caps.wCaps - self.MaxAxes = caps.wMaxAxes - self.NumAxes = caps.wNumAxes - self.MaxButtons = caps.wMaxButtons - - self.rangeX=[caps.wXmin,caps.wXmax] - self.rangeY=[caps.wYmin,caps.wYmax] - self.rangeZ=[caps.wZmin,caps.wZmax] - - self.rangeR=[caps.wRmin,caps.wRmax] - self.rangeU=[caps.wUmin,caps.wUmax] - self.rangeV=[caps.wVmin,caps.wVmax] - - self.ranges=[ self.rangeX, self.rangeY, self.rangeZ, self.rangeR, self.rangeU, self.rangeV] - - - - def getAxesRaw(self) -> list: - out=[] - ret, io = joystickapi.joyGetPosEx(self.id) - if ret: - # X Y Z R U V POV - axes = [ - io.dwXpos, - io.dwYpos, - io.dwZpos, - io.dwRpos, - io.dwUpos, - io.dwVpos, - io.dwPOV - ] - - return axes - #else: - # raise Exception("Joystick read error") - - - - - - - def getAxisRaw(self,axis: str) -> int: - """Returns value of defined axis - - axes: - - dwXpos - Current X-coordinate. - - dwYpos - Current Y-coordinate. - - dwZpos - Current Z-coordinate. - - dwRpos - Current position of the rudder or fourth joystick axis. - - dwUpos - Current fifth axis position. - - dwVpos - Current sixth axis position. - - dwPOV - Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. - - source: https://docs.microsoft.com/en-us/previous-versions/dd757112(v=vs.85) - """ - out=0 - availableAxes = ["dwXpos","dwYpos","dwZpos","dwRpos","dwUpos","dwVpos","dwPOV"] - if axis in availableAxes or axis=="list": - axes = self.getAxesRaw() - return axes[availableAxes.index(axis)] - else: - raise Exception("Axis doesnt exists") - - - - def getAxes(self) -> list: - axesRaw = self.getAxesRaw() - out=[] - - - for i in range(0,len(axesRaw)): - out.append(int(correctAxis(axesRaw[i-1],self.ranges[i-1],0.05))) - return out +def greeting(): + logger.print("------Starting------") + logger.print("f360 joystick driver") + logger.print(f"version, {VERSION}. By {AUTHOR}.") @@ -177,6 +36,12 @@ def transformCameraByMatrix(camera: adsk.core.Camera, matrix: adsk.core.Matrix3D eye.transformBy(matrix) camera.eye = eye +def transformCameraByVector(camera: adsk.core.Camera, vector: adsk.core.Vector3D): + eye: adsk.core.Point3D = camera.eye + eye.translateBy(vector) + camera.eye = eye + + def changeCameraZoom(camera: adsk.core.Camera,zoom): zoomOld = camera.viewExtents @@ -186,18 +51,28 @@ def changeCameraZoom(camera: adsk.core.Camera,zoom): numOfJoysticks = joystickapi.joyGetNumDevs() -joy = Joystick() + +joy = None def run(context): + + try: + # This will run the start function in each of your commands as defined in commands/__init__.py + commands.start() + + except: + futil.handle_error('run') + # This section executes once on script start ui = None app: adsk.core.Application = adsk.core.Application.get() ui = app.userInterface - futil.log(str("Joystick driver v"+"/version/"+" started")) - futil.log("START") + greeting() if numOfJoysticks==0: raise Exception("No joystick") + else: + joy = Joystick() # this found there https://github.com/Rabbid76/python_windows_joystickapi @@ -209,10 +84,10 @@ def run(context): ui.messageBox(str("Using gamepad: " + caps.szPname)) ret, startinfo = joystickapi.joyGetPosEx(id) break - else: - ui.messageBox(str("no gamepad detected")) + else: + ui.messageBox(str("no gamepad detected")) - + first=True # This section executes once on script start @@ -224,8 +99,21 @@ def run(context): cam: adsk.core.Camera = vp.camera vecUp: adsk.core.Vector3D = cam.upVector target: adsk.core.Point3D = cam.target + eye: adsk.core.Point3D = cam.eye + + + + eTvector=eye.vectorTo(target) + angle1 = eTvector.angleTo(vecUp) + dx,dy,dz = getPerpendicularVector(vecUp.x, vecUp.y, vecUp.z) + perpendicular = adsk.core.Point3D.create(dx,dy,dz) + perpendicular=perpendicular.asVector() + angle2=vecUp.angleTo(perpendicular) + + if numOfJoysticks==0: + raise Exception("No joystick") deg = (joy.getAxes()[6]/262144) @@ -240,7 +128,13 @@ def run(context): changeCameraZoom(cam,zoom) - futil.log( str(str(joy.getAxes()) +"|"+ str(cam.viewOrientation))) + # futil.log( str(str(joy.getAxes()) +"|"+ str(cam.viewExtents))) # all axes output + logger.print( + "vecUp - target angle: "+str(math.degrees(angle1))+ "\n"+ + "vecUp - calcul angle: "+str(math.degrees(angle2))+ "\n"+ + str(perpendicular.x)+"|"+str(perpendicular.y)+"|"+str(perpendicular.z) + ) + # matrix3d mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() @@ -251,16 +145,11 @@ def run(context): transformCameraByMatrix(cam,mat) - + transformCameraByVector(cam,perpendicular) - # zoom = cam.viewExtents - # if axisXYZRUV[0]>1024 or axisXYZRUV[0]<-1024: - # zoom = zoom - (axisXYZRUV[0]/10000)*(zoom/100) - # if zoom<0: - # zoom=0.001 diff --git a/f360-script/External controls/config.py b/f360-script/External controls/config.py index ad5c982..ca31d6b 100644 --- a/f360-script/External controls/config.py +++ b/f360-script/External controls/config.py @@ -9,7 +9,8 @@ # to set this to True while developing an add-in and set it to False when you # are ready to distribute it. DEBUG = True -VERSION = "0.1b" +VERSION = "11.06.22 12hr" +AUTHOR = "InTostor" # Gets the name of the add-in from the name of the folder the py file is in. # This is used when defining unique internal names for various UI elements @@ -19,4 +20,6 @@ COMPANY_NAME = 'ACME' # Palettes -sample_palette_id = f'{COMPANY_NAME}_{ADDIN_NAME}_palette_id' \ No newline at end of file +sample_palette_id = f'{COMPANY_NAME}_{ADDIN_NAME}_palette_id' +tools_tab_id = "ToolsTab" +my_tab_name = "test" # Only used if creating a custom Tab \ No newline at end of file diff --git a/f360-script/External controls/lib/Joystick.py b/f360-script/External controls/lib/Joystick.py new file mode 100644 index 0000000..b7b6dfd --- /dev/null +++ b/f360-script/External controls/lib/Joystick.py @@ -0,0 +1,137 @@ +from . import joystickapi +import os +from .mathExt import * + +class Joystick: + """This is wrapper class for joystick + + Attributes + ---------- + supportedOS : list + list with supported os + + + Constructor + ----------- + requires only id of joystick in system + todo: maybe in other systems name or uuid required + + Methods + ------- + getAxis(str: axis)->int + returns integer value of axis + """ + osn=None + supportedOS=['nt'] + + + axIndex=["X","Y","Z","R","U","V"] + + def __init__(self,id=0): + """ + initializing joystick. Throws "Unsopported os" if os not supported + """ + self.osn=os.name + + if self.osn not in self.supportedOS: + raise Exception("Unsupported os") + + self.id=id + ret, caps=joystickapi.joyGetDevCaps(id) + + self.ManufacturerId = caps.wMid + self.ProductId = caps.wPid + self.ProductName = caps.szPname + self.NumButtons = caps.wNumButtons + self.PeriodMin = caps.wPeriodMin + self.PeriodMax = caps.wPeriodMax + self.Caps = caps.wCaps + self.MaxAxes = caps.wMaxAxes + self.NumAxes = caps.wNumAxes + self.MaxButtons = caps.wMaxButtons + + self.rangeX=[caps.wXmin,caps.wXmax] + self.rangeY=[caps.wYmin,caps.wYmax] + self.rangeZ=[caps.wZmin,caps.wZmax] + + self.rangeR=[caps.wRmin,caps.wRmax] + self.rangeU=[caps.wUmin,caps.wUmax] + self.rangeV=[caps.wVmin,caps.wVmax] + + self.ranges=[ self.rangeX, self.rangeY, self.rangeZ, self.rangeR, self.rangeU, self.rangeV] + + + + def getAxesRaw(self) -> list: + out=[] + ret, io = joystickapi.joyGetPosEx(self.id) + if ret: + # X Y Z R U V POV + axes = [ + io.dwXpos, + io.dwYpos, + io.dwZpos, + io.dwRpos, + io.dwUpos, + io.dwVpos, + io.dwPOV + ] + + return axes + #else: + # raise Exception("Joystick read error") + + + + + + + def getAxisRaw(self,axis: str) -> int: + """Returns value of defined axis + + axes: + + dwXpos + Current X-coordinate. + + dwYpos + Current Y-coordinate. + + dwZpos + Current Z-coordinate. + + dwRpos + Current position of the rudder or fourth joystick axis. + + dwUpos + Current fifth axis position. + + dwVpos + Current sixth axis position. + + dwPOV + Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. + + source: https://docs.microsoft.com/en-us/previous-versions/dd757112(v=vs.85) + """ + out=0 + availableAxes = ["dwXpos","dwYpos","dwZpos","dwRpos","dwUpos","dwVpos","dwPOV"] + if axis in availableAxes or axis=="list": + axes = self.getAxesRaw() + return axes[availableAxes.index(axis)] + else: + raise Exception("Axis doesnt exists") + + + + def getAxes(self) -> list: + axesRaw = self.getAxesRaw() + out=[] + + if str(type(axesRaw))=="": + return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + + for i in range(0,len(axesRaw)): + out.append(int(correctAxis(axesRaw[i-1],self.ranges[i-1],0.05))) + + return out \ No newline at end of file diff --git a/f360-script/External controls/lib/__pycache__/Joystick.cpython-39.pyc b/f360-script/External controls/lib/__pycache__/Joystick.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3065787109ea22cfe838042cb4cf84a679001ac4 GIT binary patch literal 3601 zcmb_f-EJGX6&}uvek|LH`g~LJcozmA$fTI?9I-W z41E83{?EgmvSIv3bCkQ9>I?TbP;uu0kQfYdIbtc;pedk(QUW>_)W97fK`C_9*s1P$k3>pL*qz+)g%0xv?)0wemGKs#BKZhraZ^z(4WBR`%+P&UTweec{~L2}LxrIvCUq$8Q2TVI(JpmWetkWA@la zF>Rw#OUy_lwz7-FibR-9XX7tkCR5J_4c3)@6egxmxq7K&77p>8$)~Kh>UFWSzwT4F zyzYf@(`&#K7+<5{Zu&Ht+T;<1RfACwC!2bc=@D;3?Ks`vh&z9XrG)*vr3sys`kRdV z5ncB~cPb+%Y;TaUy+M-etE0HKK2Wj0?hRH3Ot^&+krdT7DQiSvXAEXLPiV;6>-eEY z*d))ru*LS!-A}puos7E=uA6e*3D*U8E9GuYxLe@vq}-hecL&_vl)F3O?k4H3qGBhu zU_q15E4^EAw8U=UqTd>P37r47SC z!uew?@RrW~&oFs&t+qnxS}1DI29oj63!Fw2N*)E`An*?l#^G_Xdz=*Ob!CP1`gQCp z7SI@W(VQVgGf&E9kzDwhWrE+RJ-M988p}cG&!>T-q0+E5 ze&GEPc1L(?gm*@GSK%D(Z@$>A+TOF5`=IBV^-h)U5V=)*rj|qO+?~b6V9%Rqu3I=MeYxxULkm z22{9nmY@wD#jUn;|G~l+OG_%*Fu~H)E>JggQH!W2R!guVU<<0$psd9i6AS7T%xknA zy?ZAPq~8sESkd9Ja~IMkmLs6%23vO8Qg+31twy7USnT)>9*L+a7aLKh#=>eWYS^&n zN3p2(5bp3|qDJY%2M_Pwy?49!`<__*{6QsCimoau1^xhD!9P>YL)Cn)nlDtdteW4U zNo-Y>oy@EH#-R}txDo>`kr*xhrJ9lRL&^sHGU$=x^CzJBBQ)-;*Yo_qI}DggE?l|c zheLp`Lcl(T#S9wbnvIA#2Pm8GyS<+IPE1r@J_XR8PC<;knIJZrl1OuiV(5%e0#Co0 zMgaJ>MJ;LT5%a0>mj%QG^DRmxiBf53QTvK<6>?O(Olg`sv(69~i1GT~P}Rrzjg$FD zX%T#DBMRB}ahKhCT$$6#{l7OV2ekh2clCYyWo0T=y@iT1u_ZQ6ayktsR=~m}uL|^# zCKgOQnQlY~HVs{&a+Q}VwvNtjLB%L2T|ZPp{P*9bFbcAN#TtSCc@US2#5VCL<~+G$ zp3J=;jVmOztFlUls*S$!mEO-aDw%K<@f8Rq4QHLVN!}`&rBBLN=04SHW9Ou4;W|GRAEn2Ctn@Eb-HntE4g3$FrNt@$ literal 0 HcmV?d00001 diff --git a/f360-script/External controls/lib/__pycache__/logger.cpython-39.pyc b/f360-script/External controls/lib/__pycache__/logger.cpython-39.pyc index a32ee7e8fa941d1c1c307621230406ab264a75b6..6a0a253c6bfd0fe28da6e90b6388a4c2b4ba24dd 100644 GIT binary patch literal 745 zcmZuuOKaRf3?7Z`wX@mXBH34mus%!WDdk4sQ4sJ_8JVVHtbYGo7|U zPUo;5ju3NAsCq(%SPy0oJsWIv*>touLyKY%!R6%VST41U!L1OVeay!pQE9ST31P=V z;5GV+{D~0n`>Yx=dWxl*x>_%5F7zRVzmc6s@R~T$IUINdho1Xc#=Zm7v?o2=75=Y- PjUEjnJf>Q=*oprGn5&*! literal 1438 zcmbtUK~EGh6mB~+FuTA;#Rws4=ICBnj0p#$1Vk_-h7bjbgk(~t-F24P&e(PpHp@l0 z`wL8#BmctR(W@u_f+ydbl@$p$JL#LgH=Wn-ef?TKHB}|h?tcGvuzt(oL)sMV2Pq zrnz!nOIkP8HBxUVD|M46(uD=jq_xtxFtxJt;&?;22@4swhH*F1%ylAn3c;;(mDIdT zO?r^YdfQ- zjg_v=g*1nwLA2gAfHQis2$Q!q8Y@CA`+hk~&`;yD*MZ zmD)J=VO4{82%V&3@SyG8zTANM%X$Co1n$acCmwP*)#;3JtOAwzQqgF&HFWf7_w12e?itBsJB zpEoZ8tWEKbjAK`g<4!KR8IC98_+yu6!!LRo66hH;Nc$CoOX(hxeZotRFy@9-FGxJ&gh^@w#fMt}Ip3Kpdr{?}2gS_Q)c}>jj|z=Af7R zOlXbvZe1y5C@4LPX>L*pUSt^ms}hU=$rZdz=J75m^<9cb5nB+Z4TOSDb5%VM6$XxXM)5Qu_Ux;Lp3Dpk3)p&+@jn+~0fgFV@% z(ah8C13zFNLE4pg;V;b-5>NdHh?jEgY0{Q;H0K=K$M*5(@0{>Pql%!txcSHa?r_I^~zK8IcTOd-D;ucD2N?NFi zQqT65P)ZgMY=|d|h7Tm;h7I_z9k4KFy*qcR4BDS4@N@E%N4Y-;;AA>4E@2gP) znvX$idzusf_8+e8eQTsPoxY6uN@smIe8dyp*;X9Z^gHXLLh5E9*+~LV;-@diW99OvloT?djp;v!p!pUB==2^N77!^cpwnb_C*4k`w;F( z=2Y{zpI3zBVxnT1m$XbqI_}v}r;UOEuU7!|01SaMk~p{oUIfsDx9DE#nV*rA2$FhD zbcD=@U{hyPy_S-U#MG`#3Bc*|k1_11w3fZZFg^|qa}lw22>nB@1xpl@<6*=B>ElD5 zurOglNfWRlM#END_F*iH6V|@F`qRBn*r&{@z&*+q*YI8dk8$0*v*x<)tTngR_3bkj z=fkPJA}lxIgat{iu_!dj%-fAIbx_3KWkFs|!X zG(hA;U1px1vtzaM8?FQF*3$`ejnWow;gUx^JrAQ-NN^=vR$vyg#e-}CxquEliZYVX z6sP3K*KN@B22UYD0~_^4764{DCKyZ+WkX z_GR)NB%IRg?%-uO$J_*gh=;G^In5cC z0>JqeaH1#^srQWR0Y5T7D<$}6Pk2yQX$#G4|B_v5L0R@tR?aHfT!LScwEPNq)dX*_ zE0^rK!gk)(td`Z&YFbO{4rH>~htQz?b^p{>zJR)$=oZ+yHw<&qQzmHWCFpBg{q@^+ zrWDDz51^NoLuhAe>`slYzHOb~v4VlOZvZn(W3u;A-jR9muxW8 int: + """Corrects axis value (its hard to explain what it does) returns 20bit int (-2^19 ; 2^19) + Parameters + ---------- + value: int + value to correct + + range: list + range of axis ( [from,to] ) + + deadzone: float + zone (from center) where value will be always zero + + + """ + out=0 + + + + out=scale(value,rang[0],rang[1],-524287,524287) + if out<-524287*deadzone or out>+524287*deadzone: + out=out + else: + out=0 + + return out + +def precissionEqual(val1,val2,epsilon): + vmin=vmax=val1-epsilon,val1+epsilon + if val2>=vmin and val2<=vmax: + return True + else: + return False + +def getVectorAngles(x,y,z): + """returns angles in radians + """ + try: + angleX = math.atan(z/y) + except ZeroDivisionError: + angleX=0 + try: + angleY = math.atan(z/x) + except ZeroDivisionError: + angleY=0 + try: + angleZ = math.atan(y/x) + except ZeroDivisionError: + angleZ=0 + return angleX,angleY,angleZ + +def getPerpendicularVector(x,y,z): + length=(x*x+y*y+z*z)**0.5 + oAngleX,oAngleY,oAngleZ = getVectorAngles(x,y,z) + angleX, angleY, angleZ = math.pi/2-oAngleX, math.pi/2-oAngleY, math.pi/2-oAngleZ + dotX,dotY,dotZ = math.cos(angleX)*length,math.cos(angleY)*length,math.cos(angleZ)*length + + return dotX,dotY,dotZ