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: 

ForgeTypeId how to use?

32 REPLIES 32
SOLVED
Reply
Message 1 of 33
c_hanschen
21934 Views, 32 Replies

ForgeTypeId how to use?

Hello,

 

I Have been using 'ConvertFromInternalUnits' for many years using DisplayUnitType, but in Revit 2021 is says:

 

Warning BC40000
'Public Shared Overloads Function ConvertFromInternalUnits(value As Double, displayUnit As DisplayUnitType) As Double' is obsolete:
'This method is deprecated in Revit 2021 and may be removed in a future version of Revit.
Please use the `ConvertFromInternalUnits(double, ForgeTypeId)` overload instead.'.

 

Can someone tell me how to use ForgeTypeId for Converting using ConvertFromInternalUnits?

Where do I find the Enumerations? or is it not working like that?

 

I also seems to need the same ForgeTypeId to get the UnitType of a parameter in Revit 2021 using p.definition.GetSpecTypeId

 

Is there any documentation about this (for me new) ForgeTypeId ?

 

Thanks,

 

Chris Hanschen

LKSVDD architecten

The Netherlands

 

32 REPLIES 32
Message 2 of 33
mhannonQ65N2
in reply to: c_hanschen

I'm also very interested in this new type. And while I haven't used it yet, I see in the API that there are 3 classes, SpecTypeId, SymbolTypeId, and UnitTypeId, that contain many ForgeTypeIds in static properties. This is probably where you'll find what you're looking for.

 

I've also done a bit of browsing in Revit 2021's data and found some .json files defining Forge schemas for what I guess are the specs, symbols, and units in those classes. What really intrigues me is the possibility of defining custom units (and symbols and specs).

Message 3 of 33
mhannonQ65N2
in reply to: mhannonQ65N2

I tried redefining leg hands as having 13 inches and Revit reported every file as corrupt. Restoring the ratio alone did not suffice; I had to restore the name to foot/feet for Revit to open any file (including metric files).

Message 4 of 33
c_hanschen
in reply to: mhannonQ65N2

@mhannonQ65N2 ,

 

Where did you find these 'static properties'?

By Example, ForgeTypeId() needs an TypeId definded by a string, I can't find any static values to put into this TypeId as a string.

 

Chris Hanschen

The Netherlands

Message 5 of 33
jeremytammik
in reply to: c_hanschen

Please read the What's New section in the Revit API help file RevitAPI.chm provided with the Revit SDK from the Revit developer centre:

 

https://www.autodesk.com/developer-network/platform-technologies/revit

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 33
c_hanschen
in reply to: jeremytammik

Thanks @jeremytammik,

 

I found it, copy - paste for the people who found this topic before reading the CHM:

All i needed was 'Imports Autodesk.Revit.DB.ForgeTypeId' before it al made sense.

 

----- start copy-paste revit api 2021 chm ------

Units API changes

Revit has converted to use an external reference to unit definitions defined in Forge schemas.

In the Autodesk.Revit.DB namespace, the enumerations DisplayUnitType, UnitSymbolType, and UnitType have been deprecated in favor of a potentially extensible set of units, symbols, and unit types. The new class:

  • Autodesk.Revit.DB.ForgeTypeId

represents an identifier for a unit, symbol, or other object, and is now used throughout the Revit API to identify units of measurement, symbols, and unit types. Unit types are now referred to as "specs" to avoid confusion with units themselves.

A ForgeTypeId instance holds a string, called a "typeid", that uniquely identifies a Forge schema. A Forge schema is a JSON document describing a data structure, supporting data interchange between applications. A typeid string includes a namespace and version number and may look something like "autodesk.spec.aec:length-1.0.0" or "autodesk.unit.unit:meters-1.0.0". By default, comparison of ForgeTypeId values in the Revit API ignores the version number.

The new classes:

  • Autodesk.Revit.DB.UnitTypeId
  • Autodesk.Revit.DB.SymbolTypeId
  • Autodesk.Revit.DB.SpecTypeId

contain a default set of named public constant properties of type ForgeTypeId. These values can be used in code replacing values of the deprecated DisplayUnitType, UnitSymbolType, and UnitType enumerations.

For example, where you previously used DisplayUnitType.DUT_WATTS_PER_SQUARE_METER_KELVIN, you would now use UnitTypeId.WattsPerSquareMeterKelvin. Where you previously used UnitType.UT_HVAC_Density, you would now use SpecTypeId.HvacDensity.

The UnitUtils class now offers a set of new methods for mapping between enumeration values and ForgeTypeId values to assist clients in migrating code to ForgeTypeId:

  • UnitUtils.IsSymbol()

  • UnitUtils.GetSpecTypeId()

  • UnitUtils.GetUnitType()

  • UnitUtils.GetUnitTypeId()

  • UnitUtils.GetDisplayUnitType()

  • UnitUtils.GetSymbolTypeId()

  • UnitUtils.GetUnitSymbolType()

