ExtensibleStorage using RevitPythonShell

471 views Asked by At

I am trying to take advantage of ExtensibleStorage in the Revit API. I'm trying to store an Array in a ArrayField. I think maybe my errors are due to the IronPython interface, but maybe someone has done this successfully? I know that the object to set i supposed to be an IList, but I can't seem to make one. In the IronPython documentation, the Array-object is used as an example. If I try this: vl = IList[ElementId]([v.ViewId for v in views]) I get a Systemerror:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: MakeGenericType on non-generic type

This is my code:

from System import Guid, Array
from Autodesk.Revit.DB.ExtensibleStorage import *

guid = Guid.NewGuid()
views = revit.uidoc.GetOpenUIViews()
vl = Array[ElementId]([v.ViewId for v in views])

schemaBuilder = SchemaBuilder(guid)
schemaBuilder.SetReadAccessLevel(AccessLevel.Public)
schemaBuilder.SetWriteAccessLevel(AccessLevel.Public)
schemaBuilder.SetSchemaName('Testing')
schemaBuilder.AddArrayField('Views', ElementId)
schema = schemaBuilder.Finish()

entity = Entity(schema)
entity.Set('Views', vl)

And this is my error message:

Exception : Autodesk.Revit.Exceptions.InvalidOperationException: Unsupported type: Autodesk.Revit.DB.ElementId[]
   at Autodesk.Revit.DB.ExtensibleStorage.Entity.Set[FieldType](String fieldName, FieldType value, ForgeTypeId unitTypeId)
   at Autodesk.Revit.DB.ExtensibleStorage.Entity.Set[FieldType](String fieldName, FieldType value)

BTW: This is working fine:

from System import Guid, Array
from Autodesk.Revit.DB.ExtensibleStorage import *

guid = Guid.NewGuid()
views = revit.uidoc.GetOpenUIViews()
v = views[0].ViewId

schemaBuilder = SchemaBuilder(guid)
schemaBuilder.SetReadAccessLevel(AccessLevel.Public)
schemaBuilder.SetWriteAccessLevel(AccessLevel.Public)
schemaBuilder.SetSchemaName('Testing')
schemaBuilder.AddSimpleField('Views', ElementId)
schema = schemaBuilder.Finish()

entity = Entity(schema)
entity.Set('Views', v)

To get the value: entity.Get[ElementId]('Views')

3

There are 3 answers

2
Joshua Lumley On

I think I had the same trouble with AddArrayField in c#, and was probably doing something wrong but my quick fix solution was to simply use AddMapField.

    FieldBuilder mapField_Child_Angle = mySchemaBuilder.AddMapField("FurnLocations_Angle", typeof(ElementId), typeof(double));
    mapField_Child_Angle.SetUnitType(UnitType.UT_Length);
0
Kyrre On

This worked for me:

from System import Guid
from System.Collections.Generic import IDictionary, Dictionary
from Autodesk.Revit.DB.ExtensibleStorage import *

keyType = str
valueType = str
name = 'UserViews'
schemaBuilder = SchemaBuilder(Guid.NewGuid())
schemaBuilder.SetReadAccessLevel(AccessLevel.Public)
schemaBuilder.SetWriteAccessLevel(AccessLevel.Public)
schemaBuilder.SetSchemaName('Test')
schemaBuilder.AddMapField(name, keyType, valueType)
schema = schemaBuilder.Finish()
ent = Entity(schema)
dic = Dictionary[str, str]()
dic.Add('kyrreViews', '234234,121345,123113')
ent.Set[IDictionary[str, str]](name, dic)
val = ent.Get[IDictionary[str, str]](name)

>>> val
Dictionary[str, str]({'kyrreViews' : '234234,121345,123113'})
0
Marcus On

Using RevitPythonShell I was able to store an array in a schema field like this:

entity.Set[IList[ElementId]]('Views', vl)