Hi Jorge,
I experimented on basis of the ui sampleskript. The dropdown Items (list of airfoilcoordinates) are addet from sql database (path in line 8) in lines 134-135. Adding and deleting are managed by clickbuttons. The commands for input change are in lines 47ff. I didn't find out, how to update the dropdownItem list in CommandCreatedHandler from the CommandInputChangeHandler.
Best regards Jörg
import adsk.core, adsk.fusion, traceback
import sqlite3
_app = None
_ui = None
_rowNumber = 0
DATABASE = 'C:/Users/<username>/airfoil_data.db'
# Global set of event handlers to keep them referenced for the duration of the command
_handlers = []
# Adds a new row to the table.
def addRowToTable(tableInput):
global _rowNumber
# Get the CommandInputs object associated with the parent command.
cmdInputs = adsk.core.CommandInputs.cast(tableInput.commandInputs)
# Create three new command inputs.
valueInput = cmdInputs.addValueInput('TableInput_value{}'.format(_rowNumber), 'Value', 'cm', adsk.core.ValueInput.createByReal(_rowNumber))
stringInput = cmdInputs.addStringValueInput('TableInput_string{}'.format(_rowNumber), 'String', str(_rowNumber))
spinnerInput = cmdInputs.addIntegerSpinnerCommandInput('spinnerInt{}'.format(_rowNumber), 'Integer Spinner', 0 , 100 , 2, int(_rowNumber))
# Add the inputs to the table.
row = tableInput.rowCount
tableInput.addCommandInput(valueInput, row, 0)
tableInput.addCommandInput(stringInput, row, 1)
tableInput.addCommandInput(spinnerInput, row, 2)
# Increment a counter used to make each row unique.
_rowNumber = _rowNumber + 1
# Event handler that reacts to any changes the user makes to any of the command inputs.
class MyCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
global foil_id
try:
eventArgs = adsk.core.InputChangedEventArgs.cast(args)
inputs = eventArgs.inputs
cmdInput = eventArgs.input
# onInputChange for click Button
if cmdInput.id == 'import':
db = databaseF(DATABASE)
db.create_database()
dlg = _ui.createFileDialog()
dlg.title = 'Open bez.dat File'
dlg.filter = 'Airfoil bez.dat files (*.dat);;All Files (*.*)'
if dlg.showOpen() != adsk.core.DialogResults.DialogOK:
return
filename = dlg.filename
test2 = db.import_airfoil_data(filename)
db.add_airfoil(str(test2[0]), str(test2[1]), str(test2[2]))
temp = cmdInput.id == 'Airfoils'
airfoil_list = db.show_airfoils()
if cmdInput.id == 'Airfoils':
objectItems = cmdInput.selectedItem
selection_name = objectItems.name
split = selection_name.split(".")
foil_id = str(split[0])
if cmdInput.id == 'delete':
db = databaseF(DATABASE)
db.create_database()
db.delete_airfoil(foil_id)
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler that reacts to when the command is destroyed. This terminates the script.
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
# When the command is done, terminate the script
# This will release all globals which will remove all event handlers
adsk.terminate()
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler that reacts when the command definitio is executed which
# results in the command being created and this event being fired.
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
# Get the command that was created.
cmd = adsk.core.Command.cast(args.command)
# Connect to the command destroyed event.
onDestroy = MyCommandDestroyHandler()
cmd.destroy.add(onDestroy)
_handlers.append(onDestroy)
# Connect to the input changed event.
onInputChanged = MyCommandInputChangedHandler()
cmd.inputChanged.add(onInputChanged)
_handlers.append(onInputChanged)
# Get the CommandInputs collection associated with the command.
inputs = cmd.commandInputs
# Create a tab input.
tabCmdInput1 = inputs.addTabCommandInput('tab_1', 'Tab 1')
tab1ChildInputs = tabCmdInput1.children
# Create bool value input with button style that can be clicked.
tab1ChildInputs.addBoolValueInput('import', 'import', False, "", True)
tab1ChildInputs.addBoolValueInput('delete', 'delete', False, "", True)
# Create dropdown input with test list style.
dropdownInput = tab1ChildInputs.addDropDownCommandInput('Airfoils', 'Airfoils', adsk.core.DropDownStyles.TextListDropDownStyle);
DROPDOWN_ITEMS = dropdownInput.listItems
db = databaseF(DATABASE)
db.create_database()
airfoil_list = db.show_airfoils()
for i in range(len(airfoil_list)):
DROPDOWN_ITEMS.add(str(airfoil_list[i][0]) + " ." + str(airfoil_list[i][1]), True, '')
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def run(context):
try:
global _app, _ui
_app = adsk.core.Application.get()
_ui = _app.userInterface
cmdDef = _ui.commandDefinitions.itemById('cmdInputsSample')
if not cmdDef:
cmdDef = _ui.commandDefinitions.addButtonDefinition('cmdInputsSample', 'Command Inputs Sample', 'Sample to demonstrate various command inputs.')
onCommandCreated = MyCommandCreatedHandler()
cmdDef.commandCreated.add(onCommandCreated)
_handlers.append(onCommandCreated)
db = databaseF(DATABASE)
db.create_database()
cmdDef.execute()
adsk.autoTerminate(False)
except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class databaseF():
def __init__(self, db):
self.db = db
def create_database(self):
conn = sqlite3.connect(self.db)
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS airfoils (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
coordinates_top TEXT NOT NULL,
coordinates_bottom TEXT NOT NULL
)
''')
conn.commit()
conn.close()
# airfoil in die Datenbank hinzufügen (name -> str, coords -> array as a str "[(0,0),...]"
def add_airfoil(self, name, coordinates_top, coordinates_bottom):
conn = sqlite3.connect(self.db)
c = conn.cursor()
c.execute("INSERT INTO airfoils (name, coordinates_top, coordinates_bottom) VALUES (?, ?, ?)",
(name, coordinates_top, coordinates_bottom))
conn.commit()
conn.close()
# airfoil aus der Datenbank löschen
def delete_airfoil(self, airfoil_id):
conn = sqlite3.connect(self.db)
c = conn.cursor()
c.execute("DELETE FROM airfoils WHERE id = ?", (airfoil_id,))
conn.commit()
conn.close()
# airfoil infos abrufen (index -> int, name -> str, top -> tupel, bottom -> tupel)
def show_airfoils(self):
conn = sqlite3.connect(self.db)
c = conn.cursor()
c.execute("SELECT * FROM airfoils")
rows = c.fetchall()
conn.close()
return rows
# Funktion, um Daten aus einer Datei im bez Format zu importieren
def import_airfoil_data(self, filepath):
with open(filepath, 'r') as file:
lines = file.readlines()
name = lines[0].strip() # Der erste Eintrag ist der Name des airfoilen
coordinates = []
for line in lines[1:]:
if line.strip(): # Ignoriere leere Zeilen
try:
x, y = map(float, line.split()) # Zwei Werte pro Zeile erwarten
coordinates.append((x, y)) # (x, y) Tupel zu Liste hinzufügen
except ValueError:
print("Fehler", "Ungültiges Koordinatenformat in der Datei.")
return None, None
coordinates_top = [coordinates[i] for i in range(0, 10)]
coordinates_bottom = list(reversed([coordinates[i] for i in range(9, 19)]))
return name, coordinates_top, coordinates_bottom
The Importfiles look like this:
NACA 0008.bez
1.0000000000000000 0.0000000000000000
0.7777777777777778 0.0279374422757889
0.5833333333333334 0.0133249808131489
0.4166666666666666 0.0771256925102178
0.2777777777777778 0.0103172561882940
0.1666666666666667 0.0655471695666222
0.0833333333333333 0.0257378087502697
0.0277777777777778 0.0317317906938658
0.0000000000000000 0.0067688756070382
0.0000000000000000 0.0000000000000000
0.0000000000000000 -0.0067688756070382
0.0277777777777778 -0.0317317906938658
0.0833333333333333 -0.0257378087502697
0.1666666666666667 -0.0655471695666222
0.2777777777777778 -0.0103172561882940
0.4166666666666666 -0.0771256925102178
0.5833333333333334 -0.0103172561882940
0.7777777777777778 -0.0279374422757889
1.0000000000000000 0.0000000000000000