Some of the preceding methods are new but are already deprecated. They have been added to the API only to assist clients in migrating code from the old enumerations to the ForgeTypeId class.

 

----- end copy-paste revit api 2021 chm ------

 

Thanks again!

 

Chris Hanschen

LKSVDD Architecten

The Netherlands

 

Message 7 of 33
reylorente1
in reply to: c_hanschen

string StaticaPressure = UnitFormatUtils.Format(doc.GetUnits(), SpecTypeId.PipingPressure, pipingSystem.GetStaticPressure(), false);

Message 8 of 33
cwaluga
in reply to: reylorente1

I would like to start a discussion among those who cannot afford to ignore deploying for "old" Revit versions. Given that there is a lot of add-in developers out there, supporting more than Revit 2021, is there any migration strategy that Autodesk likes to communicate?

 

In short: How do I ensure that I can still compile Revit 2020 builds when the deprecated DisplayUnitType is removed, possibly next year? It would be nice if Autodesk could delay the actual removal to 2022, so that 2021, 2022 and 2023 can be compiled without introducing hundreds of compile-time switches.

 

Otherwise: I did not inspect the new API in detail yet, but I hope it is written in such a way that it is possible to create an adapter for ForgeTypeId and port old versions to the new style as long as they are supported. In this way we can do an early migration of code that is supposed to compile with backward-compatibility in mind.

Message 9 of 33
jeremytammik
in reply to: cwaluga

@cwaluga Please be aware that the Revit development team do not systematically read all the discussion forum threads.

 

To seriously bring your wish to their attention, I suggest you submit it to the the Revit Idea Station and add your comments there:

 

https://forums.autodesk.com/t5/revit-ideas/idb-p/302

 

Tag it as an API wish:

 

https://forums.autodesk.com/t5/revit-ideas/idb-p/302/tab/most-recent/label-name/api

 

Ensure it gets as many votes as possible to underline its importance to you and the rest of the developer community.

 

The Revit Idea Station is currently one of the main driving input forces for Revit API enhancements.

 

The Revit development team look there. Your comment here in the discussion forum might be overlooked.

 

Thank you!

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 10 of 33
David_Robison
in reply to: cwaluga

My plan was hundreds of compile time switches.

Message 11 of 33
FRFR1426
in reply to: c_hanschen

A sample code is always welcome:

 

#if REVIT2019 || REVIT2020
double valueInInternalUnits = UnitUtils.ConvertToInternalUnits(valueInMeters,
  DisplayUnitType.DUT_METERS);
#else
// Revit 2021+
double valueInInternalUnits = UnitUtils.ConvertToInternalUnits(valueInMeters, UnitTypeId.Meters);
#endif
Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
Message 12 of 33
reylorente1
in reply to: FRFR1426

I would like, how to show the DisplayUnitType in Revit 2021.

 

I have 

 

InternalDefinition inter = param.Definition as InternalDefinition;
            var displayparam = param.DisplayUnitType;
            var unitparam = inter.UnitType;

 

This is obsolete for Revit 2021,

now is

//Veamos el BuiltinParameter,DisplayUnitType,UnitType
            InternalDefinition inter = param.Definition as InternalDefinition;
            var displayparam = param.GetUnitTypeId();
            var unitparam = inter.GetSpecTypeId();

How do I show it?2020-08-24.png

 

How do I show it?

 

Message 13 of 33


@David_Robison wrote:

My plan was hundreds of compile time switches.


Me too!

 

But I figured I could move most of my conversions to an extension class which I use to convert my values. In my case most of the conversions in my add-ins are from internal unit to metric and back so I'm getting rid of most compiler flags by concentrating them to a couple of extension classes:

 

 

public static class DoubleExtensions
{
    /// <summary>
    /// Translate double from mm to internal Ft
    /// </summary>
    /// <param name="value"></param>
    /// <returns>New value in Ft</returns>
    public static double MmToInternal(this double value)
    {
#if RVT2021
        return UnitUtils.ConvertToInternalUnits(value, UnitTypeId.Millimeters);
#else
        return UnitUtils.ConvertToInternalUnits(value, DisplayUnitType.DUT_MILLIMETERS);
#endif
    }

    /// <summary>
    /// Translate double from internal Ft to mm
    /// </summary>
    /// <param name="value"></param>
    /// <returns>New value in mm</returns>
    public static double InternalToMm(this double value)
    {
#if RVT2021
        return UnitUtils.ConvertFromInternalUnits(value, UnitTypeId.Millimeters);
#else
        return UnitUtils.ConvertFromInternalUnits(value, DisplayUnitType.DUT_MILLIMETERS);
#endif
    }

