diff --git a/python/InvenTreeLink/InvenTreeLink.py b/python/InvenTreeLink/InvenTreeLink.py
index 7a1ce0d..5f4c5a7 100644
--- a/python/InvenTreeLink/InvenTreeLink.py
+++ b/python/InvenTreeLink/InvenTreeLink.py
@@ -3,6 +3,8 @@
import os
+import threading
+
try:
from .apper import apper
from . import config
@@ -12,41 +14,13 @@
my_addin = apper.FusionApp(config.app_name, config.company_name, False)
my_addin.root_path = config.app_path
- from .commands.ShowPartCommand import ShowPartCommand
+ from .commands.EditPartCommand import EditPartCommand
from .commands.BOMOverviewCommand import BomOverviewPaletteShowCommand
- from .commands.SendBomCommand import SendBomCommand
- from .commands.SendBomOnlineCommand import SendBomOnlineCommand
- from .commands.SendStepCommand import SendStepCommand
-
+ from .commands.GenerateBomCommand import GenerateBomCommand
+ from .commands.ImportStlCommand import ImportStlCommand
+ from .commands.ImportPartCommand import ImportPartCommand
+
# Commands
- my_addin.add_command(
- 'Show part details',
- ShowPartCommand,
- {
- 'cmd_description': 'Show the InvenTree part-details for the selected part',
- 'cmd_id': config.DEF_SEND_PART,
- 'workspace': 'FusionSolidEnvironment',
- 'toolbar_panel_id': 'Commands',
- 'cmd_resources': config.DEF_SEND_PART,
- 'command_visible': True,
- 'command_promoted': False,
- }
- )
-
- my_addin.add_command(
- 'Upload STEP to attachments',
- SendStepCommand,
- {
- 'cmd_description': 'Generates a STEP file and attaches it to a part',
- 'cmd_id': config.DEF_SEND_STEP,
- 'workspace': 'FusionSolidEnvironment',
- 'toolbar_panel_id': 'Commands',
- 'cmd_resources': config.DEF_SEND_BOM,
- 'command_visible': True,
- 'command_promoted': False,
- 'palette_id': config.ITEM_PALETTE,
- }
- )
# Palette
my_addin.add_command(
@@ -56,7 +30,7 @@
'cmd_description': 'Show the BOM overview palette',
'cmd_id': config.DEF_SHOW_PALETTE,
'workspace': 'FusionSolidEnvironment',
- 'toolbar_panel_id': config.APP_PANEL,
+ 'toolbar_panel_id': config.ToolbarPanelID.INVENTREE_LINK,
'cmd_resources': 'ShowPalette',
'command_visible': True,
'command_promoted': True,
@@ -75,12 +49,12 @@
# Commands that need the palette
my_addin.add_command(
'Load BOM for assembly',
- SendBomCommand,
+ GenerateBomCommand,
{
'cmd_description': 'Load the BOM for the assembly in the current file',
'cmd_id': config.DEF_SEND_BOM,
'workspace': 'FusionSolidEnvironment',
- 'toolbar_panel_id': config.APP_PANEL,
+ 'toolbar_panel_id': config.ToolbarPanelID.INVENTREE_LINK,
'cmd_resources': config.DEF_SEND_BOM,
'command_visible': True,
'command_promoted': False,
@@ -89,14 +63,43 @@
)
my_addin.add_command(
- 'Get InvenTree Information',
- SendBomOnlineCommand,
+ 'Edit Part',
+ EditPartCommand,
{
- 'cmd_description': 'Fetch the InvenTree information for all BOM-parts',
- 'cmd_id': config.DEF_SEND_ONLINE_STATE,
+ 'cmd_description': 'Show the InvenTree part-details for the selected part',
+ 'cmd_id': config.DEF_SEND_PART,
'workspace': 'FusionSolidEnvironment',
- 'toolbar_panel_id': config.APP_PANEL,
- 'cmd_resources': config.DEF_SEND_ONLINE_STATE,
+ 'toolbar_panel_id': config.ToolbarPanelID.PART,
+ 'cmd_resources': config.DEF_SEND_PART,
+ 'command_visible': True,
+ 'command_promoted': False,
+ }
+ )
+
+ my_addin.add_command(
+ 'Import Part',
+ ImportPartCommand,
+ {
+ 'cmd_description': 'Import a Part as STL',
+ 'cmd_id': config.DEF_IMPORT_PART,
+ 'workspace': 'FusionSolidEnvironment',
+ 'toolbar_panel_id': config.ToolbarPanelID.PART,
+ 'cmd_resources': config.DEF_SEND_BOM,
+ 'command_visible': True,
+ 'command_promoted': False,
+ 'palette_id': config.ITEM_PALETTE,
+ }
+ )
+
+ my_addin.add_command(
+ 'Export STEP',
+ ImportStlCommand,
+ {
+ 'cmd_description': 'Generates a STEP file and attaches it to a part',
+ 'cmd_id': config.DEF_SEND_STEP,
+ 'workspace': 'FusionSolidEnvironment',
+ 'toolbar_panel_id': config.ToolbarPanelID.PART,
+ 'cmd_resources': 'ShowPalette',
'command_visible': True,
'command_promoted': False,
'palette_id': config.ITEM_PALETTE,
@@ -113,6 +116,61 @@
functions.init_Fusion360()
+ # class MyDocumentActivatedHandler(adsk.core.DocumentEventHandler):
+ # def __init__(self):
+ # super().__init__()
+ # def notify(self, args):
+ # eventArgs = adsk.core.DocumentEventArgs.cast(args)
+
+ # # Code to react to the event.
+ # ui.messageBox('In MyDocumentActivatedHandler event handler.\ndocument: {}'.format(eventArgs.document.name))
+
+ # class MyDocumentSavedHandler(adsk.core.DocumentEventHandler):
+ # def __init__(self):
+ # super().__init__()
+
+ # def notify(self, args):
+ # eventArgs = adsk.core.DocumentEventArgs.cast(args)
+
+ # # Code to react to the event.
+ # ui.messageBox('In MyDocumentSavedHandler event handler.')
+
+ # onDocumentSaved = MyDocumentSavedHandler()
+ # app.documentSaved.add(onDocumentSaved)
+
+ # onDocumentActivated = MyDocumentActivatedHandler()
+ # app.documentActivated.add(onDocumentActivated)
+
+ # def correct_inventree_names_thread():
+ # # Recursively correct the names to inventree names
+ # def correct_inventree_names(component):
+ # part = functions.inventree_get_part(component.id)
+
+ # if part:
+ # if component.name.lower() != part.name.lower():
+ # print(f"Correcting name of '{component.name}' to '{part.name}'")
+ # component.name = part.name
+
+ # if component.partNumber.lower() != part.IPN.lower():
+ # print(f"Correcting IPN of '{component.partNumber}' to '{part.IPN}'")
+ # component.partNumber = part.IPN
+
+ # for occurrence in component.occurrences:
+ # if occurrence.component:
+ # correct_inventree_names(occurrence.component)
+
+ # ao = apper.AppObjects()
+ # root = ao.product.rootComponent
+
+ # for occurrence in root.occurrences:
+ # if occurrence.component:
+ # correct_inventree_names(occurrence.component)
+
+ # t = threading.Thread(target=correct_inventree_names_thread)
+ # t.start()
+
+ print("InvenTreeLink started.")
+
except: # noqa: E722
app = adsk.core.Application.get()
ui = app.userInterface
diff --git a/python/InvenTreeLink/commands/BOMOverviewCommand.py b/python/InvenTreeLink/commands/BOMOverviewCommand.py
index e7b3947..54bb57e 100644
--- a/python/InvenTreeLink/commands/BOMOverviewCommand.py
+++ b/python/InvenTreeLink/commands/BOMOverviewCommand.py
@@ -7,7 +7,13 @@
from ..apper import apper
from .. import config
from .. import helpers
+from .. import functions
+
+from ..functions import inv_api, inventree_get_part
+import threading
+import typing
+import sys
# Class for a Fusion 360 Palette Command
class BomOverviewPaletteShowCommand(apper.PaletteCommandBase):
@@ -22,6 +28,9 @@ def on_palette_execute(self, palette: adsk.core.Palette):
# Run when ever a fusion event is fired from the corresponding web page
def on_html_event(self, html_args: adsk.core.HTMLEventArgs):
data = json.loads(html_args.data)
+
+ from inventree.part import Part
+ from inventree.part import BomItem
try:
ao = apper.AppObjects()
@@ -46,6 +55,14 @@ def on_html_event(self, html_args: adsk.core.HTMLEventArgs):
selections.add(entitiesByToken) # TODO selection not working
helpers.get_cmd(ao, config.DEF_SEND_PART).execute()
+ elif html_args.action == 'SyncAll':
+ root = ao.product.rootComponent
+
+ # sync_all_thread(ao, root)
+
+ t = threading.Thread(target=sync_all_thread, args=(ao, root))
+ t.start()
+
# TODO investigate ghost answers
# else:
# raise NotImplementedError('unknown message received from HTML')
@@ -56,3 +73,228 @@ def on_html_event(self, html_args: adsk.core.HTMLEventArgs):
# Handle any extra cleanup when user closes palette here
def on_palette_close(self):
pass
+
+def propose_create_f360_part(ao, component: adsk.fusion.Component, buttons):
+ physicalProperties = component.physicalProperties
+
+ fusion_360_data = (
+ f"Part Number: {component.partNumber}
"
+ f"Name: {component.name}
"
+ f"Description: {component.description}
"
+
+ f"ID: {component.id}
"
+ f"Area: {physicalProperties.area}cm2
"
+ f"Volume: {physicalProperties.volume}cm3
"
+ f"Mass: {physicalProperties.mass}kg
"
+ f"Density: {physicalProperties.density}g/cm3
"
+ )
+
+ if component.material and component.material.name:
+ fusion_360_data += f"Material: {component.material.name}
"
+
+ axis = ['x', 'y', 'z']
+ bb_min = {a: getattr(component.boundingBox.minPoint, a) for a in axis}
+ bb_max = {a: getattr(component.boundingBox.maxPoint, a) for a in axis}
+ bb = {a: bb_max[a] - bb_min[a] for a in axis}
+
+ fusion_360_data += (
+ f"Dimensions: {bb['x']}cm x {bb['y']}cm x {bb['z']}cm
"
+ )
+
+ text = (
+ f"Part {component.partNumber} | {component.name} is not recognized by Inventree.
"
+ "Do you want to create a Part with the values provided by Fusion360?
"
+ f"{fusion_360_data}"
+ )
+
+ return ao.ui.messageBox(text, "Sync All", buttons, 1)
+
+
+@apper.lib_import(config.lib_path)
+def sync_all_thread(ao, root: adsk.fusion.Component):
+ print("Starting sync_all thread.")
+
+ palette = ao.ui.palettes.itemById(config.ITEM_PALETTE)
+
+ log_html = []
+ def log(message: str, color: str = "black"):
+ log_html.append(f'{message}')
+
+ palette.sendInfoToHTML(
+ config.DEF_SYNC_LOG,
+ '
'.join(log_html)
+ )
+
+ palette.sendInfoToHTML(
+ config.DEF_SEND_BOM,
+ (
+ '
Syncing ...
' + 'Retrieving BOM...
' + '| Name | " + "Count | " + "Synced | " + "
|---|
{len(bom)} parts found in {datetime.now() - start}
" + f"{table_html}" + "" + ) + + palette.sendInfoToHTML( + config.DEF_SEND_BOM, + json.dumps(complete_html) + ) + + #create_bom_thread() + t = threading.Thread(target=create_bom_thread, args=()) + t.start() + except Exception as _e: + config.app_tracking.capture_exception(_e) + raise _e diff --git a/python/InvenTreeLink/commands/ImportPartCommand.py b/python/InvenTreeLink/commands/ImportPartCommand.py new file mode 100644 index 0000000..da6bcca --- /dev/null +++ b/python/InvenTreeLink/commands/ImportPartCommand.py @@ -0,0 +1,23 @@ +import adsk.core +import adsk.fusion +import adsk.cam + +import os +from datetime import datetime + +from ..apper import apper +from .. import functions +from .. import helpers +from .. import config + + +class ImportPartCommand(apper.Fusion360CommandBase): + + @apper.lib_import(config.lib_path) + def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): + try: + ao = apper.AppObjects() + + except Exception as _e: + config.app_tracking.capture_exception(_e) + raise _e diff --git a/python/InvenTreeLink/commands/SendStepCommand.py b/python/InvenTreeLink/commands/ImportStlCommand.py similarity index 92% rename from python/InvenTreeLink/commands/SendStepCommand.py rename to python/InvenTreeLink/commands/ImportStlCommand.py index ebe1067..58e6f28 100644 --- a/python/InvenTreeLink/commands/SendStepCommand.py +++ b/python/InvenTreeLink/commands/ImportStlCommand.py @@ -11,7 +11,7 @@ from .. import config -class SendStepCommand(apper.Fusion360CommandBase): +class ImportStlCommand(apper.Fusion360CommandBase): @apper.lib_import(config.lib_path) def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): @@ -20,8 +20,6 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma try: ao = apper.AppObjects() - ao.ui.messageBox("STEP FILE") - if ao.ui.activeSelections.count == 1: occ = adsk.fusion.Occurrence.cast(ao.ui.activeSelections[0].entity) @@ -35,8 +33,6 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma self._write_step(temp_path, occ.component) - ao.ui.messageBox("File at {}, size: {}".format(temp_path, os.path.getsize(temp_path))) - part = functions.inventree_get_part(occ.component.id) if part is False: diff --git a/python/InvenTreeLink/commands/SendBomCommand.py b/python/InvenTreeLink/commands/SendBomCommand.py deleted file mode 100644 index 359d277..0000000 --- a/python/InvenTreeLink/commands/SendBomCommand.py +++ /dev/null @@ -1,47 +0,0 @@ -import adsk.core -import adsk.fusion -import adsk.cam - -import json -from datetime import datetime - -from ..apper import apper -from .. import config -from .. import functions - - -class SendBomCommand(apper.Fusion360CommandBase): - def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): - try: - # Get Reference to Palette - ao = apper.AppObjects() - palette = ao.ui.palettes.itemById(config.ITEM_PALETTE) - - # Send message to the HTML Page - if palette: - palette.sendInfoToHTML( - config.DEF_SEND_BOM, - '| Name | Count |
|---|
{nbr} parts found in {time}
{table}'.format( - nbr=len(config.BOM), - table=table_c, - time=datetime.now() - start - ) - ) - palette.sendInfoToHTML( - 'SendTree', - json.dumps(config.BOM_HIR) - ) - except Exception as _e: - config.app_tracking.capture_exception(_e) - raise _e diff --git a/python/InvenTreeLink/commands/SendBomOnlineCommand.py b/python/InvenTreeLink/commands/SendBomOnlineCommand.py deleted file mode 100644 index 45de1bb..0000000 --- a/python/InvenTreeLink/commands/SendBomOnlineCommand.py +++ /dev/null @@ -1,40 +0,0 @@ -import adsk.core -import adsk.fusion -import adsk.cam - -from ..apper import apper -from .. import config -from .. import functions - - -class SendBomOnlineCommand(apper.Fusion360CommandBase): - def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): - try: - # Get Reference to Palette - ao = apper.AppObjects() - palette = ao.ui.palettes.itemById(config.ITEM_PALETTE) - - # Send message to the HTML Page - if palette: - palette.sendInfoToHTML( - config.DEF_SEND_BOM, - '| Name | Count | Is InvenTree |
|---|
Check the github for more information
-Check the github for more + information