From 7a507f124744ff9a24e5d4d4f7132e9cd85cd8fb Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Fri, 14 Jun 2024 16:31:21 -0600 Subject: [PATCH 01/14] Http server is being annoying. Looking into direct file upload --- exporter/SynthesisFusionAddin/Synthesis.py | 27 +++++ .../src/Fission/HttpServer.py | 17 +++ .../src/UI/ConfigCommand.py | 110 +++++++++--------- 3 files changed, 99 insertions(+), 55 deletions(-) create mode 100644 exporter/SynthesisFusionAddin/src/Fission/HttpServer.py diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index 4ed3a0fede..bbd3a67ee4 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -1,3 +1,7 @@ +from http.server import HTTPServer +from threading import Thread + +from .src.Fission.HttpServer import MyHTTPHandler from .src.general_imports import root_logger, gm, INTERNAL_ID, APP_NAME, DESCRIPTION from .src.UI import HUI, Handlers, Camera, Helper, ConfigCommand @@ -11,6 +15,10 @@ from .src.UI import MarkingMenu import adsk.core +httpServer: HTTPServer | None = None +serveThread: Thread | None = None + +HTTP_PORT = 3004 def run(_): """## Entry point to application from Fusion 360. @@ -23,6 +31,21 @@ def run(_): # Remove all items prior to start just to make sure unregister_all() + # httpServer = HTTPServer(('127.0.0.1', HTTP_PORT), MyHTTPHandler) + + # def serveFunc(): + # try: + # print('Http serve') + # httpServer.serve_forever() + # except: + # print('Error') + # logging.getLogger(f"{INTERNAL_ID}").error( + # "Failed:\n{}".format(traceback.format_exc()) + # ) + + # serveThread = Thread(target = serveFunc) + # serveThread.run() + # creates the UI elements register_ui() @@ -46,6 +69,10 @@ def stop(_): try: unregister_all() + if httpServer: + httpServer.server_close() + httpServer = None + app = adsk.core.Application.get() ui = app.userInterface diff --git a/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py b/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py new file mode 100644 index 0000000000..9ce5c9e80f --- /dev/null +++ b/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py @@ -0,0 +1,17 @@ +from http.server import BaseHTTPRequestHandler +import logging + +from ..general_imports import INTERNAL_ID +# from socketserver import BaseRequestHandler + +class MyHTTPHandler(BaseHTTPRequestHandler): + + def __init__(self, a, b, c): + print('init') + pass + + def do_GET(self): + logging.getLogger(f'{INTERNAL_ID}').debug('Request') + self.send_response(200) + self.end_headers() + self.wfile.write(bytes('test')) diff --git a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py index 4c540f5bd5..dbd2350d4a 100644 --- a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py @@ -1192,12 +1192,12 @@ def notify(self, args): # defaultPath = self.fp # defaultPath = os.getenv() - # if mode == 5: - # savepath = FileDialogConfig.SaveFileDialog( - # defaultPath=self.fp, ext="Synthesis File (*.synth)" - # ) - # else: - # savepath = FileDialogConfig.SaveFileDialog(defaultPath=self.fp) + if mode == 5: + savepath = FileDialogConfig.SaveFileDialog( + defaultPath=self.fp, ext="Synthesis File (*.synth)" + ) + else: + savepath = FileDialogConfig.SaveFileDialog(defaultPath=self.fp) processedFileName = gm.app.activeDocument.name.replace(" ", "_") dropdownExportMode = INPUTS_ROOT.itemById("mode") @@ -1206,55 +1206,55 @@ def notify(self, args): elif dropdownExportMode.selectedItem.index == 1: isRobot = False - if platform.system() == "Windows": - if isRobot: - if export_as_part_boolean.value: - savepath = ( - os.getenv("APPDATA") - + "\\Autodesk\\Synthesis\\MixAndMatch\\Mira\\" - + processedFileName - + ".mira" - ) - else: - savepath = ( - os.getenv("APPDATA") - + "\\Autodesk\\Synthesis\\Mira\\" - + processedFileName - + ".mira" - ) - else: - savepath = ( - os.getenv("APPDATA") - + "\\Autodesk\\Synthesis\\Mira\\Fields\\" - + processedFileName - + ".mira" - ) - else: - from os.path import expanduser - - home = expanduser("~") - if isRobot: - if export_as_part_boolean.value: - savepath = ( - home - + "/.config/Autodesk/Synthesis/MixAndMatch/Mira/" - + processedFileName - + ".mira" - ) - else: - savepath = ( - home - + "/.config/Autodesk/Synthesis/Mira/" - + processedFileName - + ".mira" - ) - else: - savepath = ( - home - + "/.config/Autodesk/Synthesis/Mira/Fields/" - + processedFileName - + ".mira" - ) + # if platform.system() == "Windows": + # if isRobot: + # if export_as_part_boolean.value: + # savepath = ( + # os.getenv("APPDATA") + # + "\\Autodesk\\Synthesis\\MixAndMatch\\Mira\\" + # + processedFileName + # + ".mira" + # ) + # else: + # savepath = ( + # os.getenv("APPDATA") + # + "\\Autodesk\\Synthesis\\Mira\\" + # + processedFileName + # + ".mira" + # ) + # else: + # savepath = ( + # os.getenv("APPDATA") + # + "\\Autodesk\\Synthesis\\Mira\\Fields\\" + # + processedFileName + # + ".mira" + # ) + # else: + # from os.path import expanduser + + # home = expanduser("~") + # if isRobot: + # if export_as_part_boolean.value: + # savepath = ( + # home + # + "/.config/Autodesk/Synthesis/MixAndMatch/Mira/" + # + processedFileName + # + ".mira" + # ) + # else: + # savepath = ( + # home + # + "/.config/Autodesk/Synthesis/Mira/" + # + processedFileName + # + ".mira" + # ) + # else: + # savepath = ( + # home + # + "/.config/Autodesk/Synthesis/Mira/Fields/" + # + processedFileName + # + ".mira" + # ) if savepath == False: # save was canceled From c3dbff63b7af9f6677a59122e8572e3bcabd75d7 Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Sat, 15 Jun 2024 00:01:55 -0600 Subject: [PATCH 02/14] Fusion API is proving annoying --- exporter/SynthesisFusionAddin/Synthesis.py | 38 +++++++++++++++---- .../src/Fission/HttpServer.py | 4 +- .../src/Parser/SynthesisParser/Parser.py | 6 ++- .../src/general_imports.py | 2 +- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index bbd3a67ee4..53badbbee1 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -1,6 +1,8 @@ from http.server import HTTPServer from threading import Thread +import adsk.fusion + from .src.Fission.HttpServer import MyHTTPHandler from .src.general_imports import root_logger, gm, INTERNAL_ID, APP_NAME, DESCRIPTION @@ -15,11 +17,6 @@ from .src.UI import MarkingMenu import adsk.core -httpServer: HTTPServer | None = None -serveThread: Thread | None = None - -HTTP_PORT = 3004 - def run(_): """## Entry point to application from Fusion 360. @@ -31,7 +28,7 @@ def run(_): # Remove all items prior to start just to make sure unregister_all() - # httpServer = HTTPServer(('127.0.0.1', HTTP_PORT), MyHTTPHandler) + # httpServer = HTTPServer(('', HTTP_PORT), MyHTTPHandler) # def serveFunc(): # try: @@ -45,6 +42,7 @@ def run(_): # serveThread = Thread(target = serveFunc) # serveThread.run() + # serveFunc() # creates the UI elements register_ui() @@ -59,7 +57,6 @@ def run(_): "Failed:\n{}".format(traceback.format_exc()) ) - def stop(_): """## Fusion 360 exit point - deconstructs buttons and handlers @@ -155,4 +152,31 @@ def register_ui() -> None: command=True, ) + app = adsk.core.Application.get() + ui = app.userInterface + + showPaletteCmdDef = ui.commandDefinitions.itemById('showAPSLogin') + if showPaletteCmdDef: + if not showPaletteCmdDef.deleteMe(): + print('fhsdja') + else: + print('fdshjs') + + showPaletteCmdDef = None + + if not showPaletteCmdDef: + showPaletteCmdDef = ui.commandDefinitions.addButtonDefinition('showAPSLogin', 'Show Custom Synthesis Palette', 'Show the custom palette', '') + + class CreateHandlerThing(adsk.core.CommandCreatedEventHandler): + def notify(self, args: adsk.core.CommandCreatedEventArgs): + print('Eyyooo') + + # Connect to Command Created event. + showPaletteCmdDef.commandCreated.add(CreateHandlerThing()) + + panel = ui.allToolbarPanels.itemById('SolidScriptsAddinsPanel') + cntrl = panel.controls.itemById('showAPSLogin') + if not cntrl: + panel.controls.addCommand(showPaletteCmdDef) + gm.elements.append(commandButton) diff --git a/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py b/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py index 9ce5c9e80f..ef99966693 100644 --- a/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py +++ b/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py @@ -8,9 +8,11 @@ class MyHTTPHandler(BaseHTTPRequestHandler): def __init__(self, a, b, c): print('init') - pass + print(f'{self.address_string}') + print(f'{self.command}') def do_GET(self): + print('get') logging.getLogger(f'{INTERNAL_ID}').debug('Request') self.send_response(200) self.end_headers() diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py index bf3cae59a7..70993d36fe 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py @@ -29,7 +29,11 @@ def __init__(self, options: any): def export(self) -> bool: try: app = adsk.core.Application.get() - design = app.activeDocument.design + design: adsk.fusion.Design = app.activeDocument.design + + folder = design.parentDocument.dataFile.parentFolder + print(f'===\nFolder\nName: {folder.name}\n===') + folder.uploadFile(f'{design.parentDocument.name}_mira') assembly_out = assembly_pb2.Assembly() fill_info( diff --git a/exporter/SynthesisFusionAddin/src/general_imports.py b/exporter/SynthesisFusionAddin/src/general_imports.py index 7c2711ee77..e32e90df39 100644 --- a/exporter/SynthesisFusionAddin/src/general_imports.py +++ b/exporter/SynthesisFusionAddin/src/general_imports.py @@ -46,7 +46,7 @@ A_EP = None # Setup the global state - gm = GlobalManager() + gm: GlobalManager = GlobalManager() my_addin_path = os.path.dirname(os.path.realpath(__file__)) except: # should also log this From 882aa2a7aa632d73a08fac29ebf35c9fc4f63cf1 Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Sat, 15 Jun 2024 19:15:21 -0600 Subject: [PATCH 03/14] Edit joint panel with marking menu button --- .../src/UI/ConfigCommand.py | 10 + .../src/UI/Configuration/JointEditPanel.py | 13 + .../src/UI/MarkingMenu.py | 432 ++++++++++-------- .../src/UI/Util/EventHandlers.py | 68 +++ 4 files changed, 331 insertions(+), 192 deletions(-) create mode 100644 exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py create mode 100644 exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py diff --git a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py index dbd2350d4a..76875dc49e 100644 --- a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py @@ -5,6 +5,8 @@ from enum import Enum import platform +from .Util.EventHandlers import MakeCommandExecuteHandler + from ..Parser.SynthesisParser.Utilities import guid_occurrence from ..general_imports import * from ..configure import NOTIFIED, write_configuration @@ -954,6 +956,14 @@ def notify(self, args): ), previous.filePath, ) + + def t(args: adsk.core.CommandEventArgs): + print('sup') + + a = MakeCommandExecuteHandler(t) + + # onExecute = CommandExecuteHandlerShort(lambda args: logging.getLogger(f'{INTERNAL_ID}').debug('Hello world from execute')) + cmd.execute.add(onExecute) gm.handlers.append(onExecute) # 0 diff --git a/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py b/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py new file mode 100644 index 0000000000..bee12110c8 --- /dev/null +++ b/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py @@ -0,0 +1,13 @@ +from adsk.core import * +from adsk.fusion import * + +def BuildJointEditPanel(joint: Joint, args: CommandCreatedEventArgs): + inputs = args.command.commandInputs + + cmdTest = inputs.itemById('test') + if cmdTest: + cmdTest.deleteMe() + + cmdTest = inputs.addBoolValueInput('test', 'Test Boolean Input', False) + + print('Built joint edit panel') \ No newline at end of file diff --git a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py index 0a1fbadcbf..6bf8f177e6 100644 --- a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py +++ b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py @@ -1,3 +1,5 @@ +from .Util.EventHandlers import * +from .Configuration.JointEditPanel import * import adsk.core, adsk.fusion, traceback import logging.handlers @@ -10,55 +12,24 @@ entities = [] occurrencesOfComponents = {} +DROPDOWN_ID = "SynthesisMain" +DROPDOWN_COLLISION_ID = "synthesis" +DROPDOWN_CONFIG_ID = "SynthesisConfig" -def setupMarkingMenu(ui: adsk.core.UserInterface): - handlers.clear() - try: - - def setLinearMarkingMenu(args): - try: - menuArgs = adsk.core.MarkingMenuEventArgs.cast(args) - - linearMenu = menuArgs.linearMarkingMenu - linearMenu.controls.addSeparator("LinearSeparator") - - synthDropDown = linearMenu.controls.addDropDown( - "Synthesis", "", "synthesis" - ) +SEPARATOR = "LinearSeparator" - cmdSelectDisabled = ui.commandDefinitions.itemById("SelectDisabled") - synthDropDown.controls.addCommand(cmdSelectDisabled) +COMM_SELECT_DISABLED = "SelectDisabled" +COMM_ENABLE_ALL = "EnableAllCollision" +COMM_DISABLE_COLLISION = "DisableCollision" +COMM_ENABLE_COLLISION = "EnableCollision" +COMM_DELETE = "DeleteComponent" - synthDropDown.controls.addSeparator() - - cmdEnableAll = ui.commandDefinitions.itemById("EnableAllCollision") - synthDropDown.controls.addCommand(cmdEnableAll) - synthDropDown.controls.addSeparator() - - if args.selectedEntities: - sel0 = args.selectedEntities[0] - occ = adsk.fusion.Occurrence.cast(sel0) - - if occ: - if ( - occ.attributes.itemByName("synthesis", "collision_off") - == None - ): - cmdDisableCollision = ui.commandDefinitions.itemById( - "DisableCollision" - ) - synthDropDown.controls.addCommand(cmdDisableCollision) - else: - cmdEnableCollision = ui.commandDefinitions.itemById( - "EnableCollision" - ) - synthDropDown.controls.addCommand(cmdEnableCollision) - except: - if ui: - ui.messageBox("setting linear menu failed: {}").format( - traceback.format_exc() - ) +COMM_EDIT_JOINT = "EditJoint" +def setupMarkingMenu(ui: adsk.core.UserInterface): + print('Setting up mark up menu') + handlers.clear() + try: def setCollisionAttribute(occ: adsk.fusion.Occurrence, isEnabled: bool = True): attr = occ.attributes.itemByName("synthesis", "collision_off") if attr == None and not isEnabled: @@ -79,159 +50,236 @@ def applyToSelfAndAllChildren(occ: adsk.fusion.Occurrence, modFunc): if o.childOccurrences.count > 0: childLists.append(o.childOccurrences) - class MyCommandCreatedEventHandler(adsk.core.CommandCreatedEventHandler): - def __init__(self): - super().__init__() - - def notify(self, args): - try: - command = args.command - onCommandExcute = MyCommandExecuteHandler() - handlers.append(onCommandExcute) - command.execute.add(onCommandExcute) - except: - ui.messageBox("command created failed: {}").format( - traceback.format_exc() - ) - - class MyCommandExecuteHandler(adsk.core.CommandEventHandler): - def __init__(self): - super().__init__() - - def notify(self, args): - try: - command = args.firingEvent.sender - cmdDef = command.parentCommandDefinition - if cmdDef: - if cmdDef.id == "EnableCollision": - # ui.messageBox('Enable') - if entities: - func = lambda occ: setCollisionAttribute(occ, True) - for e in entities: - occ = adsk.fusion.Occurrence.cast(e) - if occ: - applyToSelfAndAllChildren(occ, func) - elif cmdDef.id == "DisableCollision": - # ui.messageBox('Disable') - if entities: - func = lambda occ: setCollisionAttribute(occ, False) - for e in entities: - occ = adsk.fusion.Occurrence.cast(e) - if occ: - applyToSelfAndAllChildren(occ, func) - elif cmdDef.id == "SelectDisabled": - app = adsk.core.Application.get() - product = app.activeProduct - design = adsk.fusion.Design.cast(product) - ui.activeSelections.clear() - if design: - attrs = design.findAttributes( - "synthesis", "collision_off" - ) - for attr in attrs: - for b in adsk.fusion.Occurrence.cast( - attr.parent - ).bRepBodies: - ui.activeSelections.add(b) - elif cmdDef.id == "EnableAllCollision": - app = adsk.core.Application.get() - product = app.activeProduct - design = adsk.fusion.Design.cast(product) - if design: - for attr in design.findAttributes( - "synthesis", "collision_off" - ): - attr.deleteMe() - else: - ui.messageBox("command {} triggered.".format(cmdDef.id)) - else: - ui.messageBox("No CommandDefinition") - except: - ui.messageBox("command executed failed: {}").format( - traceback.format_exc() - ) - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) - - class MyMarkingMenuHandler(adsk.core.MarkingMenuEventHandler): - def __init__(self): - super().__init__() - - def notify(self, args): - try: - setLinearMarkingMenu(args) - - global occurrencesOfComponents - - # selected entities - global entities - entities.clear() - entities = args.selectedEntities - except: - if ui: - ui.messageBox( - "Marking Menu Displaying event failed: {}".format( - traceback.format_exc() + def handleCommandExecute(args: adsk.core.CommandEventArgs): + try: + command = args.firingEvent.sender + cmdDef = CommandDefinition.cast(command.parentCommandDefinition) + if cmdDef: + if cmdDef.id == COMM_ENABLE_COLLISION: + # ui.messageBox('Enable') + if entities: + func = lambda occ: setCollisionAttribute(occ, True) + for e in entities: + occ = adsk.fusion.Occurrence.cast(e) + if occ: + applyToSelfAndAllChildren(occ, func) + elif cmdDef.id == COMM_DISABLE_COLLISION: + # ui.messageBox('Disable') + if entities: + func = lambda occ: setCollisionAttribute(occ, False) + for e in entities: + occ = adsk.fusion.Occurrence.cast(e) + if occ: + applyToSelfAndAllChildren(occ, func) + elif cmdDef.id == COMM_SELECT_DISABLED: + app = adsk.core.Application.get() + product = app.activeProduct + design = adsk.fusion.Design.cast(product) + ui.activeSelections.clear() + if design: + attrs = design.findAttributes( + "synthesis", "collision_off" ) - ) + for attr in attrs: + for b in adsk.fusion.Occurrence.cast( + attr.parent + ).bRepBodies: + ui.activeSelections.add(b) + elif cmdDef.id == COMM_ENABLE_ALL: + app = adsk.core.Application.get() + product = app.activeProduct + design = adsk.fusion.Design.cast(product) + if design: + for attr in design.findAttributes( + "synthesis", "collision_off" + ): + attr.deleteMe() + # elif cmdDef.id == COMM_EDIT_JOINT: + # if entities: + # joint = adsk.fusion.Joint.case(entities[0]) + # if joint: + # print('Joint edit') + else: + ui.messageBox("command {} triggered.".format(cmdDef.id)) + else: + ui.messageBox("No CommandDefinition") + except: + print('Error') + ui.messageBox("command executed failed: {}").format( + traceback.format_exc() + ) + logging.getLogger(f"{INTERNAL_ID}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) - # Add customized handler for marking menu displaying - onMarkingMenuDisplaying = MyMarkingMenuHandler() - handlers.append(onMarkingMenuDisplaying) - ui.markingMenuDisplaying.add(onMarkingMenuDisplaying) + def handleMarkingMenu(args: adsk.core.MarkingMenuEventArgs): + linearMenu = args.linearMarkingMenu + linearMenu.controls.addSeparator(SEPARATOR) - # Add customized handler for commands creating - onCommandCreated = MyCommandCreatedEventHandler() - handlers.append(onCommandCreated) - - cmdDisableCollision = ui.commandDefinitions.itemById("DisableCollision") - if not cmdDisableCollision: - cmdDisableCollision = ui.commandDefinitions.addButtonDefinition( - "DisableCollision", - "Disable Collisions", - "Disable collisions with this occurrence inside Synthesis", - ) - cmdDisableCollision.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdDisableCollision) - cmdEnableCollision = ui.commandDefinitions.itemById("EnableCollision") - if not cmdEnableCollision: - cmdEnableCollision = ui.commandDefinitions.addButtonDefinition( - "EnableCollision", - "Enable Collisions", - "Enable collisions with this occurrence inside Synthesis", - ) - cmdEnableCollision.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdEnableCollision) - cmdEnableAllCollision = ui.commandDefinitions.itemById("EnableAllCollision") - if not cmdEnableAllCollision: - cmdEnableAllCollision = ui.commandDefinitions.addButtonDefinition( - "EnableAllCollision", - "Enable All Collision", - "Enable collisions for all occurrences in design", + synthesisDropDown = linearMenu.controls.addDropDown( + "Synthesis", "", DROPDOWN_ID ) - cmdEnableAllCollision.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdEnableAllCollision) - - cmdSelectDisabled = ui.commandDefinitions.itemById("SelectDisabled") - if not cmdSelectDisabled: - cmdSelectDisabled = ui.commandDefinitions.addButtonDefinition( - "SelectDisabled", - "Selected Collision Disabled Occurrences", - "Select all occurrences labeled for collision disabled", + + ''' + COLLISION + ''' + synthesisCollisionDropDown = synthesisDropDown.controls.addDropDown( + "Collision", "", DROPDOWN_COLLISION_ID ) - cmdSelectDisabled.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdSelectDisabled) - - cmdDeleteComponent = ui.commandDefinitions.itemById("DeleteComponent") - if not cmdDeleteComponent: - cmdDeleteComponent = ui.commandDefinitions.addButtonDefinition( - "DeleteComponent", - "Delete All Occurrences", - "Delete all occurrences with the same component", + + cmdSelectDisabled = ui.commandDefinitions.itemById(COMM_SELECT_DISABLED) + synthesisCollisionDropDown.controls.addCommand(cmdSelectDisabled) + + synthesisCollisionDropDown.controls.addSeparator() + + cmdEnableAll = ui.commandDefinitions.itemById(COMM_ENABLE_ALL) + synthesisCollisionDropDown.controls.addCommand(cmdEnableAll) + synthesisCollisionDropDown.controls.addSeparator() + + if args.selectedEntities: + sel0 = args.selectedEntities[0] + occ = adsk.fusion.Occurrence.cast(sel0) + + if occ: + if not occ.attributes.itemByName("synthesis", "collision_off"): + cmdDisableCollision = ui.commandDefinitions.itemById(COMM_DISABLE_COLLISION) + synthesisCollisionDropDown.controls.addCommand(cmdDisableCollision) + else: + cmdEnableCollision = ui.commandDefinitions.itemById(COMM_ENABLE_COLLISION) + synthesisCollisionDropDown.controls.addCommand(cmdEnableCollision) + + ''' + CONFIGURATION + ''' + synthesisConfigDropDown = synthesisDropDown.controls.itemById(DROPDOWN_CONFIG_ID) + if synthesisConfigDropDown: + synthesisConfigDropDown.deleteMe() + + synthesisConfigDropDown = synthesisDropDown.controls.addDropDown( + "Config", "", DROPDOWN_CONFIG_ID ) - cmdDeleteComponent.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdDeleteComponent) + + configEmpty = True + + if args.selectedEntities and len(args.selectedEntities) == 1: + selectedJoint = adsk.fusion.Joint.cast(args.selectedEntities[0]) + + if selectedJoint: + cmdEditJoint = ui.commandDefinitions.itemById(COMM_EDIT_JOINT) + synthesisConfigDropDown.controls.addCommand(cmdEditJoint) + configEmpty = False + + if configEmpty: + synthesisConfigDropDown.deleteMe() + + ''' + Globals + ''' + global occurrencesOfComponents + + # selected entities + global entities + entities.clear() + entities = args.selectedEntities + + # Add customized handler for marking menu displaying + ui.markingMenuDisplaying.add(MakeMarkingMenuEventHandler(handleMarkingMenu, handlers)) + + # Add customized handler for commands creating + + def handleCommandCreated(args: adsk.core.CommandCreatedEventArgs): + args.command.execute.add(MakeCommandExecuteHandler(handleCommandExecute, handlers)) + + onCommandCreated = MakeCommandCreatedHandler(handleCommandCreated, handlers) + + # Disable Collision Button + cmdDisableCollision = ui.commandDefinitions.itemById(COMM_DISABLE_COLLISION) + if cmdDisableCollision: + cmdDisableCollision.deleteMe() + + cmdDisableCollision = ui.commandDefinitions.addButtonDefinition( + COMM_DISABLE_COLLISION, + "Disable Collisions", + "Disable collisions with this occurrence inside Synthesis", + ) + cmdDisableCollision.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdDisableCollision) + + # Enable Collision Button + cmdEnableCollision = ui.commandDefinitions.itemById(COMM_ENABLE_COLLISION) + if cmdEnableCollision: + cmdEnableCollision.deleteMe() + + cmdEnableCollision = ui.commandDefinitions.addButtonDefinition( + COMM_ENABLE_COLLISION, + "Enable Collisions", + "Enable collisions with this occurrence inside Synthesis", + ) + cmdEnableCollision.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdEnableCollision) + + # Enable All Collision Button + cmdEnableAllCollision = ui.commandDefinitions.itemById(COMM_ENABLE_ALL) + if cmdEnableAllCollision: + cmdEnableAllCollision.deleteMe() + + cmdEnableAllCollision = ui.commandDefinitions.addButtonDefinition( + COMM_ENABLE_ALL, + "Enable All Collision", + "Enable collisions for all occurrences in design", + ) + cmdEnableAllCollision.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdEnableAllCollision) + + # Select Disabled Button + cmdSelectDisabled = ui.commandDefinitions.itemById(COMM_SELECT_DISABLED) + if cmdSelectDisabled: + cmdSelectDisabled.deleteMe() + + cmdSelectDisabled = ui.commandDefinitions.addButtonDefinition( + COMM_SELECT_DISABLED, + "Selected Collision Disabled Occurrences", + "Select all occurrences labeled for collision disabled", + ) + cmdSelectDisabled.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdSelectDisabled) + + # Delete Component Button + cmdDeleteComponent = ui.commandDefinitions.itemById(COMM_DELETE) + if cmdDeleteComponent: + cmdDeleteComponent.deleteMe() + + cmdDeleteComponent = ui.commandDefinitions.addButtonDefinition( + COMM_DELETE, + "Delete All Occurrences", + "Delete all occurrences with the same component", + ) + cmdDeleteComponent.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdDeleteComponent) + + ''' + CONFIG COMMANDS + ''' + def handleEditJoint(args: CommandCreatedEventArgs): + if entities: + joint = adsk.fusion.Joint.cast(entities[0]) + if joint: + BuildJointEditPanel(joint, args) + + onJointEditCreated = MakeCommandCreatedHandler( + handleEditJoint, + handlers + ) + + cmdEditJoint = ui.commandDefinitions.itemById(COMM_EDIT_JOINT) + if cmdEditJoint: + cmdEditJoint.deleteMe() + + cmdEditJoint = ui.commandDefinitions.addButtonDefinition( + COMM_EDIT_JOINT, "Edit Joint", "Edit joint details for Synthesis" + ) + cmdEditJoint.commandCreated.add(onJointEditCreated) + cmdDefs.append(cmdEditJoint) except: ui.messageBox("Failed:\n{}".format(traceback.format_exc())) diff --git a/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py b/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py new file mode 100644 index 0000000000..28f5b2d588 --- /dev/null +++ b/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py @@ -0,0 +1,68 @@ +from typing import List +from adsk.core import * +from adsk.core import MarkingMenuEventArgs + +from ...general_imports import INTERNAL_ID, gm +import logging, traceback + +def ErrorHandle(handler, eventArgs): + try: + handler(eventArgs) + except: + gm.ui.messageBox("command executed failed: {}").format( + traceback.format_exc() + ) + logging.getLogger(f"{INTERNAL_ID}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) + +class _CommandCreatedHandlerShort(CommandCreatedEventHandler): + def __init__(self, handler): + super().__init__() + self.handler = handler + + def notify(self, eventArgs: CommandCreatedEventArgs) -> None: + ErrorHandle(self.handler, eventArgs) + +class _CommandExecuteHandlerShort(CommandEventHandler): + def __init__(self, handler): + super().__init__() + self.handler = handler + + def notify(self, eventArgs: CommandEventArgs) -> None: + ErrorHandle(self.handler, eventArgs) + +class _SelectionEventHandlerShort(SelectionEventHandler): + def __init__(self, handler): + super().__init__() + self.handler = handler + + def notify(self, eventArgs: SelectionEventArgs) -> None: + ErrorHandle(self.handler, eventArgs) + +class _MarkingMenuEventHandlerShort(MarkingMenuEventHandler): + def __init__(self, handler): + super().__init__() + self.handler = handler + + def notify(self, eventArgs: MarkingMenuEventArgs) -> None: + # print('AHHH') + ErrorHandle(self.handler, eventArgs) + +def MakeCommandCreatedHandler(notify, handlerCollection: List | None = None) -> _CommandCreatedHandlerShort: + handler = _CommandCreatedHandlerShort(notify) + if handlerCollection is not None: + handlerCollection.append(handler) + return handler + +def MakeCommandExecuteHandler(notify, handlerCollection: List | None = None) -> _CommandExecuteHandlerShort: + handler = _CommandExecuteHandlerShort(notify) + if handlerCollection is not None: + handlerCollection.append(handler) + return handler + +def MakeMarkingMenuEventHandler(notify, handlerCollection: List | None = None) -> _MarkingMenuEventHandlerShort: + handler = _MarkingMenuEventHandlerShort(notify) + if handlerCollection is not None: + handlerCollection.append(handler) + return handler \ No newline at end of file From 0f840360d87bca8126e1eb4446418caf5c2e6445 Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Sat, 15 Jun 2024 23:55:03 -0600 Subject: [PATCH 04/14] Sample edit panel in Fusion, download functions for Fission --- .../src/UI/ConfigCommand.py | 6 ++++ .../src/UI/Configuration/JointEditPanel.py | 31 ++++++++++++++----- .../src/UI/MarkingMenu.py | 2 +- .../src/UI/Util/EventHandlers.py | 4 +-- fission/src/aps/APSDataManagement.ts | 24 ++++++++++++++ .../src/modals/mirabuf/ImportMirabufModal.tsx | 4 +-- 6 files changed, 58 insertions(+), 13 deletions(-) diff --git a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py index 76875dc49e..f5bc38e6d4 100644 --- a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py @@ -999,6 +999,11 @@ def t(args: adsk.core.CommandEventArgs): cmd.destroy.add(onDestroy) gm.handlers.append(onDestroy) # 8 + app = adsk.core.Application.get() + document = app.activeDocument + if document.isModified: + print('Modified') + except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) @@ -1513,6 +1518,7 @@ def notify(self, args): gm.app.activeViewport.refresh() else: gm.app.activeDocument.design.rootComponent.opacity = 1 + for ( group ) in gm.app.activeDocument.design.rootComponent.customGraphicsGroups: diff --git a/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py b/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py index bee12110c8..109d80fc70 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py +++ b/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py @@ -1,13 +1,30 @@ from adsk.core import * from adsk.fusion import * +from ..Util.EventHandlers import * -def BuildJointEditPanel(joint: Joint, args: CommandCreatedEventArgs): +COMM_JOINT_SPEED = 'JointSpeed' + +handlers = [] + +def remove(id: str, inputs: CommandInputs): + cmd = inputs.itemById(id) + if cmd: + cmd.deleteMe() + +def buildJointEditPanel(joint: Joint, args: CommandCreatedEventArgs): inputs = args.command.commandInputs - cmdTest = inputs.itemById('test') - if cmdTest: - cmdTest.deleteMe() - - cmdTest = inputs.addBoolValueInput('test', 'Test Boolean Input', False) + remove(COMM_JOINT_SPEED, inputs) + cmdJointSpeed = inputs.addValueInput( + COMM_JOINT_SPEED, + 'Joint Speed', + 'deg', + ValueInput.createByReal(3.1415926) + ) + + args.command.execute.add(MakeCommandExecuteHandler(updateJointInfo, handlers)) + + print('Built joint edit panel') - print('Built joint edit panel') \ No newline at end of file +def updateJointInfo(args: CommandEventArgs): + print(f'Executing') \ No newline at end of file diff --git a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py index 6bf8f177e6..e8e07440fd 100644 --- a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py +++ b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py @@ -264,7 +264,7 @@ def handleEditJoint(args: CommandCreatedEventArgs): if entities: joint = adsk.fusion.Joint.cast(entities[0]) if joint: - BuildJointEditPanel(joint, args) + buildJointEditPanel(joint, args) onJointEditCreated = MakeCommandCreatedHandler( handleEditJoint, diff --git a/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py b/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py index 28f5b2d588..9931b81fb4 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py +++ b/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py @@ -9,9 +9,7 @@ def ErrorHandle(handler, eventArgs): try: handler(eventArgs) except: - gm.ui.messageBox("command executed failed: {}").format( - traceback.format_exc() - ) + gm.ui.messageBox(f'command executed failed: {traceback.format_exc()}') logging.getLogger(f"{INTERNAL_ID}").error( "Failed:\n{}".format(traceback.format_exc()) ) diff --git a/fission/src/aps/APSDataManagement.ts b/fission/src/aps/APSDataManagement.ts index 264f095872..dd568d9070 100644 --- a/fission/src/aps/APSDataManagement.ts +++ b/fission/src/aps/APSDataManagement.ts @@ -148,4 +148,28 @@ export async function getFolderData(project: Project, folder: Folder): Promise { + const auth = APS.auth + if (!auth) { + return undefined + } + + try { + return await fetch(`https://developer.api.autodesk.com/data/v1/projects/${project.id}/items/${item.id}`, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${auth.access_token}` + } + }).then(x => x.json()).then(async x => { + console.debug(x) + const downloadLink = x.included[0].relationships.storage.meta.link.href + console.debug(`Download Link: ${downloadLink}`) + return await fetch(downloadLink, { method: 'GET', headers: { 'Authorization': `Bearer ${auth.access_token}` } }) + }).then(x => x.blob()).then(x => { window.open(URL.createObjectURL(x)) }) + } catch (e) { + console.error('Failed to download item') + return undefined + } } \ No newline at end of file diff --git a/fission/src/modals/mirabuf/ImportMirabufModal.tsx b/fission/src/modals/mirabuf/ImportMirabufModal.tsx index 564976cdd0..85d132844f 100644 --- a/fission/src/modals/mirabuf/ImportMirabufModal.tsx +++ b/fission/src/modals/mirabuf/ImportMirabufModal.tsx @@ -3,7 +3,7 @@ import Modal, { ModalPropsImpl } from "../../components/Modal" import { FaPlus } from "react-icons/fa6" import Button from "@/components/Button"; import Label, { LabelSize } from "@/components/Label"; -import { Data, Folder, Hub, Item, Project, getFolderData, getHubs, getProjects } from "@/aps/APSDataManagement"; +import { Data, Folder, Hub, Item, Project, downloadItem, getFolderData, getHubs, getProjects } from "@/aps/APSDataManagement"; interface ItemCardProps { id: string; @@ -109,7 +109,7 @@ const ImportMirabufModal: React.FC = ({ modalId }) => { : folderData?.map(x => x instanceof Folder ? ItemCard({ name: `DIR: ${x.displayName}`, id: x.id, buttonText: '>', onClick: () => setSelectedFolder(x) }) : x instanceof Item - ? ItemCard({ name: `${x.displayName}`, id: x.id, buttonText: 'import', onClick: () => { console.log(`Selecting ${x.displayName} (${x.id})`) } }) + ? ItemCard({ name: `${x.displayName}`, id: x.id, buttonText: 'import', onClick: () => { downloadItem(selectedProject, x) } }) : ItemCard({ name: `${x.type}: ${x.id}`, id: x.id, buttonText: '---', onClick: () => { console.log(`Selecting (${x.id})`) } }) ) } From 26e3152f51c8e99a95d3fa6c007ddd007f386483 Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Sun, 16 Jun 2024 13:18:54 -0600 Subject: [PATCH 05/14] Working on import --- fission/src/Synthesis.tsx | 2 + fission/src/components/MainHUD.tsx | 5 ++ .../mirabuf/ImportLocalMirabufModal.tsx | 68 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 fission/src/modals/mirabuf/ImportLocalMirabufModal.tsx diff --git a/fission/src/Synthesis.tsx b/fission/src/Synthesis.tsx index 7cfd69ca47..9d7bf98725 100644 --- a/fission/src/Synthesis.tsx +++ b/fission/src/Synthesis.tsx @@ -53,6 +53,7 @@ import ManageAssembliesModal from './modals/spawning/ManageAssembliesModal.tsx'; import World from './systems/World.ts'; import { AddRobotsModal, AddFieldsModal, SpawningModal } from './modals/spawning/SpawningModals.tsx'; import ImportMirabufModal from './modals/mirabuf/ImportMirabufModal.tsx'; +import ImportLocalMirabufModal from './modals/mirabuf/ImportLocalMirabufModal.tsx'; const DEFAULT_MIRA_PATH = '/api/mira/Robots/Team 2471 (2018)_v7.mira'; @@ -273,6 +274,7 @@ const initialModals = [ , , , + , ] const initialPanels: ReactElement[] = [ diff --git a/fission/src/components/MainHUD.tsx b/fission/src/components/MainHUD.tsx index d1178622e8..9a53ed9e7f 100644 --- a/fission/src/components/MainHUD.tsx +++ b/fission/src/components/MainHUD.tsx @@ -147,6 +147,11 @@ const MainHUD: React.FC = () => { icon={} onClick={() => openModal("import-mirabuf")} /> + } + onClick={() => openModal("import-local-mirabuf")} + />
= ({ modalId }) => { + // update tooltip based on type of drivetrain, receive message from Synthesis + const { showTooltip } = useTooltipControlContext() + + const fileUploadRef = useRef(null) + + const [selectedFile, setSelectedFile] = useState(undefined) + + const uploadClicked = () => { + if (fileUploadRef.current) { + fileUploadRef.current.click() + } + } + + const onInputChanged = (e: ChangeEvent) => { + if (e.target.files) { + const file = e.target.files[0] + setSelectedFile(file) + } + } + + return ( + } + modalId={modalId} + acceptEnabled={selectedFile == undefined} + onAccept={() => { + if (selectedFile) { + console.log(`Mira: '${selectedFile}'`) + showTooltip("controls", [ + { control: "WASD", description: "Drive" }, + { control: "E", description: "Intake" }, + { control: "Q", description: "Dispense" }, + ]) + + CreateMirabufFromUrl(URL.createObjectURL(selectedFile)).then(x => { + if (x) { + World.SceneRenderer.RegisterSceneObject(x) + } + }) + } + } + } + > +
+ +
+
+ ) +} + +export default ImportLocalMirabufModal \ No newline at end of file From e33c803543e33a7f1da57d6a33512cac934ece31 Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Thu, 20 Jun 2024 11:32:06 -0700 Subject: [PATCH 06/14] Fixed elevator behavior and added velocity control to slider drivers --- .../behavior/GenericElevatorBehavior.ts | 10 ++-- .../src/systems/simulation/driver/Driver.ts | 5 ++ .../systems/simulation/driver/HingeDriver.ts | 11 ++--- .../systems/simulation/driver/SliderDriver.ts | 49 ++++++++++++++++--- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts index 1190cff16a..e77b037eae 100644 --- a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts @@ -9,7 +9,7 @@ class GenericElevatorBehavior extends Behavior { private _positiveInput: string; private _negativeInput: string; - private _linearSpeed = 1; + private _linearSpeed = 10; constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, jointIndex: number) { super([sliderDriver], [sliderStimulus]); @@ -25,12 +25,12 @@ class GenericElevatorBehavior extends Behavior { } // Changes the elevators target position - moveElevator(positionDelta: number) { - this._sliderDriver.targetPosition += positionDelta; + moveElevator(linearVelocity: number) { + this._sliderDriver.targetVelocity = linearVelocity; } - public Update(deltaT: number): void { - this.moveElevator(InputSystem.GetAxis(this._positiveInput, this._negativeInput)*this._linearSpeed*deltaT); + public Update(_: number): void { + this.moveElevator(InputSystem.GetAxis(this._positiveInput, this._negativeInput)*this._linearSpeed); } } diff --git a/fission/src/systems/simulation/driver/Driver.ts b/fission/src/systems/simulation/driver/Driver.ts index 19361c0361..409cebfbdf 100644 --- a/fission/src/systems/simulation/driver/Driver.ts +++ b/fission/src/systems/simulation/driver/Driver.ts @@ -2,4 +2,9 @@ abstract class Driver { public abstract Update(deltaT: number): void; } +export enum DriverControlMode { + Velocity = 0, + Position = 1 +} + export default Driver; \ No newline at end of file diff --git a/fission/src/systems/simulation/driver/HingeDriver.ts b/fission/src/systems/simulation/driver/HingeDriver.ts index 5e5c680baf..136b1ee546 100644 --- a/fission/src/systems/simulation/driver/HingeDriver.ts +++ b/fission/src/systems/simulation/driver/HingeDriver.ts @@ -1,5 +1,5 @@ import Jolt from "@barclah/jolt-physics"; -import Driver from "./Driver"; +import Driver, { DriverControlMode } from "./Driver"; import { SIMULATION_PERIOD } from "@/systems/physics/PhysicsSystem"; import JOLT from "@/util/loading/JoltSyncLoader"; @@ -22,7 +22,7 @@ class HingeDriver extends Driver { return this._targetAngle; } public set targetAngle(rads: number) { - this._targetAngle = rads; + this._targetAngle = Math.max(this._constraint.GetLimitsMin(), Math.min(this._constraint.GetLimitsMax(), rads)); } public set minTorqueLimit(nm: number) { @@ -37,6 +37,7 @@ class HingeDriver extends Driver { public get controlMode(): DriverControlMode { return this._controlMode; } + public set controlMode(mode: DriverControlMode) { this._controlMode = mode; switch (mode) { @@ -79,13 +80,7 @@ class HingeDriver extends Driver { } else if (this._controlMode == DriverControlMode.Position) { this._constraint.SetTargetAngle(this._targetAngle); } - } } -export enum DriverControlMode { - Velocity = 0, - Position = 1 -} - export default HingeDriver; \ No newline at end of file diff --git a/fission/src/systems/simulation/driver/SliderDriver.ts b/fission/src/systems/simulation/driver/SliderDriver.ts index b6ace1ad60..f278d70edd 100644 --- a/fission/src/systems/simulation/driver/SliderDriver.ts +++ b/fission/src/systems/simulation/driver/SliderDriver.ts @@ -1,14 +1,23 @@ import Jolt from "@barclah/jolt-physics"; -import Driver from "./Driver"; +import Driver, { DriverControlMode } from "./Driver"; import { SIMULATION_PERIOD } from "@/systems/physics/PhysicsSystem"; import JOLT from "@/util/loading/JoltSyncLoader"; -import InputSystem from "@/systems/input/InputSystem"; class SliderDriver extends Driver { private _constraint: Jolt.SliderConstraint; + + private _controlMode: DriverControlMode = DriverControlMode.Velocity; + private _targetVelocity: number = 0.0; private _targetPosition: number = 0.0; + public get targetVelocity(): number { + return this._targetVelocity; + } + public set targetVelocity(radsPerSec: number) { + this._targetVelocity = radsPerSec; + } + public get targetPosition(): number { return this._targetPosition; } @@ -25,6 +34,25 @@ class SliderDriver extends Driver { motorSettings.mMaxForceLimit = newtons; } + public get controlMode(): DriverControlMode { + return this._controlMode; + } + + public set controlMode(mode: DriverControlMode) { + this._controlMode = mode; + switch (mode) { + case DriverControlMode.Velocity: + this._constraint.SetMotorState(JOLT.EMotorState_Velocity); + break; + case DriverControlMode.Position: + this._constraint.SetMotorState(JOLT.EMotorState_Position); + break; + default: + // idk + break; + } + } + public constructor(constraint: Jolt.SliderConstraint) { super(); @@ -36,17 +64,24 @@ class SliderDriver extends Driver { springSettings.mDamping = 0.995; motorSettings.mSpringSettings = springSettings; - motorSettings.mMinForceLimit = -125.0; - motorSettings.mMaxForceLimit = 125.0; + motorSettings.mMinForceLimit = -250.0; + motorSettings.mMaxForceLimit = 250.0; - this._constraint.SetMotorState(JOLT.EMotorState_Position); + //this._constraint.SetMotorState(JOLT.EMotorState_Position); this.targetPosition = this._constraint.GetCurrentPosition(); + this.controlMode = DriverControlMode.Velocity; } public Update(_: number): void { - this._targetPosition += ((InputSystem.getInput("sliderUp") ? 1 : 0) - (InputSystem.getInput("sliderDown") ? 1 : 0))*3; - this._constraint.SetTargetPosition(this._targetPosition); + // this._targetPosition += ((InputSystem.getInput("sliderUp") ? 1 : 0) - (InputSystem.getInput("sliderDown") ? 1 : 0))*3; + // this._constraint.SetTargetVelocity(this._targetPosition); + + if (this._controlMode == DriverControlMode.Velocity) { + this._constraint.SetTargetVelocity(this._targetVelocity); + } else if (this._controlMode == DriverControlMode.Position) { + this._constraint.SetTargetPosition(this._targetPosition); + } } } From 125b44ebadf6318ec59f06d096e70f0c9525cd71 Mon Sep 17 00:00:00 2001 From: a-crowell Date: Thu, 20 Jun 2024 15:37:49 -0700 Subject: [PATCH 07/14] Minor clean up --- fission/src/systems/input/InputSystem.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index d64bb19d85..33e2b41e43 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -69,7 +69,7 @@ class InputSystem extends WorldSystem { } } - public Update(_: number): void {InputSystem + public Update(_: number): void { InputSystem._currentModifierState = { ctrl: InputSystem.isKeyPressed("ControlLeft") || InputSystem.isKeyPressed("ControlRight"), alt: InputSystem.isKeyPressed("AltLeft") || InputSystem.isKeyPressed("AltRight"), shift: InputSystem.isKeyPressed("ShiftLeft") || InputSystem.isKeyPressed("ShiftRight"), meta: InputSystem.isKeyPressed("MetaLeft") || InputSystem.isKeyPressed("MetaRight") } } From 9e38a93b23b3be3facc058a468444081eacab65d Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Fri, 21 Jun 2024 13:20:21 -0700 Subject: [PATCH 08/14] Update accept button to show on selected file --- fission/src/modals/mirabuf/ImportLocalMirabufModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fission/src/modals/mirabuf/ImportLocalMirabufModal.tsx b/fission/src/modals/mirabuf/ImportLocalMirabufModal.tsx index 4b9fbbcd7b..a21edd024b 100644 --- a/fission/src/modals/mirabuf/ImportLocalMirabufModal.tsx +++ b/fission/src/modals/mirabuf/ImportLocalMirabufModal.tsx @@ -33,7 +33,7 @@ const ImportLocalMirabufModal: React.FC = ({ modalId }) => { name={"Import Local Assemblies"} icon={} modalId={modalId} - acceptEnabled={selectedFile == undefined} + acceptEnabled={selectedFile !== undefined} onAccept={() => { if (selectedFile) { console.log(`Mira: '${selectedFile}'`) From 6cf5e30d16c8bca1fa9e57099ba83d419a5ebb21 Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Mon, 24 Jun 2024 09:25:57 -0700 Subject: [PATCH 09/14] Initial removal of exploratory code --- exporter/SynthesisFusionAddin/Synthesis.py | 26 ---- .../src/Fission/HttpServer.py | 19 --- .../src/Parser/SynthesisParser/Parser.py | 4 - .../src/UI/ConfigCommand.py | 124 ++++++++---------- 4 files changed, 55 insertions(+), 118 deletions(-) delete mode 100644 exporter/SynthesisFusionAddin/src/Fission/HttpServer.py diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index 53badbbee1..d632c474cb 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -1,9 +1,3 @@ -from http.server import HTTPServer -from threading import Thread - -import adsk.fusion - -from .src.Fission.HttpServer import MyHTTPHandler from .src.general_imports import root_logger, gm, INTERNAL_ID, APP_NAME, DESCRIPTION from .src.UI import HUI, Handlers, Camera, Helper, ConfigCommand @@ -28,22 +22,6 @@ def run(_): # Remove all items prior to start just to make sure unregister_all() - # httpServer = HTTPServer(('', HTTP_PORT), MyHTTPHandler) - - # def serveFunc(): - # try: - # print('Http serve') - # httpServer.serve_forever() - # except: - # print('Error') - # logging.getLogger(f"{INTERNAL_ID}").error( - # "Failed:\n{}".format(traceback.format_exc()) - # ) - - # serveThread = Thread(target = serveFunc) - # serveThread.run() - # serveFunc() - # creates the UI elements register_ui() @@ -66,10 +44,6 @@ def stop(_): try: unregister_all() - if httpServer: - httpServer.server_close() - httpServer = None - app = adsk.core.Application.get() ui = app.userInterface diff --git a/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py b/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py deleted file mode 100644 index ef99966693..0000000000 --- a/exporter/SynthesisFusionAddin/src/Fission/HttpServer.py +++ /dev/null @@ -1,19 +0,0 @@ -from http.server import BaseHTTPRequestHandler -import logging - -from ..general_imports import INTERNAL_ID -# from socketserver import BaseRequestHandler - -class MyHTTPHandler(BaseHTTPRequestHandler): - - def __init__(self, a, b, c): - print('init') - print(f'{self.address_string}') - print(f'{self.command}') - - def do_GET(self): - print('get') - logging.getLogger(f'{INTERNAL_ID}').debug('Request') - self.send_response(200) - self.end_headers() - self.wfile.write(bytes('test')) diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py index 70993d36fe..095cd87992 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py @@ -31,10 +31,6 @@ def export(self) -> bool: app = adsk.core.Application.get() design: adsk.fusion.Design = app.activeDocument.design - folder = design.parentDocument.dataFile.parentFolder - print(f'===\nFolder\nName: {folder.name}\n===') - folder.uploadFile(f'{design.parentDocument.name}_mira') - assembly_out = assembly_pb2.Assembly() fill_info( assembly_out, diff --git a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py index f5bc38e6d4..20594340d5 100644 --- a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py @@ -5,8 +5,6 @@ from enum import Enum import platform -from .Util.EventHandlers import MakeCommandExecuteHandler - from ..Parser.SynthesisParser.Utilities import guid_occurrence from ..general_imports import * from ..configure import NOTIFIED, write_configuration @@ -957,13 +955,6 @@ def notify(self, args): previous.filePath, ) - def t(args: adsk.core.CommandEventArgs): - print('sup') - - a = MakeCommandExecuteHandler(t) - - # onExecute = CommandExecuteHandlerShort(lambda args: logging.getLogger(f'{INTERNAL_ID}').debug('Hello world from execute')) - cmd.execute.add(onExecute) gm.handlers.append(onExecute) # 0 @@ -999,11 +990,6 @@ def t(args: adsk.core.CommandEventArgs): cmd.destroy.add(onDestroy) gm.handlers.append(onDestroy) # 8 - app = adsk.core.Application.get() - document = app.activeDocument - if document.isModified: - print('Modified') - except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) @@ -1207,12 +1193,12 @@ def notify(self, args): # defaultPath = self.fp # defaultPath = os.getenv() - if mode == 5: - savepath = FileDialogConfig.SaveFileDialog( - defaultPath=self.fp, ext="Synthesis File (*.synth)" - ) - else: - savepath = FileDialogConfig.SaveFileDialog(defaultPath=self.fp) + # if mode == 5: + # savepath = FileDialogConfig.SaveFileDialog( + # defaultPath=self.fp, ext="Synthesis File (*.synth)" + # ) + # else: + # savepath = FileDialogConfig.SaveFileDialog(defaultPath=self.fp) processedFileName = gm.app.activeDocument.name.replace(" ", "_") dropdownExportMode = INPUTS_ROOT.itemById("mode") @@ -1221,55 +1207,55 @@ def notify(self, args): elif dropdownExportMode.selectedItem.index == 1: isRobot = False - # if platform.system() == "Windows": - # if isRobot: - # if export_as_part_boolean.value: - # savepath = ( - # os.getenv("APPDATA") - # + "\\Autodesk\\Synthesis\\MixAndMatch\\Mira\\" - # + processedFileName - # + ".mira" - # ) - # else: - # savepath = ( - # os.getenv("APPDATA") - # + "\\Autodesk\\Synthesis\\Mira\\" - # + processedFileName - # + ".mira" - # ) - # else: - # savepath = ( - # os.getenv("APPDATA") - # + "\\Autodesk\\Synthesis\\Mira\\Fields\\" - # + processedFileName - # + ".mira" - # ) - # else: - # from os.path import expanduser - - # home = expanduser("~") - # if isRobot: - # if export_as_part_boolean.value: - # savepath = ( - # home - # + "/.config/Autodesk/Synthesis/MixAndMatch/Mira/" - # + processedFileName - # + ".mira" - # ) - # else: - # savepath = ( - # home - # + "/.config/Autodesk/Synthesis/Mira/" - # + processedFileName - # + ".mira" - # ) - # else: - # savepath = ( - # home - # + "/.config/Autodesk/Synthesis/Mira/Fields/" - # + processedFileName - # + ".mira" - # ) + if platform.system() == "Windows": + if isRobot: + if export_as_part_boolean.value: + savepath = ( + os.getenv("APPDATA") + + "\\Autodesk\\Synthesis\\MixAndMatch\\Mira\\" + + processedFileName + + ".mira" + ) + else: + savepath = ( + os.getenv("APPDATA") + + "\\Autodesk\\Synthesis\\Mira\\" + + processedFileName + + ".mira" + ) + else: + savepath = ( + os.getenv("APPDATA") + + "\\Autodesk\\Synthesis\\Mira\\Fields\\" + + processedFileName + + ".mira" + ) + else: + from os.path import expanduser + + home = expanduser("~") + if isRobot: + if export_as_part_boolean.value: + savepath = ( + home + + "/.config/Autodesk/Synthesis/MixAndMatch/Mira/" + + processedFileName + + ".mira" + ) + else: + savepath = ( + home + + "/.config/Autodesk/Synthesis/Mira/" + + processedFileName + + ".mira" + ) + else: + savepath = ( + home + + "/.config/Autodesk/Synthesis/Mira/Fields/" + + processedFileName + + ".mira" + ) if savepath == False: # save was canceled From e20ee3239aa025a8a8143e44f14bae52a2261ceb Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Mon, 24 Jun 2024 09:30:48 -0700 Subject: [PATCH 10/14] Final removal of exploratory code (post branch save) --- exporter/SynthesisFusionAddin/Synthesis.py | 28 +- .../src/UI/Configuration/JointEditPanel.py | 30 -- .../src/UI/MarkingMenu.py | 432 ++++++++---------- .../src/UI/Util/EventHandlers.py | 66 --- 4 files changed, 193 insertions(+), 363 deletions(-) delete mode 100644 exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py delete mode 100644 exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index d632c474cb..1e396b8837 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -11,6 +11,7 @@ from .src.UI import MarkingMenu import adsk.core + def run(_): """## Entry point to application from Fusion 360. @@ -126,31 +127,4 @@ def register_ui() -> None: command=True, ) - app = adsk.core.Application.get() - ui = app.userInterface - - showPaletteCmdDef = ui.commandDefinitions.itemById('showAPSLogin') - if showPaletteCmdDef: - if not showPaletteCmdDef.deleteMe(): - print('fhsdja') - else: - print('fdshjs') - - showPaletteCmdDef = None - - if not showPaletteCmdDef: - showPaletteCmdDef = ui.commandDefinitions.addButtonDefinition('showAPSLogin', 'Show Custom Synthesis Palette', 'Show the custom palette', '') - - class CreateHandlerThing(adsk.core.CommandCreatedEventHandler): - def notify(self, args: adsk.core.CommandCreatedEventArgs): - print('Eyyooo') - - # Connect to Command Created event. - showPaletteCmdDef.commandCreated.add(CreateHandlerThing()) - - panel = ui.allToolbarPanels.itemById('SolidScriptsAddinsPanel') - cntrl = panel.controls.itemById('showAPSLogin') - if not cntrl: - panel.controls.addCommand(showPaletteCmdDef) - gm.elements.append(commandButton) diff --git a/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py b/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py deleted file mode 100644 index 109d80fc70..0000000000 --- a/exporter/SynthesisFusionAddin/src/UI/Configuration/JointEditPanel.py +++ /dev/null @@ -1,30 +0,0 @@ -from adsk.core import * -from adsk.fusion import * -from ..Util.EventHandlers import * - -COMM_JOINT_SPEED = 'JointSpeed' - -handlers = [] - -def remove(id: str, inputs: CommandInputs): - cmd = inputs.itemById(id) - if cmd: - cmd.deleteMe() - -def buildJointEditPanel(joint: Joint, args: CommandCreatedEventArgs): - inputs = args.command.commandInputs - - remove(COMM_JOINT_SPEED, inputs) - cmdJointSpeed = inputs.addValueInput( - COMM_JOINT_SPEED, - 'Joint Speed', - 'deg', - ValueInput.createByReal(3.1415926) - ) - - args.command.execute.add(MakeCommandExecuteHandler(updateJointInfo, handlers)) - - print('Built joint edit panel') - -def updateJointInfo(args: CommandEventArgs): - print(f'Executing') \ No newline at end of file diff --git a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py index e8e07440fd..0a1fbadcbf 100644 --- a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py +++ b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py @@ -1,5 +1,3 @@ -from .Util.EventHandlers import * -from .Configuration.JointEditPanel import * import adsk.core, adsk.fusion, traceback import logging.handlers @@ -12,24 +10,55 @@ entities = [] occurrencesOfComponents = {} -DROPDOWN_ID = "SynthesisMain" -DROPDOWN_COLLISION_ID = "synthesis" -DROPDOWN_CONFIG_ID = "SynthesisConfig" - -SEPARATOR = "LinearSeparator" - -COMM_SELECT_DISABLED = "SelectDisabled" -COMM_ENABLE_ALL = "EnableAllCollision" -COMM_DISABLE_COLLISION = "DisableCollision" -COMM_ENABLE_COLLISION = "EnableCollision" -COMM_DELETE = "DeleteComponent" - -COMM_EDIT_JOINT = "EditJoint" def setupMarkingMenu(ui: adsk.core.UserInterface): - print('Setting up mark up menu') handlers.clear() try: + + def setLinearMarkingMenu(args): + try: + menuArgs = adsk.core.MarkingMenuEventArgs.cast(args) + + linearMenu = menuArgs.linearMarkingMenu + linearMenu.controls.addSeparator("LinearSeparator") + + synthDropDown = linearMenu.controls.addDropDown( + "Synthesis", "", "synthesis" + ) + + cmdSelectDisabled = ui.commandDefinitions.itemById("SelectDisabled") + synthDropDown.controls.addCommand(cmdSelectDisabled) + + synthDropDown.controls.addSeparator() + + cmdEnableAll = ui.commandDefinitions.itemById("EnableAllCollision") + synthDropDown.controls.addCommand(cmdEnableAll) + synthDropDown.controls.addSeparator() + + if args.selectedEntities: + sel0 = args.selectedEntities[0] + occ = adsk.fusion.Occurrence.cast(sel0) + + if occ: + if ( + occ.attributes.itemByName("synthesis", "collision_off") + == None + ): + cmdDisableCollision = ui.commandDefinitions.itemById( + "DisableCollision" + ) + synthDropDown.controls.addCommand(cmdDisableCollision) + else: + cmdEnableCollision = ui.commandDefinitions.itemById( + "EnableCollision" + ) + synthDropDown.controls.addCommand(cmdEnableCollision) + except: + if ui: + ui.messageBox("setting linear menu failed: {}").format( + traceback.format_exc() + ) + def setCollisionAttribute(occ: adsk.fusion.Occurrence, isEnabled: bool = True): attr = occ.attributes.itemByName("synthesis", "collision_off") if attr == None and not isEnabled: @@ -50,236 +79,159 @@ def applyToSelfAndAllChildren(occ: adsk.fusion.Occurrence, modFunc): if o.childOccurrences.count > 0: childLists.append(o.childOccurrences) - def handleCommandExecute(args: adsk.core.CommandEventArgs): - try: - command = args.firingEvent.sender - cmdDef = CommandDefinition.cast(command.parentCommandDefinition) - if cmdDef: - if cmdDef.id == COMM_ENABLE_COLLISION: - # ui.messageBox('Enable') - if entities: - func = lambda occ: setCollisionAttribute(occ, True) - for e in entities: - occ = adsk.fusion.Occurrence.cast(e) - if occ: - applyToSelfAndAllChildren(occ, func) - elif cmdDef.id == COMM_DISABLE_COLLISION: - # ui.messageBox('Disable') - if entities: - func = lambda occ: setCollisionAttribute(occ, False) - for e in entities: - occ = adsk.fusion.Occurrence.cast(e) - if occ: - applyToSelfAndAllChildren(occ, func) - elif cmdDef.id == COMM_SELECT_DISABLED: - app = adsk.core.Application.get() - product = app.activeProduct - design = adsk.fusion.Design.cast(product) - ui.activeSelections.clear() - if design: - attrs = design.findAttributes( - "synthesis", "collision_off" - ) - for attr in attrs: - for b in adsk.fusion.Occurrence.cast( - attr.parent - ).bRepBodies: - ui.activeSelections.add(b) - elif cmdDef.id == COMM_ENABLE_ALL: - app = adsk.core.Application.get() - product = app.activeProduct - design = adsk.fusion.Design.cast(product) - if design: - for attr in design.findAttributes( - "synthesis", "collision_off" - ): - attr.deleteMe() - # elif cmdDef.id == COMM_EDIT_JOINT: - # if entities: - # joint = adsk.fusion.Joint.case(entities[0]) - # if joint: - # print('Joint edit') + class MyCommandCreatedEventHandler(adsk.core.CommandCreatedEventHandler): + def __init__(self): + super().__init__() + + def notify(self, args): + try: + command = args.command + onCommandExcute = MyCommandExecuteHandler() + handlers.append(onCommandExcute) + command.execute.add(onCommandExcute) + except: + ui.messageBox("command created failed: {}").format( + traceback.format_exc() + ) + + class MyCommandExecuteHandler(adsk.core.CommandEventHandler): + def __init__(self): + super().__init__() + + def notify(self, args): + try: + command = args.firingEvent.sender + cmdDef = command.parentCommandDefinition + if cmdDef: + if cmdDef.id == "EnableCollision": + # ui.messageBox('Enable') + if entities: + func = lambda occ: setCollisionAttribute(occ, True) + for e in entities: + occ = adsk.fusion.Occurrence.cast(e) + if occ: + applyToSelfAndAllChildren(occ, func) + elif cmdDef.id == "DisableCollision": + # ui.messageBox('Disable') + if entities: + func = lambda occ: setCollisionAttribute(occ, False) + for e in entities: + occ = adsk.fusion.Occurrence.cast(e) + if occ: + applyToSelfAndAllChildren(occ, func) + elif cmdDef.id == "SelectDisabled": + app = adsk.core.Application.get() + product = app.activeProduct + design = adsk.fusion.Design.cast(product) + ui.activeSelections.clear() + if design: + attrs = design.findAttributes( + "synthesis", "collision_off" + ) + for attr in attrs: + for b in adsk.fusion.Occurrence.cast( + attr.parent + ).bRepBodies: + ui.activeSelections.add(b) + elif cmdDef.id == "EnableAllCollision": + app = adsk.core.Application.get() + product = app.activeProduct + design = adsk.fusion.Design.cast(product) + if design: + for attr in design.findAttributes( + "synthesis", "collision_off" + ): + attr.deleteMe() + else: + ui.messageBox("command {} triggered.".format(cmdDef.id)) else: - ui.messageBox("command {} triggered.".format(cmdDef.id)) - else: - ui.messageBox("No CommandDefinition") - except: - print('Error') - ui.messageBox("command executed failed: {}").format( - traceback.format_exc() - ) - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + ui.messageBox("No CommandDefinition") + except: + ui.messageBox("command executed failed: {}").format( + traceback.format_exc() + ) + logging.getLogger(f"{INTERNAL_ID}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) + + class MyMarkingMenuHandler(adsk.core.MarkingMenuEventHandler): + def __init__(self): + super().__init__() + + def notify(self, args): + try: + setLinearMarkingMenu(args) + + global occurrencesOfComponents + + # selected entities + global entities + entities.clear() + entities = args.selectedEntities + except: + if ui: + ui.messageBox( + "Marking Menu Displaying event failed: {}".format( + traceback.format_exc() + ) + ) - def handleMarkingMenu(args: adsk.core.MarkingMenuEventArgs): - linearMenu = args.linearMarkingMenu - linearMenu.controls.addSeparator(SEPARATOR) + # Add customized handler for marking menu displaying + onMarkingMenuDisplaying = MyMarkingMenuHandler() + handlers.append(onMarkingMenuDisplaying) + ui.markingMenuDisplaying.add(onMarkingMenuDisplaying) - synthesisDropDown = linearMenu.controls.addDropDown( - "Synthesis", "", DROPDOWN_ID + # Add customized handler for commands creating + onCommandCreated = MyCommandCreatedEventHandler() + handlers.append(onCommandCreated) + + cmdDisableCollision = ui.commandDefinitions.itemById("DisableCollision") + if not cmdDisableCollision: + cmdDisableCollision = ui.commandDefinitions.addButtonDefinition( + "DisableCollision", + "Disable Collisions", + "Disable collisions with this occurrence inside Synthesis", ) - - ''' - COLLISION - ''' - synthesisCollisionDropDown = synthesisDropDown.controls.addDropDown( - "Collision", "", DROPDOWN_COLLISION_ID + cmdDisableCollision.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdDisableCollision) + cmdEnableCollision = ui.commandDefinitions.itemById("EnableCollision") + if not cmdEnableCollision: + cmdEnableCollision = ui.commandDefinitions.addButtonDefinition( + "EnableCollision", + "Enable Collisions", + "Enable collisions with this occurrence inside Synthesis", ) - - cmdSelectDisabled = ui.commandDefinitions.itemById(COMM_SELECT_DISABLED) - synthesisCollisionDropDown.controls.addCommand(cmdSelectDisabled) - - synthesisCollisionDropDown.controls.addSeparator() - - cmdEnableAll = ui.commandDefinitions.itemById(COMM_ENABLE_ALL) - synthesisCollisionDropDown.controls.addCommand(cmdEnableAll) - synthesisCollisionDropDown.controls.addSeparator() - - if args.selectedEntities: - sel0 = args.selectedEntities[0] - occ = adsk.fusion.Occurrence.cast(sel0) - - if occ: - if not occ.attributes.itemByName("synthesis", "collision_off"): - cmdDisableCollision = ui.commandDefinitions.itemById(COMM_DISABLE_COLLISION) - synthesisCollisionDropDown.controls.addCommand(cmdDisableCollision) - else: - cmdEnableCollision = ui.commandDefinitions.itemById(COMM_ENABLE_COLLISION) - synthesisCollisionDropDown.controls.addCommand(cmdEnableCollision) - - ''' - CONFIGURATION - ''' - synthesisConfigDropDown = synthesisDropDown.controls.itemById(DROPDOWN_CONFIG_ID) - if synthesisConfigDropDown: - synthesisConfigDropDown.deleteMe() - - synthesisConfigDropDown = synthesisDropDown.controls.addDropDown( - "Config", "", DROPDOWN_CONFIG_ID + cmdEnableCollision.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdEnableCollision) + cmdEnableAllCollision = ui.commandDefinitions.itemById("EnableAllCollision") + if not cmdEnableAllCollision: + cmdEnableAllCollision = ui.commandDefinitions.addButtonDefinition( + "EnableAllCollision", + "Enable All Collision", + "Enable collisions for all occurrences in design", ) - - configEmpty = True - - if args.selectedEntities and len(args.selectedEntities) == 1: - selectedJoint = adsk.fusion.Joint.cast(args.selectedEntities[0]) - - if selectedJoint: - cmdEditJoint = ui.commandDefinitions.itemById(COMM_EDIT_JOINT) - synthesisConfigDropDown.controls.addCommand(cmdEditJoint) - configEmpty = False - - if configEmpty: - synthesisConfigDropDown.deleteMe() - - ''' - Globals - ''' - global occurrencesOfComponents - - # selected entities - global entities - entities.clear() - entities = args.selectedEntities - - # Add customized handler for marking menu displaying - ui.markingMenuDisplaying.add(MakeMarkingMenuEventHandler(handleMarkingMenu, handlers)) - - # Add customized handler for commands creating - - def handleCommandCreated(args: adsk.core.CommandCreatedEventArgs): - args.command.execute.add(MakeCommandExecuteHandler(handleCommandExecute, handlers)) - - onCommandCreated = MakeCommandCreatedHandler(handleCommandCreated, handlers) - - # Disable Collision Button - cmdDisableCollision = ui.commandDefinitions.itemById(COMM_DISABLE_COLLISION) - if cmdDisableCollision: - cmdDisableCollision.deleteMe() - - cmdDisableCollision = ui.commandDefinitions.addButtonDefinition( - COMM_DISABLE_COLLISION, - "Disable Collisions", - "Disable collisions with this occurrence inside Synthesis", - ) - cmdDisableCollision.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdDisableCollision) - - # Enable Collision Button - cmdEnableCollision = ui.commandDefinitions.itemById(COMM_ENABLE_COLLISION) - if cmdEnableCollision: - cmdEnableCollision.deleteMe() - - cmdEnableCollision = ui.commandDefinitions.addButtonDefinition( - COMM_ENABLE_COLLISION, - "Enable Collisions", - "Enable collisions with this occurrence inside Synthesis", - ) - cmdEnableCollision.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdEnableCollision) - - # Enable All Collision Button - cmdEnableAllCollision = ui.commandDefinitions.itemById(COMM_ENABLE_ALL) - if cmdEnableAllCollision: - cmdEnableAllCollision.deleteMe() - - cmdEnableAllCollision = ui.commandDefinitions.addButtonDefinition( - COMM_ENABLE_ALL, - "Enable All Collision", - "Enable collisions for all occurrences in design", - ) - cmdEnableAllCollision.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdEnableAllCollision) - - # Select Disabled Button - cmdSelectDisabled = ui.commandDefinitions.itemById(COMM_SELECT_DISABLED) - if cmdSelectDisabled: - cmdSelectDisabled.deleteMe() - - cmdSelectDisabled = ui.commandDefinitions.addButtonDefinition( - COMM_SELECT_DISABLED, - "Selected Collision Disabled Occurrences", - "Select all occurrences labeled for collision disabled", - ) - cmdSelectDisabled.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdSelectDisabled) - - # Delete Component Button - cmdDeleteComponent = ui.commandDefinitions.itemById(COMM_DELETE) - if cmdDeleteComponent: - cmdDeleteComponent.deleteMe() - - cmdDeleteComponent = ui.commandDefinitions.addButtonDefinition( - COMM_DELETE, - "Delete All Occurrences", - "Delete all occurrences with the same component", - ) - cmdDeleteComponent.commandCreated.add(onCommandCreated) - cmdDefs.append(cmdDeleteComponent) - - ''' - CONFIG COMMANDS - ''' - def handleEditJoint(args: CommandCreatedEventArgs): - if entities: - joint = adsk.fusion.Joint.cast(entities[0]) - if joint: - buildJointEditPanel(joint, args) - - onJointEditCreated = MakeCommandCreatedHandler( - handleEditJoint, - handlers - ) - - cmdEditJoint = ui.commandDefinitions.itemById(COMM_EDIT_JOINT) - if cmdEditJoint: - cmdEditJoint.deleteMe() - - cmdEditJoint = ui.commandDefinitions.addButtonDefinition( - COMM_EDIT_JOINT, "Edit Joint", "Edit joint details for Synthesis" - ) - cmdEditJoint.commandCreated.add(onJointEditCreated) - cmdDefs.append(cmdEditJoint) + cmdEnableAllCollision.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdEnableAllCollision) + + cmdSelectDisabled = ui.commandDefinitions.itemById("SelectDisabled") + if not cmdSelectDisabled: + cmdSelectDisabled = ui.commandDefinitions.addButtonDefinition( + "SelectDisabled", + "Selected Collision Disabled Occurrences", + "Select all occurrences labeled for collision disabled", + ) + cmdSelectDisabled.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdSelectDisabled) + + cmdDeleteComponent = ui.commandDefinitions.itemById("DeleteComponent") + if not cmdDeleteComponent: + cmdDeleteComponent = ui.commandDefinitions.addButtonDefinition( + "DeleteComponent", + "Delete All Occurrences", + "Delete all occurrences with the same component", + ) + cmdDeleteComponent.commandCreated.add(onCommandCreated) + cmdDefs.append(cmdDeleteComponent) except: ui.messageBox("Failed:\n{}".format(traceback.format_exc())) diff --git a/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py b/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py deleted file mode 100644 index 9931b81fb4..0000000000 --- a/exporter/SynthesisFusionAddin/src/UI/Util/EventHandlers.py +++ /dev/null @@ -1,66 +0,0 @@ -from typing import List -from adsk.core import * -from adsk.core import MarkingMenuEventArgs - -from ...general_imports import INTERNAL_ID, gm -import logging, traceback - -def ErrorHandle(handler, eventArgs): - try: - handler(eventArgs) - except: - gm.ui.messageBox(f'command executed failed: {traceback.format_exc()}') - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) - -class _CommandCreatedHandlerShort(CommandCreatedEventHandler): - def __init__(self, handler): - super().__init__() - self.handler = handler - - def notify(self, eventArgs: CommandCreatedEventArgs) -> None: - ErrorHandle(self.handler, eventArgs) - -class _CommandExecuteHandlerShort(CommandEventHandler): - def __init__(self, handler): - super().__init__() - self.handler = handler - - def notify(self, eventArgs: CommandEventArgs) -> None: - ErrorHandle(self.handler, eventArgs) - -class _SelectionEventHandlerShort(SelectionEventHandler): - def __init__(self, handler): - super().__init__() - self.handler = handler - - def notify(self, eventArgs: SelectionEventArgs) -> None: - ErrorHandle(self.handler, eventArgs) - -class _MarkingMenuEventHandlerShort(MarkingMenuEventHandler): - def __init__(self, handler): - super().__init__() - self.handler = handler - - def notify(self, eventArgs: MarkingMenuEventArgs) -> None: - # print('AHHH') - ErrorHandle(self.handler, eventArgs) - -def MakeCommandCreatedHandler(notify, handlerCollection: List | None = None) -> _CommandCreatedHandlerShort: - handler = _CommandCreatedHandlerShort(notify) - if handlerCollection is not None: - handlerCollection.append(handler) - return handler - -def MakeCommandExecuteHandler(notify, handlerCollection: List | None = None) -> _CommandExecuteHandlerShort: - handler = _CommandExecuteHandlerShort(notify) - if handlerCollection is not None: - handlerCollection.append(handler) - return handler - -def MakeMarkingMenuEventHandler(notify, handlerCollection: List | None = None) -> _MarkingMenuEventHandlerShort: - handler = _MarkingMenuEventHandlerShort(notify) - if handlerCollection is not None: - handlerCollection.append(handler) - return handler \ No newline at end of file From 99e54fd6a5545e1c60b1fb937d1622eefa689e8c Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Mon, 24 Jun 2024 09:31:34 -0700 Subject: [PATCH 11/14] Formatting --- exporter/SynthesisFusionAddin/Synthesis.py | 1 + 1 file changed, 1 insertion(+) diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index 1e396b8837..4ed3a0fede 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -36,6 +36,7 @@ def run(_): "Failed:\n{}".format(traceback.format_exc()) ) + def stop(_): """## Fusion 360 exit point - deconstructs buttons and handlers From 4bfa5a48704576a729b924cb525e0842f8312f4c Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Mon, 24 Jun 2024 11:37:32 -0700 Subject: [PATCH 12/14] Moved into `branp/hunters-download-item` --- fission/src/aps/APSDataManagement.ts | 24 ------------------- .../ui/modals/mirabuf/ImportMirabufModal.tsx | 4 ++-- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/fission/src/aps/APSDataManagement.ts b/fission/src/aps/APSDataManagement.ts index df14f73d33..0c6c4a6cec 100644 --- a/fission/src/aps/APSDataManagement.ts +++ b/fission/src/aps/APSDataManagement.ts @@ -160,27 +160,3 @@ export async function getFolderData(project: Project, folder: Folder): Promise { - const auth = APS.auth - if (!auth) { - return undefined - } - - try { - return await fetch(`https://developer.api.autodesk.com/data/v1/projects/${project.id}/items/${item.id}`, { - method: 'GET', - headers: { - 'Authorization': `Bearer ${auth.access_token}` - } - }).then(x => x.json()).then(async x => { - console.debug(x) - const downloadLink = x.included[0].relationships.storage.meta.link.href - console.debug(`Download Link: ${downloadLink}`) - return await fetch(downloadLink, { method: 'GET', headers: { 'Authorization': `Bearer ${auth.access_token}` } }) - }).then(x => x.blob()).then(x => { window.open(URL.createObjectURL(x)) }) - } catch (e) { - console.error('Failed to download item') - return undefined - } -} diff --git a/fission/src/ui/modals/mirabuf/ImportMirabufModal.tsx b/fission/src/ui/modals/mirabuf/ImportMirabufModal.tsx index b5c596de88..4e63772253 100644 --- a/fission/src/ui/modals/mirabuf/ImportMirabufModal.tsx +++ b/fission/src/ui/modals/mirabuf/ImportMirabufModal.tsx @@ -3,7 +3,7 @@ import Modal, { ModalPropsImpl } from "@/components/Modal" import { FaPlus } from "react-icons/fa6" import Button from "@/components/Button" import Label, { LabelSize } from "@/components/Label" -import { Data, Folder, Hub, Item, Project, downloadItem, getFolderData, getHubs, getProjects } from "@/aps/APSDataManagement" +import { Data, Folder, Hub, Item, Project, getFolderData, getHubs, getProjects } from "@/aps/APSDataManagement" interface ItemCardProps { id: string @@ -143,7 +143,7 @@ const ImportMirabufModal: React.FC = ({ modalId }) => { id: x.id, buttonText: "import", onClick: () => { - downloadItem(selectedProject, x) + console.log(`Selecting ${x.displayName} (${x.id})`) }, }) : ItemCard({ From 156deb256b1120970e042227c6ca470504ec072a Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Wed, 26 Jun 2024 14:07:27 -0700 Subject: [PATCH 13/14] Greatly improved elevator stages moving each other --- fission/src/systems/input/InputSystem.ts | 3 +++ .../behavior/GenericElevatorBehavior.ts | 2 +- .../src/systems/simulation/driver/SliderDriver.ts | 15 +++++---------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index cd7f4610e6..3c28117609 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -123,6 +123,9 @@ class InputSystem extends WorldSystem { // Returns true if two modifier states are identical private static CompareModifiers(state1: ModifierState, state2: ModifierState) : boolean { + if (!state1 || !state2) + return false; + return state1.alt == state2.alt && state1.ctrl == state2.ctrl && state1.meta == state2.meta && state1.shift == state2.shift; } } diff --git a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts index e77b037eae..49125917f8 100644 --- a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts @@ -9,7 +9,7 @@ class GenericElevatorBehavior extends Behavior { private _positiveInput: string; private _negativeInput: string; - private _linearSpeed = 10; + private _linearSpeed = 2.5; constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, jointIndex: number) { super([sliderDriver], [sliderStimulus]); diff --git a/fission/src/systems/simulation/driver/SliderDriver.ts b/fission/src/systems/simulation/driver/SliderDriver.ts index 1d547159e2..2ad547a831 100644 --- a/fission/src/systems/simulation/driver/SliderDriver.ts +++ b/fission/src/systems/simulation/driver/SliderDriver.ts @@ -64,22 +64,17 @@ class SliderDriver extends Driver { const motorSettings = this._constraint.GetMotorSettings() const springSettings = motorSettings.mSpringSettings springSettings.mFrequency = 20 * (1.0 / SIMULATION_PERIOD) - springSettings.mDamping = 0.995 + springSettings.mDamping = 0.999 motorSettings.mSpringSettings = springSettings - motorSettings.mMinForceLimit = -250.0 - motorSettings.mMaxForceLimit = 250.0 + motorSettings.mMinForceLimit = -900.0 + motorSettings.mMaxForceLimit = 900.0 - this._constraint.SetMotorState(JOLT.EMotorState_Position) + this._constraint.SetMotorState(JOLT.EMotorState_Velocity) this.controlMode = DriverControlMode.Velocity; - this.targetPosition = this._constraint.GetCurrentPosition() } - public Update(_: number): void { - // this._targetPosition += ((InputSystem.getInput("sliderUp") ? 1 : 0) - (InputSystem.getInput("sliderDown") ? 1 : 0))*3; - // this._constraint.SetTargetVelocity(this._targetPosition); - - if (this._controlMode == DriverControlMode.Velocity) { + public Update(_: number): void {if (this._controlMode == DriverControlMode.Velocity) { this._constraint.SetTargetVelocity(this._targetVelocity); } else if (this._controlMode == DriverControlMode.Position) { this._constraint.SetTargetPosition(this._targetPosition); From dabe89faade6024dae01fa09584a1b11dea8146b Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Wed, 26 Jun 2024 14:15:16 -0700 Subject: [PATCH 14/14] Improved arm movement and reduced 'bouncing' against it's limits --- fission/src/systems/simulation/behavior/GenericArmBehavior.ts | 2 +- fission/src/systems/simulation/driver/HingeDriver.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts index 6e5a0b7c0c..79a9c6079c 100644 --- a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts @@ -9,7 +9,7 @@ class GenericArmBehavior extends Behavior { private _positiveInput: string; private _negativeInput: string; - private _rotationalSpeed = 30; + private _rotationalSpeed = 6; constructor(hingeDriver: HingeDriver, hingeStimulus: HingeStimulus, jointIndex: number) { super([hingeDriver], [hingeStimulus]); diff --git a/fission/src/systems/simulation/driver/HingeDriver.ts b/fission/src/systems/simulation/driver/HingeDriver.ts index 11f5e703e1..4500508490 100644 --- a/fission/src/systems/simulation/driver/HingeDriver.ts +++ b/fission/src/systems/simulation/driver/HingeDriver.ts @@ -65,8 +65,8 @@ class HingeDriver extends Driver { springSettings.mDamping = 0.995 motorSettings.mSpringSettings = springSettings - motorSettings.mMinTorqueLimit = -50.0 - motorSettings.mMaxTorqueLimit = 50.0 + motorSettings.mMinTorqueLimit = -200.0 + motorSettings.mMaxTorqueLimit = 200.0 this._targetAngle = this._constraint.GetCurrentAngle()