Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MassPerUnitArea bug in ConvertToInternalUnits

15 REPLIES 15
SOLVED
Reply
Message 1 of 16
martin.vollmer9PGT7
940 Views, 15 Replies

MassPerUnitArea bug in ConvertToInternalUnits

I have got a value, that I convert with UnitUtils.ConvertToInternalUnits(value, SpecTypeId.MassPerUnitArea) for Revit 2022 and Revit 2023 and with UnitUtils.ConvertToInternalUnits(value, ParameterType.MassPerUnitArea) for Revit 2020 and Revit 2021.
I set the result to a Autodesk.Revit.DB.Parameter.
When I edit the type parameters, it works with Revit 2020, but I see a completely different value with Revit 2021, 2022 and 2023
My code works with other units for all Revit versions.
Has anyone knowledge about that issue?

15 REPLIES 15
Message 2 of 16

In 2020 ConvertToInternalUnits takes a DisplayUnitType (e.g DUT_KILOGRAMS_MASS_PER_SQUARE_METER), not a ParameterType. In 2022 and later, the ForgeTypeId it takes should be for a unit (e.g. UnitTypeId.KilogramsPerSquareMeter)

Message 3 of 16

Thanks for your answer, but that is not the problem. The given code runs with other units, but not with MassPerUnitArea. And it runs with the unit MassPerUnitArea for Revit 2020, but not for Revit 2021, 2022 and 2023. So with UnitTypeId.KilogramsPerSquareMeter it does not work in Revit 2022 and Revit 2023.

Message 4 of 16

It is as @mhannonQ65N2 noted you need to use UnitTypeId not SpecTypeId i.e. what units are the mass and what units are the area?

 

It is all ForgeTypeIds but there are different versions of the ForgeTypeIds.

 

If you are saying UnitTypeId.KilogramsPerSquareMeter still doesn't convert correctly then suggest you produce a minimal reproducible case or check again what the internal units are for that (they may not be what you expect).

Revit 2023:

 

 

