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: 

Determine if Category supports Type parameter binding

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
Todd_Jacobs
2209 Views, 8 Replies

Determine if Category supports Type parameter binding

Hi,

 

I can get a list of categories that support bound paramters like this.

 

SortedList<string, Category> CatList = new SortedList<string, Category>();

Categories cats = doc.Settings.Categories;

foreach (Category cat in cats)
{
   if (cat.AllowsBoundParameters)
   {

      CatList.Add(cat.Name, cat);
   }
}

 

But how can I tell from this list which categories allow Type bound parameters vs. Instance bound parameters I would like to produce two lists, simlar like the UI for adding project parameters when switching from Type to Instance, the Categories list updates with the avaliable categories for the given selection, not interested in sub-categories at the moment.

 

As an example:

The Sheets category shows up only under Instance, but not when selecting Type.

 

 

Thank you,

8 REPLIES 8
Message 2 of 9
jeremytammik
in reply to: Todd_Jacobs

Dear Todd,

Thank you for your query.

I may have just the thing for you:

http://thebuildingcoder.typepad.com/blog/2014/03/category-analysis-with-and-without-python.html

Does that satisfy your needs?

I hope it does.

Best regards,

Jeremy



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

Message 3 of 9
Todd_Jacobs
in reply to: jeremytammik

Jeremy,

 

Thanks for the reply - by the way great info on your blog and GitHub sites.

 

->Does that satisfy your needs?

 

Not really,  I was hoping to not over complicate this solution. Which brings to question, How does Revit do it internally? is it a static list?

 

Here is where I want to be:

// Create a Category Set containing only categories that allow Type bound parameters
Categories cats = doc.Settings.Categories;
Autodesk.Revit.DB.CategorySet catSetTypeOnly = doc.Application.Create.NewCategorySet();
foreach (Category cat in cats)
{
    if (cat.AllowsBoundParameters) // Given to us by Revit.
    {
        if ( catAllowsTypeBoundParameters(cat) ) // Needed by me and maybe some others.
        {
            catSetTypeOnly.Insert(cat);
        }
    }
}

 Then I could produce the same list as Revit for these as shown below:

 

CatBoundSharedTypeAndInstance.png

 

Thanks for your help

Todd

Message 4 of 9
jeremytammik
in reply to: Todd_Jacobs

Dear Todd,

Thank you for your update, both here on the forum and via the ADN case.

I heard back from the development team on this. From the code review, it appears that there is no way to reproduce this list via the API. The internal Revit method to check whether category allows bound type parameters is not exposed to public API. The type parameters support is set up during Revit initialization by static hardcode binding. I am therefore sorry to say that there is currently no API access to this functionality.

I submitted the wish list item CF-1079 [API wish: access to CategoryInfo hasSymbols -- 09406242] on your behalf for the functionality you suggest, as this issue requires exploration and possibly a modification to our software. Please make a note of this number for future reference.

Sorry that I have no better suggestion for you right now.

Please let us know if you find some other way to figure out the information you need. Thank you!

Best regards,

 

Jeremy



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

Message 5 of 9
Todd_Jacobs
in reply to: jeremytammik

For our immediate needs we developed a set of hardcoded enum ‘s for this task as a workaround

 

Please be advised that Equality checks will fail without casting, and Type Safe concerns are not addressed.

 

Please see attached CodeExample.txt

Message 6 of 9
jeremytammik
in reply to: Todd_Jacobs

Dear Todd,

Congratulations on putting together these two useful lists, and thank you very much for sharing them.

I struggled a bit to understand your sample code, and even your choice of enum.

When trying to make use of the sample code snippet as it stands I found it rather convoluted.

It seems to me there must be an easier and more streamlined way of handling this.

I also wonder whether it is more efficient performance-wise to use an enumeration of a dictionary for looking up the built-in categories to find out whether they support type or instance parameters, respectively.

Basically, this can be seen as two dictionaries mapping a built-in category to a Boolean yes-no value.

Or just mapping to a yes value, and no answer stands for no.

I looked at this discussion on 'enum and performance':

http://stackoverflow.com/questions/3256713/enum-and-performance

In the end, I lean towards the dictionary solution.

I therefore reused your two lists to convert them to dictionaries and define two Boolean predicate methods:

  BuiltInCategory bic = ...;
 
  bool bType = BicSupportsTypeParameters( bic );
  bool bInstance = BicSupportsInstanceParameters( bic );

 

I implemented a new external command CmdCategorySupportsTypeParameter in The Building Coder samples to test them.

I use two simple arrays to store the collections of built-in categories supporting type and instance parameters, respectively:

  static public BuiltInCategory[]
    _bicAllowsBoundParametersAsType
      = new BuiltInCategory[]
      {
        ///<summary>Analytical Links</summary>
        BuiltInCategory.OST_LinksAnalytical,
        ///<summary>Structural Connections</summary>
        BuiltInCategory.OST_StructConnections,
        ///<summary>Structural Fabric Areas</summary>
        BuiltInCategory.OST_FabricAreas,

  . . .

        ///<summary>Walls</summary>
        BuiltInCategory.OST_Walls
      };
  #endregion // Built-in categories supporting type parameters

  #region Built-in categories supporting instance parameters
  static public BuiltInCategory[]
    _bicAllowsBoundParametersAsInstance
      = new BuiltInCategory[]
      {
        ///<summary>Analytical Links</summary>
        BuiltInCategory.OST_LinksAnalytical,
        ///<summary>Analytical Nodes</summary>
        BuiltInCategory.OST_AnalyticalNodes,
        ///<summary>Analytical Foundation Slabs</summary>
        BuiltInCategory.OST_FoundationSlabAnalytical,

  . . .
 
        ///<summary>Walls</summary>
        BuiltInCategory.OST_Walls
      };
  #endregion // Built-in categories supporting instance parameters


