Why?
Some time ago, when I was first getting my hands dirty with Revit API, I used to go to Jeremy Tammik’s website and attempt to re-create his examples. Sometimes, I would try to throw in a small change here and there to experiment with it a little bit. Long story short, he had this example about locking things up in a model and preventing it from being deleted. Here’s a full post:
Lock the Model, e.g. Prevent Deletion
It was using something called an Updater – gives you an ability to “watch” Elements in a model – and I thought it would be cool to check it out and learn a little more about it. At the same time I thought that locking things up in a model was dope, so why not implement it in my personal set of tools. However, as you might have noticed that example implemented by Jeremy was locking things up “per session” which means that your list of protected elements was getting re-set every time you close Revit. That sucks! I guess Jeremy really wanted to show the Updater and how that works, rather than locking things up for real. However, I did want to lock things up for real, and I needed to keep them behind bars for as long as I chose to. This is how:
I implemented something called Extensible Storage. What is it? Here’s a description from Autodesk Help Page:
“The Revit API allows you to create your own class-like Schema data structures and attach instances of them to any Element in a Revit model. Schema-based data is saved with the Revit model and allows for higher-level, metadata-enhanced, object-oriented data structures. Schema data can be configured to be readable and/or writable to all users, just a specific application vendor, or just a specific application from a vendor.”
What it really means:
Ability to store custom data inside of Revit Elements. In plain words, it means that you can store your Grandma’s favorite song’s lyrics inside your chair family – and no one would notice (hopefully).
What?
How does that work? Well it’s actually pretty straight forward:
- Create and name a new schema (schema is like an object that will be stored inside the Element)
- Set the read/write access for the schema (so that either only you or everyone has access to it)
- Define one or more fields of data for the schema (fields are like parameters. you can have multiple fields in one Schema)
- Create an entity based on the schema (entity is like an instance of a schema. all that stuff above is really defining what the Schema will be, but you really create an instance of it when you create an entity)
- Assign values to the fields for the entity (write something to your parameter)
- Associate the entity with a Revit element (add that instance to Revit element)
What this means in practice? Let’s demonstrate how you can store a string (text) inside of Element. First let’s implement a CreateSchema() method that will create a new Schema for us.
How?
Next we need a method to create an Entity of this Schema (instance) and add it to an Element:
Now, these two utility methods is pretty much all we need to successfully implement an Extensible Storage in our model, and reap the benefits of storing “stuff” in our Revit model. In case that you are still questioning the merits of this method I recommend reading this PDF by Jeremy that he used when presenting at AU few years ago:
Extensible Storage in the Revit 2012 API
It has some real nice examples, as well as great explanation of why Extensible Storage would be better than Shared Parameters in some cases.
Let’s have a look at the whole thing implementing these two methods as well as an Updater to lock things up in a model for good – no Pin necessary. :-)
You will need an Updater and Application code to re-create this so please grab it from Jeremy’s website. It’s posted in the first link on top of this page.
Hi Konrad,
Thank you for such an inspirational article! I’m quite new with C# and it’s been a privilege to learn from examples shared by persons such as yourself. I tried to recreate the example and everything worked out perfectly except I can’t figure out a way to automatically start the protection after re-opening the file (i.e. I lock some elements from deletion, save and close and re-open the file, I always have to run the PreventDeletion command first before the protectedId list gets filled up and the updater kicks in) What can I do to initialize the protecteIds list upon the opening of the file? Many thanks in advance.
UPDATE: I managed to solve it by adding a DocumentOpened EventHandler in the application. Thank you for the inspiration anyway.
Hi, I tried this code but I can not store the entity on the element, I have an exception “A managed exception was thrown by Revit or by one of its external applications”. Somebody has had this issue?
konrad, i appreciate your here presented results!
as i am constantly failing to get the fieldcontent in a python approach, do you by any chance have ellaborated a solution based on python?
i’m stuck @
fieldData = entity.Get(“myfieldname”, DisplayUnitType_DUT_METERS)
the schema is created, the data is stored in the fields (i can access the data with RevitLookup)
unfortunately i have no clue how to read the content with ironpython
thanks in advance
peter