    /// <summary>
    /// Translate double from degrees to internal radians
    /// </summary>
    /// <param name="value"></param>
    /// <returns>New value in radians</returns>
    public static double DegToInternal(this double value)
    {
#if RVT2021
        return UnitUtils.ConvertToInternalUnits(value, UnitTypeId.Degrees);
#else
        return UnitUtils.ConvertToInternalUnits(value, DisplayUnitType.DUT_DECIMAL_DEGREES);
#endif
    }

    /// <summary>
    /// Translate double from internal radians to degrees
    /// </summary>
    /// <param name="value"></param>
    /// <returns>New value in degrees</returns>
    public static double InternalToDeg(this double value)
    {
#if RVT2021
        return UnitUtils.ConvertFromInternalUnits(value, UnitTypeId.Degrees);
#else
        return UnitUtils.ConvertFromInternalUnits(value, DisplayUnitType.DUT_DECIMAL_DEGREES);
#endif
    }
}

 

And with the added bonus that my code gets quite a bit cleaner without all UnitUtils conversions

 

double distMm = distance.InternalToMm();

 

 

Message 14 of 33
Maltezc
in reply to: c_hanschen

so, the way I understand this thread is that: 

If you have a plugin that spans Revit 2021 and 2022 and you need to get units of the project, 

 

In revit 2021, you can use

string getUnits = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits.ToString();

 

But for the Revit 2022 version, there's no way to get the units unless it's a Forge project and you're running the Revit 2022 API?

Message 15 of 33
David_Robison
in reply to: Maltezc

For Revit 2022, it doesn't need to be any sort of special Forge project. Link it to the Revit 2022 DLL and the function will exist. The signature changes to use ForgeTypeId, but that's just part of the Revit API now.

 

I didn't actually test this code at all, but you would need a change something like this and it will work fine in Revit 2022:

 

#if !REVIT2022
doc.GetUnits().GetFormatOptions(UnitType.UT_Length)
#else
doc.GetUnits().GetFormatOptions(SpecTypeId.Length)
#endif
Message 16 of 33
Maltezc
in reply to: David_Robison

Thank you for the clarification. That helps. 

 

I gotta figure out how to use preprocessor directives as you have used in your example so I can handle different Revit versions in cases such as this. 

Message 17 of 33
c_hanschen
in reply to: Maltezc

I'm using Visual studio 2019 with compile configurations, named R2019, R2020, R2021 and R022

 

My code to convert units from internal to millimeter, this is an example of redirecting to code for the used API.

 

Public Function IU2mm(MyValueInternalUnits As Double, Optional AfrondenHeleMm As Boolean = False) As Double '

Dim mm As Double

#If CONFIG = "R2019" Or CONFIG = "R2020" Then
mm = UnitUtils.ConvertFromInternalUnits(MyValueInternalUnits, DisplayUnitType.DUT_MILLIMETERS)
#Else
mm = UnitUtils.ConvertFromInternalUnits(MyValueInternalUnits, unitTypeId:=UnitTypeId.Millimeters)
#End If

If AfrondenHeleMm = True Then mm = Math.Round(mm, 0)
Return mm

End Function

 

Chris Hanschen

LKSVDD architecten

The Netherlands

Message 18 of 33
jeremy_tammik
in reply to: c_hanschen

Dear Chris, 

 

Thank you for the VB example.

 

Apparently, the conditional compilation syntax in C# differs slightly from VB:

 

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives

 

The #if statement in C# is Boolean and only tests whether the symbol has been defined or not. You can use the operators == (equality) and != (inequality) to test for the bool values `true` or `false`. `true` means the symbol is defined.

 

Here is a nice discussion on concrete usage:

 

https://stackoverflow.com/questions/2923210/conditional-compilation-and-framework-targets

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 19 of 33
jeremy_tammik
in reply to: c_hanschen

So, your method could look like this in C#:

    

 

    public static double InternalUnitToMillimetres( 
      double a, 
      bool roundup = false )
    {
      double mm;

#if (CONFIG_R2019 || CONFIG_R2020)
      mm = UnitUtils.ConvertFromInternalUnits(
        a, DisplayUnitType.DUT_MILLIMETERS );
#else
      mm = UnitUtils.ConvertFromInternalUnits( 
        a, UnitTypeId.Millimeters );
#endif
      
      return roundup ? Math.Round( mm, 0 ) : mm;
    }

 

   

Many, many, more nice examples above...

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 20 of 33
Maltezc
in reply to: c_hanschen

Hi all, I'm having trouble setting up for multiple versions. 

 

I created a separate post here.

 

It is primarily focused on the .csproj part of the setup. 

 

First time using preprocessor directives.

 

Feel free to give it a look over.

 

I'd appreciate it. 

 

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community