They are used to define dicctionaries for faster lookup:

  static readonly Dictionary<BuiltInCategory, BuiltInCategory>
    _bicSupportsTypeParameters
      = _bicAllowsBoundParametersAsType
        .ToDictionary<BuiltInCategory, BuiltInCategory>(
          c => c );

  static readonly Dictionary<BuiltInCategory, BuiltInCategory>
    _bicSupportsInstanceParameters
      = _bicAllowsBoundParametersAsInstance
        .ToDictionary<BuiltInCategory, BuiltInCategory>(
          c => c );

 

These in turn are used to define two efficient Boolean predicate lookup functions:

 

  /// <summary>
  /// Return true if the given built-in
  /// category supports type parameters.
  /// </summary>
  static bool BicSupportsTypeParameters(
    BuiltInCategory bic )
  {
    return _bicSupportsTypeParameters.ContainsKey(
      bic );
  }

  /// <summary>
  /// Return true if the given built-in
  /// category supports instance parameters.
  /// </summary>
  static bool BicSupportsInstanceParameters(
    BuiltInCategory bic )
  {
    return _bicSupportsInstanceParameters.ContainsKey(
      bic );
  }

 

Here is the external command Execute method implementation to exercise them:

 

  static string SupportsOrNotString( bool b )
  {
    return b
      ? "supports"
      : "does not support";
  }

  public Result Execute(
    ExternalCommandData revit,
    ref string message,
    ElementSet elements )
  {
    UIApplication uiapp = revit.Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;
    Document doc = uidoc.Document;

    int nCategories = 0;
    int nSupportType = 0;
    int nSupportInstance = 0;
    bool bType, bInstance;

    foreach( BuiltInCategory bic in
      Enum.GetValues( typeof( BuiltInCategory ) ) )
    {
      bType = BicSupportsTypeParameters( bic );
      bInstance = BicSupportsInstanceParameters( bic );

      ++nCategories;
      nSupportType += bType ? 1 : 0;
      nSupportInstance += bInstance ? 1 : 0;

      Debug.Print( "{0} {1} instance and {2} type parameters",
        bic,
        SupportsOrNotString( bInstance ),
        SupportsOrNotString( bType ) );
    }

    string caption = "Categories supporting type "
      + "and instance parameters";

    string msg = string.Format(
      "Tested {0} built-in categories "
      + "in total, {1} supporting instance and {2} "
      + "supporting type parameters.", nCategories,
      nSupportInstance, nSupportType );

    Debug.Print( "\n" + caption + ":\n" + msg );

    TaskDialog.Show( caption, msg );

    return Result.Succeeded;
  }

 

It tests their return gvalue for each and eveery built-in category enumeration value and prints a report like this to the Visual Studio debug output window:

OST_StackedWalls_Obsolete_IdInWrongRange does not support instance and does not support type parameters
OST_MassTags_Obsolete_IdInWrongRange does not support instance and does not support type parameters
OST_MassSurface_Obsolete_IdInWrongRange does not support instance and does not support type parameters
. . .
OST_LinksAnalytical supports instance and supports type parameters
. . .
OST_AnalyticalNodes supports instance and does not support type parameters
. . .
OST_MatchAll does not support instance and does not support type parameters
INVALID does not support instance and does not support type parameters

Categories supporting type and instance parameters:
Tested 919 built-in categories in total, 128 supporting instance and 91 supporting type parameters.

 

I do not see any categories at all that support type parameters and not instance parameters.

Here is the task dialogue summarising the results:

categories_supporting_type_and_instance_parameters.png

I published the full source code in The Building Coder GitHub repository:

https://github.com/jeremytammik/the_building_coder_samples

This is release 2014.0.109.0:

https://github.com/jeremytammik/the_building_coder_samples/releases/tag/2014.0.109.0

I hope this helps.

Best regards,

Jeremy



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

Message 7 of 9
jeremytammik
in reply to: jeremytammik

Dear Todd,

 

Thank you for your appreciation, kudos, and accepting this as a solution!

 

I summarised, cleaned up and published our conversation on The Building Coder blog:

 

http://thebuildingcoder.typepad.com/blog/2014/04/category-support-for-shared-type-and-instance-param...

 

Thank you above all for both raising and solving the issue!

 

Best regards,

 

Jeremy



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

Message 8 of 9
juqing27
in reply to: jeremytammik

@jeremytammik @Todd_Jacobs  Hi Jeremy and Todd! Is there an updated solution now to determine which categories can be type-binding vs which ones are instance-binding? Thought I'd ask since it's 9 years later...:)

 

Thanks,

Qing

Message 9 of 9
Todd_Jacobs
in reply to: Todd_Jacobs

Hello Qing,

As you stated, it's been about 9 years since Jeremy was kind enough to submit the wish list item CF-1079 [API wish: access to CategoryInfo hasSymbols -- 09406242] on my behalf regarding this functionality.  I don't know how to checkup on the progress of this wish list item, maybe if Jeremy is still monitoring this thread he would be kind enough to provide an update.

Regards,

Todd

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