Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utilize Fusion's Unit Manager [AARD-1773] #1101

Merged
merged 6 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
Joint,
ModelHierarchy,
PhysicalDepth,
PreferredUnits,
Wheel,
encodeNestedObjects,
makeObjectFromJson,
Expand All @@ -43,10 +42,7 @@ class ExporterOptions:
wheels: list[Wheel] = field(default_factory=list)
joints: list[Joint] = field(default_factory=list)
gamepieces: list[Gamepiece] = field(default_factory=list)
preferredUnits: PreferredUnits = field(default=PreferredUnits.IMPERIAL)

# Always stored in kg regardless of 'preferredUnits'
robotWeight: KG = field(default=0.0)
robotWeight: KG = field(default=KG(0.0))
autoCalcRobotWeight: bool = field(default=False)
autoCalcGamepieceWeight: bool = field(default=False)

Expand Down
Binary file not shown.
Binary file not shown.
24 changes: 12 additions & 12 deletions exporter/SynthesisFusionAddin/src/Types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@
from enum import Enum, EnumType
from typing import Any, TypeAlias, get_args, get_origin

import adsk.fusion

# Not 100% sure what this is for - Brandon
JointParentType = Enum("JointParentType", ["ROOT", "END"])

WheelType = Enum("WheelType", ["STANDARD", "OMNI", "MECANUM"])
SignalType = Enum("SignalType", ["PWM", "CAN", "PASSIVE"])
ExportMode = Enum("ExportMode", ["ROBOT", "FIELD"]) # Dynamic / Static export
PreferredUnits = Enum("PreferredUnits", ["METRIC", "IMPERIAL"])
ExportLocation = Enum("ExportLocation", ["UPLOAD", "DOWNLOAD"])
UnitSystem = Enum("UnitSystem", ["METRIC", "IMPERIAL"])

FUSION_UNIT_SYSTEM: dict[int, UnitSystem] = {
adsk.fusion.DistanceUnits.MillimeterDistanceUnits: UnitSystem.METRIC,
adsk.fusion.DistanceUnits.CentimeterDistanceUnits: UnitSystem.METRIC,
adsk.fusion.DistanceUnits.MeterDistanceUnits: UnitSystem.METRIC,
adsk.fusion.DistanceUnits.InchDistanceUnits: UnitSystem.IMPERIAL,
adsk.fusion.DistanceUnits.FootDistanceUnits: UnitSystem.IMPERIAL,
}


@dataclass
Expand Down Expand Up @@ -72,18 +82,8 @@ class ModelHierarchy(Enum):
SingleMesh = 3


LBS: TypeAlias = float
KG: TypeAlias = float


def toLbs(kgs: KG) -> LBS:
return LBS(round(kgs * 2.2062, 2))


def toKg(pounds: LBS) -> KG:
return KG(round(pounds / 2.2062, 2))


LBS: TypeAlias = float
PRIMITIVES = (bool, str, int, float, type(None))


Expand Down
7 changes: 0 additions & 7 deletions exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,6 @@ def notify(self, args: adsk.core.CommandEventArgs) -> None:
selectedJoints, selectedWheels = jointConfigTab.getSelectedJointsAndWheels()
selectedGamepieces = gamepieceConfigTab.getGamepieces()

if generalConfigTab.exportMode == ExportMode.ROBOT:
units = generalConfigTab.selectedUnits
else:
assert generalConfigTab.exportMode == ExportMode.FIELD
units = gamepieceConfigTab.selectedUnits