Private Function Obj_220925a(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
        Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
        If UIDoc Is Nothing Then Return Result.Cancelled Else
        Dim IntDoc As Document = UIDoc.Document

        Dim Kg As Double = 100
        Dim m2 As Double = 10

        Dim KgPerSqFt = Kg / (m2 * (1000 / 304.8) ^ 2) 'Internal
        Dim KgPerSqm = Kg / m2

        Dim V0 = UnitUtils.ConvertToInternalUnits(KgPerSqm, UnitTypeId.KilogramsPerSquareMeter)
        Dim V1 = UnitUtils.ConvertFromInternalUnits(V0, UnitTypeId.KilogramsPerSquareMeter)

        Debug.WriteLine(KgPerSqm)
        Debug.WriteLine(V0)
        Debug.WriteLine(V1)
        Debug.WriteLine(KgPerSqFt)

        Return Result.Succeeded
    End Function

 

10
0.9290304
10
0.9290304

Message 5 of 16

Thanks for you answer and example. Your example is exactly what I do. 
If you create a parmeter with that unit and you set your result V0 as value to that parameter, you should see your original value KgPerSqm in Revit, if you edit your parameter. 
I use my code for parameters with the types
SpecTypeId.Length, SpecTypeId.Distance, SpecTypeId.Area, SpecTypeId.Volume, SpecTypeId.Weight, SpecTypeId.MassPerUnitLength, SpecTypeId.ThermalConductivity, SpecTypeId.ThermalResistance.

It works as expected, except with SpecTypeId.MassPerUnitLength. Here I do not see the original value, if I edit that parameter in Revit, do not see the original value KgPerSqm

Message 6 of 16

I can't replicate that in 2023 for type or instance parameter:

 

Incidentally if you use SetValueString it will convert the double input to a string but then likely get it wrong because this method expects display units not internal units. It will only get it right if the display units and the internal units are the same. However, this method shouldn't be used in most cases since it has more overhead. I think you may know this but since you've provided no code I can only guess what you know.

 

220926b.PNG

Private Function Obj_220925a(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
        Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
        If UIDoc Is Nothing Then Return Result.Cancelled Else
        Dim IntDoc As Document = UIDoc.Document

        Dim Kg As Double = 100
        Dim m2 As Double = 10

        Dim KgPerSqFt = Kg / (m2 * (1000 / 304.8) ^ 2) 'Internal
        Dim KgPerSqm = Kg / m2

        Dim V0 = UnitUtils.ConvertToInternalUnits(KgPerSqm, UnitTypeId.KilogramsPerSquareMeter)
        Dim V1 = UnitUtils.ConvertFromInternalUnits(V0, UnitTypeId.KilogramsPerSquareMeter)

        Debug.WriteLine(KgPerSqm)
        Debug.WriteLine(V0)
        Debug.WriteLine(V1)
        Debug.WriteLine(KgPerSqFt)

        Dim R As Reference = Nothing
        Try
            R = UIDoc.Selection.PickObject(Selection.ObjectType.Element)
        Catch ex As Exception
            Return Result.Cancelled
        End Try
        Dim El As Element = IntDoc.GetElement(R)

        Using Tx As New Transaction(IntDoc, "Change Param")
            If Tx.Start = TransactionStatus.Started Then

                Dim Px As Parameter = El.LookupParameter("RPT_MassPerArea")
                Dim Py As Parameter = IntDoc.GetElement(El.GetTypeId).LookupParameter("RPT_MassPerAreaOnType")

                If Px Is Nothing OrElse Py Is Nothing Then
                    Tx.RollBack()
                Else
                    Px.Set(V0)
                    Py.Set(V0 * 2)
                    'I just multiplied it by 2 to distinguish it in the type

                    'Py.SetValueString(V0) 'This may cause you issues since display units are expected.
                    Tx.Commit()
                End If

            End If
        End Using

        Return Result.Succeeded
    End Function

 

 

 

 

Message 7 of 16

That is strange. I create shared parameters. I attached the shared parameter file here. You there see the used parameter "Flächengewicht" with unit type MASS_PER_UNIT_AREA
In between I found, that if I multiply the conversation result (V0) with the factor "0,0310809501733882", I get the right parameter value, when I edit it with unit "kg/m2"
I set the value with parameter.Set(V0);

Message 8 of 16

Can you share the code for this in whatever language you are using?

Message 9 of 16

I cannot share the whole code, but here I collected the regarding lines:

Categories categories = doc.Settings.Categories;
ElementId elementId = new ElementId(Autodesk.Revit.DB.BuiltInCategory.OST_Walls);
Category category = categories.Cast<Category>().ToList().FirstOrDefault(c => c.Id == elementId);
CategorySet categorySet = doc.Application.Create.NewCategorySet();
categorySet.Insert(category);
TypeBinding typeBinding = doc.Application.Create.NewTypeBinding(categorySet);
ExternalDefinitionCreationOptions definitionCreationOptions = new ExternalDefinitionCreationOptions("Flächengewicht", SpecTypeId.MassPerUnitArea);
Definition definition = definitionGroup.Definitions.Create(definitionCreationOptions);
doc.ParameterBindings.Insert(definition, typeBinding, BuiltInParameterGroup.PG_DATA);
HostObjAttributes revitElement = Autodesk.Revit.DB.WallType; //shorted
Parameter parameter = revitElement.LookupParameter("Flächengewicht");
double value = UnitUtils.ConvertToInternalUnits(value, UnitTypeId.KilogramsForcePerSquareMeter);
parameter.Set(valueRevit);

definition = definitionGroup.Definitions.Create(definitionCreationOptions);

Message 10 of 16

The only thing I can see is the following lines look wrong:

 

Parameter parameter = revitElement.LookupParameter("Flächengewicht");
double value = UnitUtils.ConvertToInternalUnits(value, UnitTypeId.KilogramsForcePerSquareMeter);
parameter.Set(valueRevit);

 

i.e. where does 'valueRevit' come from and why is 'value' input into UnitUtils on the same line that it is defined as a double?

Message 11 of 16

Sorry, that was wrong. The lines are:

Parameter parameter = revitElement.LookupParameter("Flächengewicht");
double valueRevit = UnitUtils.ConvertToInternalUnits(value, UnitTypeId.KilogramsForcePerSquareMeter);
parameter.Set(valueRevit);

Message 12 of 16

Hint: With Revit 2020 and DisplayUnitType.DUT_KILOGRAMS_MASS_PER_SQUARE_METER it works as expected.

Parameter parameter = revitElement.LookupParameter("Flächengewicht");
double valueRevit = UnitUtils.ConvertToInternalUnits(value, DisplayUnitType.DUT_KILOGRAMS_MASS_PER_SQUARE_METER);
parameter.Set(valueRevit);

Message 13 of 16

Are you doing this on a completely new project where that parameter has never been bound before in any form? My point about this is that once the parameter binding is defined with a certain guid a different version of it with the same guid will not change that. The units would be obvious in the UI however unless the unit symbol is omitted.

 

Can you share the file containing that parameter.

 

The only other difference between you and me is perhaps the UI language I don't know if that would play a part in terms of how the UnitUtils works, it seems unlikely. So your best course of action is probably to prepare a minimal reproducible case for Autodesk to analyse. Based on the information I have I think we've exhausted all the 'it works for me why doesn't it work for you' scenarios I can think of.

Message 14 of 16

I added the shared parmeter file "KnaufSharedParameters.txt" above. 

I tried with different languages, that does not make the difference.

As far as I saw, you did not create a shared parameter in your example for that, did you?
Maybe that is the difference.
We deliver a release end of this week, so I will use my work around with that factor, I have to correct it for this unit.
But next week I will create an example plugin for that.

Message 15 of 16

Your problem is that KilogramsForcePerSquareMeter is not the same as kilograms mass per square meter. Kilograms are a unit of mass. One Kilograms Force is the gravitational force on an object with a mass of 1 kg in Earth's gravitational field (9.80665 m/s² in SI units, 32.1740 ft/s² in Revit's internal units). The number you found, "0,0310809501733882", is the reciprocal of standard gravity in Revit's internal units. So by multiplying a value by that you are converting from kilograms force to kilograms mass.

Message 16 of 16

Awsome, that is it. Thanks a lot  🙂

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report