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?
Solved! Go to Solution.
Solved by mhannonQ65N2. Go to Solution.
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)
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.
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
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
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.
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
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);
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);
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?
Sorry, that was wrong. The lines are:
Parameter parameter = revitElement.LookupParameter("Flächengewicht");
double valueRevit = UnitUtils.ConvertToInternalUnits(value, UnitTypeId.KilogramsForcePerSquareMeter);
parameter.Set(valueRevit);
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);
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.
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.
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.
Can't find what you're looking for? Ask the community or share your knowledge.