exporterOptions = ExporterOptions(
str(savepath),
name,
Expand All @@ -338,7 +332,6 @@ def notify(self, args: adsk.core.CommandEventArgs) -> None:
joints=selectedJoints,
wheels=selectedWheels,
gamepieces=selectedGamepieces,
preferredUnits=units,
robotWeight=generalConfigTab.robotWeight,
autoCalcRobotWeight=generalConfigTab.autoCalculateWeight,
autoCalcGamepieceWeight=gamepieceConfigTab.autoCalculateWeight,
Expand Down
78 changes: 15 additions & 63 deletions exporter/SynthesisFusionAddin/src/UI/GamepieceConfigTab.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

from src.Logging import logFailure
from src.Parser.ExporterOptions import ExporterOptions
from src.Types import Gamepiece, PreferredUnits, toKg, toLbs
from src.UI import IconPaths
from src.Types import Gamepiece, UnitSystem
from src.UI.CreateCommandInputsHelper import (
createBooleanInput,
createTableInput,
createTextBoxInput,
)
from src.Util import convertMassUnitsFrom, convertMassUnitsTo, getFusionUnitSystem


class GamepieceConfigTab:
Expand All @@ -19,7 +19,6 @@ class GamepieceConfigTab:
gamepieceTable: adsk.core.TableCommandInput
previousAutoCalcWeightCheckboxState: bool
previousSelectedUnitDropdownIndex: int
currentUnits: PreferredUnits

@logFailure
def __init__(self, args: adsk.core.CommandCreatedEventArgs, exporterOptions: ExporterOptions) -> None:
Expand All @@ -37,20 +36,6 @@ def __init__(self, args: adsk.core.CommandCreatedEventArgs, exporterOptions: Exp
)
self.previousAutoCalcWeightCheckboxState = exporterOptions.autoCalcGamepieceWeight

self.currentUnits = exporterOptions.preferredUnits
imperialUnits = self.currentUnits == PreferredUnits.IMPERIAL
weightUnitTable = gamepieceTabInputs.addDropDownCommandInput(
"gamepieceWeightUnit", "Unit of Mass", adsk.core.DropDownStyles.LabeledIconDropDownStyle
)

# Invisible white space characters are required in the list item name field to make this work.
# I have no idea why, Fusion API needs some special education help - Brandon
weightUnitTable.listItems.add("‎", imperialUnits, IconPaths.massIcons["LBS"])
weightUnitTable.listItems.add("‎", not imperialUnits, IconPaths.massIcons["KG"])
weightUnitTable.tooltip = "Unit of mass"
weightUnitTable.tooltipDescription = "<hr>Configure the unit of mass for for the weight calculation."
self.previousSelectedUnitDropdownIndex = int(not imperialUnits)

self.gamepieceTable = createTableInput(
"gamepieceTable",
"Gamepiece",
Expand All @@ -62,8 +47,17 @@ def __init__(self, args: adsk.core.CommandCreatedEventArgs, exporterOptions: Exp
self.gamepieceTable.addCommandInput(
createTextBoxInput("gamepieceNameHeader", "Name", gamepieceTabInputs, "Name", bold=False), 0, 0
)
fusUnitSystem = getFusionUnitSystem()
self.gamepieceTable.addCommandInput(
createTextBoxInput("gamepieceWeightHeader", "Weight", gamepieceTabInputs, "Weight", bold=False), 0, 1
createTextBoxInput(
"gamepieceWeightHeader",
"Weight",
gamepieceTabInputs,
f"Weight {'(lbs)' if fusUnitSystem is UnitSystem.IMPERIAL else '(kg)'}",
bold=False,
),
0,
1,
)
self.gamepieceTable.addCommandInput(
createTextBoxInput(
Expand Down Expand Up @@ -112,10 +106,6 @@ def isVisible(self, value: bool) -> None:
def isActive(self) -> bool:
return self.gamepieceConfigTab.isActive or False

@property
def selectedUnits(self) -> PreferredUnits:
return self.currentUnits

@property
def autoCalculateWeight(self) -> bool:
autoCalcWeightButton: adsk.core.BoolValueCommandInput = self.gamepieceConfigTab.children.itemById(
Expand Down Expand Up @@ -168,26 +158,13 @@ def addChildOccurrences(childOccurrences: adsk.fusion.OccurrenceList) -> None:
frictionCoefficient.valueOne = 0.5

physical = gamepiece.component.getPhysicalProperties(adsk.fusion.CalculationAccuracy.LowCalculationAccuracy)
if self.currentUnits == PreferredUnits.IMPERIAL:
gamepieceMass = toLbs(physical.mass)
else:
gamepieceMass = round(physical.mass, 2)

gamepieceMass = round(convertMassUnitsFrom(physical.mass), 2)
weight = commandInputs.addValueInput(
"gamepieceWeight", "Weight Input", "", adsk.core.ValueInput.createByString(str(gamepieceMass))
)
weight.tooltip = "Weight of field element"
weight.isEnabled = not self.previousAutoCalcWeightCheckboxState

weightUnitDropdown: adsk.core.DropDownCommandInput = self.gamepieceConfigTab.children.itemById(
"gamepieceWeightUnit"
)
if weightUnitDropdown.selectedItem.index == 0:
weight.tooltipDescription = "<tt>(in pounds)</tt>"
else:
assert weightUnitDropdown.selectedItem.index == 1
weight.tooltipDescription = "<tt>(in kilograms)</tt>"

row = self.gamepieceTable.rowCount
self.gamepieceTable.addCommandInput(gamepieceName, row, 0)
self.gamepieceTable.addCommandInput(weight, row, 1)
Expand Down Expand Up @@ -222,7 +199,7 @@ def getGamepieces(self) -> list[Gamepiece]:
gamepieces: list[Gamepiece] = []
for row in range(1, self.gamepieceTable.rowCount): # Row is 1 indexed
gamepieceEntityToken = self.selectedGamepieceList[row - 1].entityToken
gamepieceWeight = self.gamepieceTable.getInputAtPosition(row, 1).value
gamepieceWeight = convertMassUnitsTo(self.gamepieceTable.getInputAtPosition(row, 1).value)
gamepieceFrictionCoefficient = self.gamepieceTable.getInputAtPosition(row, 2).valueOne
gamepieces.append(Gamepiece(gamepieceEntityToken, gamepieceWeight, gamepieceFrictionCoefficient))

Expand All @@ -232,25 +209,14 @@ def reset(self) -> None:
self.selectedGamepieceEntityIDs.clear()
self.selectedGamepieceList.clear()

@logFailure
def updateWeightTableToUnits(self, units: PreferredUnits) -> None:
assert units in {PreferredUnits.METRIC, PreferredUnits.IMPERIAL}
conversionFunc = toKg if units == PreferredUnits.METRIC else toLbs
for row in range(1, self.gamepieceTable.rowCount): # Row is 1 indexed
weightInput: adsk.core.ValueCommandInput = self.gamepieceTable.getInputAtPosition(row, 1)
weightInput.value = conversionFunc(weightInput.value)

@logFailure
def calcGamepieceWeights(self) -> None:
for row in range(1, self.gamepieceTable.rowCount): # Row is 1 indexed
weightInput: adsk.core.ValueCommandInput = self.gamepieceTable.getInputAtPosition(row, 1)
physical = self.selectedGamepieceList[row - 1].component.getPhysicalProperties(
adsk.fusion.CalculationAccuracy.LowCalculationAccuracy
)
if self.currentUnits == PreferredUnits.IMPERIAL:
weightInput.value = toLbs(physical.mass)
else:
weightInput.value = round(physical.mass, 2)
weightInput.value = round(convertMassUnitsFrom(physical.mass), 2)

@logFailure
def handleInputChanged(
Expand Down Expand Up @@ -283,20 +249,6 @@ def handleInputChanged(

self.previousAutoCalcWeightCheckboxState = autoCalcWeightButton.value

elif commandInput.id == "gamepieceWeightUnit":
weightUnitDropdown = adsk.core.DropDownCommandInput.cast(commandInput)
if weightUnitDropdown.selectedItem.index == self.previousSelectedUnitDropdownIndex:
return

if weightUnitDropdown.selectedItem.index == 0:
self.currentUnits = PreferredUnits.IMPERIAL
else:
assert weightUnitDropdown.selectedItem.index == 1
self.currentUnits = PreferredUnits.METRIC

self.updateWeightTableToUnits(self.currentUnits)
self.previousSelectedUnitDropdownIndex = weightUnitDropdown.selectedItem.index

elif commandInput.id == "gamepieceAddButton":
gamepieceSelection.isVisible = gamepieceSelection.isEnabled = True
gamepieceSelection.clearSelection()
Expand Down
Loading
Loading