How to loop through the Design Option Sets of a document?

How to loop through the Design Option Sets of a document?

Anonymous
Not applicable
1,949 Views
8 Replies
Message 1 of 9

How to loop through the Design Option Sets of a document?

Anonymous
Not applicable

Hi all,

 

I'm having trouble looping through all of the Design Option Sets in a document. I'm able to loop through all of the Design Options, but that object seems to have no information about what Design Option Set it belongs to. Code below.

 

 

Essentially, in the end I would like to display the Design Option Sets and Design Options in a TreeView, much like how it is shown in Revit.

 

 

Looping through design options of a document:

For Each projectDocument As Revit.DB.Document In commandData.Application.Application.Documents
                If linkedModelData.Contains(D & projectDocument.PathName & L) Then
                    Dim linkedModelRootNode = tvDesignOptions.Nodes.Add(projectDocument.Title)

                    'Loop through design options and add to the tree view
                    Dim collector = New Revit.DB.FilteredElementCollector(projectDocument)
                    Dim FilteredDesignOptionElements = collector.OfClass(GetType(Revit.DB.DesignOption)).GetElementIterator


                    While FilteredDesignOptionElements.MoveNext
                        Dim currentDesignOption As DesignOption = FilteredDesignOptionElements.Current

                        Dim designOptionNode = linkedModelRootNode.Nodes.Add(currentDesignOption.Name)
                        designOptionNode.Tag = currentDesignOption.UniqueId & D & projectDocument.PathName

                        'If the design option was previously selected, set to checked
                        If CurrentlySelectedDesignOptions.Contains(D & currentDesignOption.UniqueId & D) Or currentDesignOption.IsPrimary Then
                            designOptionNode.Checked = True
                        End If
                    End While

                    linkedModelRootNode.ExpandAll()
                End If
            Next

0 Likes
Accepted solutions (1)
1,950 Views
8 Replies
Replies (8)
Message 2 of 9

jeremytammik
Autodesk
Autodesk

Dear John,

 

\You could simplify your code a bit and skip the GetElementIterator and MoveNext stuff by simply using Foreach directly on the collector itself.

 

You could also make your code a little bit more readable by using the {i} 'Insert Code' button above.

 

I searched the Revit API help for various combinations of the three words design option set.

 

I found some interesting titbits like the ElementDesignOptionFilter and PrimaryDesignOptionMemberFilter classes, the ElementRecord.GetDesignOptionId method (mistake?) and the Element.DesignOption property, but nothing that looks as if it might be useful for you.

 

Maybe there is no official API support for what you want to achieve.

 

Here is an unofficial approach that does some of it:

 

http://thebuildingcoder.typepad.com/blog/2015/03/list-and-switch-design-options-using-ui-automation....

 

I look forward to hearing how you end up solving this.

 

Good luck!

 

Best regards,

 

Jeremy

 



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

0 Likes
Message 3 of 9

Anonymous
Not applicable

 A bit late, but maybe it'll help someone...

 

public class DesignOptionSet
{
    public string Name { get; set; }
    public IEnumerable<string> DesignOptions { get; set; }
}
private IEnumerable<DesignOptionSet> GetDesignOptionSets(Document document)
{
    List<DesignOptionSet> designOptionSets = new List<DesignOptionSet>();

    foreach (DesignOption dOpt in new FilteredElementCollector(document).OfClass(typeof(DesignOption)).Cast<DesignOption>())
    {
        DesignOptionSet t = new DesignOptionSet();
        Element e = document.GetElement(dOpt.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementId());

        t.Name = e.Name;
        List<string> option = new List<string>
        {
            dOpt.Name
        };
        t.DesignOptions = option;
        designOptionSets.Add(t);
    }

    // group by name to remove duplicate names and group options
    designOptionSets = designOptionSets
        .GroupBy(t => t.Name,
            (k, opt) => new DesignOptionSet()
            {
                Name = k,
                DesignOptions = opt.Select(ts => ts.DesignOptions.FirstOrDefault()).ToList()
            }
            ).ToList();

    return designOptionSets;

}
Message 4 of 9

jan_christel
Participant
Participant

That works a charm! Thank you!

0 Likes
Message 5 of 9

jan_christel
Participant
Participant

Here is the above code in python 🙂

 

# desing sets
def GetNumberOfDesignSets(doc):
    collector = FilteredElementCollector(doc).OfClass(DesignOption)
    designSets = []
    for do in collector:
        e = doc.GetElement(do.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementId())
        designSetName = Element.Name.GetValue(e)
        if(designSetName not in designSets):
            designSets.append(designSetName)
    return len(designSets)
Message 6 of 9

David_W_Koch
Mentor
Mentor

@jan_christel 

 

I am trying to do something similar in python.  My code is trying to create a list of the Design Option Sets associated with each Design Option in a list.  I am using what seems to me to be identical code to what you showed, but I get an error:   AttributeError: 'Parameter' object has no attribute 'AsElementID'.

 

designOptions is the variable that holds the list of Design Options.

 

 

 

designOptionSets = []
for dO in designOptions:
    designOptionSet = doc.GetElement(dO.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementID())
    designOptionSets.append(designOptionSet)

 

 

Any and all suggestions are welcome.  Am I missing an import statement?  Here is what I have for that:

 

 

 

import clr

# Import RevitAPI.
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference("RevitNodes")
import Revit

clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Import Document Manager and TransactionManager.
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

 

 

I am doing this in Revit 2022 at the moment if that matters.


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

0 Likes
Message 7 of 9

jan_christel
Participant
Participant
Accepted solution

Hi David,

Uh that had me stumped 🙂
Turns out there is a spelling error in this line:

designOptionSet = doc.GetElement(dO.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementID())

should be:

designOptionSet = doc.GetElement(dO.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementId())

ElementID vs ElementId (lowercase d in Id)

 

Message 8 of 9

David_W_Koch
Mentor
Mentor

I am at a loss here.

 

The API documentation says that the Parameter Class has an AsElementID method.

 

(dO0.get_Parameter(BuiltInParameter.OPTION_SET_ID)) , where dO0 is the first item on my designOptions elements list:

  • Prints as 
    <Autodesk.Revit.DB.Parameter object at 0x0000000000000513 [Autodesk.Revit.DB.Parameter]>
  • The StorageType is ElementID.
  • The HasValue property is True.
  • Yet (dO0.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementID()) throws an error stating AttributeError:  'Parameter' object has no attribute 'AsElementID'.

I tried this in Revit 2020 and 2024 as well and got the same results.


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

0 Likes
Message 9 of 9

David_W_Koch
Mentor
Mentor

@jan_christel wrote:

Hi David,

Uh that had me stumped 🙂
Turns out there is a spelling error in this line:

designOptionSet = doc.GetElement(dO.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementID())

should be:

designOptionSet = doc.GetElement(dO.get_Parameter(BuiltInParameter.OPTION_SET_ID).AsElementId())

ElementID vs ElementId (lowercase d in Id)

 


 

THANK YOU!  I am embarrassed to say how long I have stared at this code, comparing it to the sources I had, and never saw the error in capitalizing the "d".  Ignore my previous post - I started writing it before your reply.

 

Thanks again!


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature