Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

UnitsManager.formatInternalValue not properly adjusting for precision set in User Preference

mcd8604
Enthusiast

UnitsManager.formatInternalValue not properly adjusting for precision set in User Preference

mcd8604
Enthusiast
Enthusiast

I am trying to display some internal values to the user formatted to their preferences by using UnitsManager.formatInternalValue, however it doesn't seem to be adjusting the precision properly. For example, the user preferences are set as such (with default Unit of mm):

mcd8604_0-1637250158939.png

When I run the following snippet:

 

 

adsk.core.Application.get().activeProduct.unitsManager.formatInternalValue(0.123456789, adsk.core.Application.get().activeProduct.unitsManager.defaultLengthUnits) 

 

 

Then I would expect the return string to be:
1.235 mm

However, the returned value is:

1.2345679 mm

(note that it is actually rounding at the 7th decimal place)

Am I misunderstanding how the formatting system is supposed to work, or is this a bug?

 

edit: I am currently using version 2.0.11415.

0 Likes
Reply
Accepted solutions (1)
507 Views
5 Replies
Replies (5)

kandennti
Mentor
Mentor

Hi @mcd8604 .

 

I thought the preference settings only affect the GUI display, so I'm not sure if I should consider it a bug or not.

Why don't you try using Round for now?

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        value = 0.123456789

        unitMgr: adsk.core.UnitsManager = app.activeProduct.unitsManager
        precision = app.preferences.unitAndValuePreferences.generalPrecision

        res = [
            f'original : {unitMgr.formatInternalValue(value)}',
            f'use generalPrecision : {unitMgr.formatInternalValue(round(value, precision))}',
        ]

        ui.messageBox('\n'.join(res))
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes

mcd8604
Enthusiast
Enthusiast

I can do the formatting in my own code if it's necessary. I think that maybe the documentation is misleading.
https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-6592d7a9-703e-4878-a690-b9359acb5cda

0 Likes

mcd8604
Enthusiast
Enthusiast

We have to make sure to round while in the preferred units otherwise the precision will be off by the difference of internal unit precision (cm) and whatever is in preferences. In order to do this, we have to convert to that unit then do the rounding.. but then we have to convert back to internal units again to use the format method:

 

 

 

def _formatInternalValue(value, displayUnits=None, showUnits=True):
	valueConverted = unitsManager.convert(value, 'cm', unitsManager.defaultLengthUnits)
	roundedValueConverted = round(valueConverted, precision)
	roundedValueInternal = unitsManager.convert(roundedValueConverted, unitsManager.defaultLengthUnits, 'cm')
	return unitsManager.formatInternalValue(roundedValueInternal, displayUnits or unitsManager.defaultLengthUnits, showUnits)

 

 

 

edit: Unfortunately, neither of these rounding methods work when converted to inches, for example. This is due to the conversion naturally adding more decimal places in most cases (i.e. because an inch isn't a whole multiple of centimeters).

 

I think this should help a little. Unfortunately, it doesn't support many of the preferences that UnitsManager.formatInternalValue would and I'm left trying to figure out a better way to do this without re-implementing every formatting preference.

 

def _formatInternalValue(value, displayUnits=None, showUnits=True):
	valueConverted = unitsManager.convert(value, unitsManager.internalUnits, displayUnits or unitsManager.defaultLengthUnits)
	roundedValueConverted = round(valueConverted, precision)
	formattedValue = f'{roundedValueConverted}
	if showUnits:
		formattedValue += f' {unitsManager.formatUnits(displayUnits or unitsManager.defaultLengthUnits)}'
	return formattedValue

 

0 Likes

mcd8604
Enthusiast
Enthusiast

I tried working with standardizeExpression and this seems to be working much better, though it is lacking the ability to format trailing zeros properly. I still have to test all the different preferences.

def _formatInternalValue(value, displayUnits=None, showUnits=True):
	convertedValue = unitsManager.convert(value, unitsManager.internalUnits, displayUnits or unitsManager.defaultLengthUnits)
	return unitsManager.standardizeExpression(str(round(convertedValue, precision)), displayUnits or self.unitsManager.defaultLengthUnits)

 

0 Likes

BrianEkins
Mentor
Mentor
Accepted solution

This is a bug.  It should be using the unit preferences settings when formatting the string.  I'll make sure a bug gets logged.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
1 Like