The Revit API 2012 provides an official way to extend the Element data now. In the old days, we could only create some cumbersome invisible parameters and attach them to the elements where we want to store some extra data. Now the Extensible Storage API can directly address so basic a need for us and has much power.
However, as introduced and demonstrated before, unnecessary complexities, impositions, redundancies and inconsistencies are here and there. In case any of those points as mentioned repeatedly in early posts slips out of our minds, the data storage or retrieval would just fail. In addition, the out-of-box supported data types are just a few, far less than enough.
For example, if we would like to store some data of the Autodesk.Revit.DB.Color type, which is popular enough in the Revit API people would admit, what shall we do?
Here is a way to store the Revit Color data, converting all those RGB of the single Color value to some short integer values, using the FieldBuilder and its AddSimpleField() method to define three of such short type Field variables, creating an Entity from the built-up Schema, assigning the RBG short values with three Entity.Set<short>() calls, and finally attaching the Entity instance to the Element of concern. In terms of reading the same Revit Color back, similar things have to be done, but in the opposite order of course. By the way, Byte type cannot be used here since it is not supported by the Field.
It sounds scary, doesn’t it?
Do not worry. With the assistance of the Revit Data Operator, the task becomes super easy. Only two lines of cool code are necessary:
Autodesk.Revit.DB.Color color = new Autodesk.Revit.DB.Color(11, 22, 33);
RevitAddinWizard.SuperEasyCoolDataOperator.SetDataToElement(
"DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", color, CachedDoc.GetElement(picked));
Here is the code to read back the same Color data from the same Element:
Autodesk.Revit.DB.Color color = RevitAddinWizard.SuperEasyCoolDataOperator.GetDataFromElement<Autodesk.Revit.DB.Color>("DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", CachedDoc.GetElement(picked));
Once again, we only need two lines of code to get the work done. In terms of how to pick an Element and start a Transaction so as to set the Color data to the Element, please refere to ealier posts. We have demonstrated how to do so already many times, so we don't replicate the code here.
Through adding two more lines of code as follows,
string str = string.Format("Revit Color: R-{0} G-{1} B-{2}", color.Red, color.Green, color.Blue);
MessageBox.Show(str, "MyData");
we can happily verify that everything works just fine.
Here is the core of the Easy & Cool Revit Data Operator:
using System;
using System.Xml.Serialization;
using System.IO;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage; //Revit API 2012 only
namespace RevitAddinWizard
{
public class SuperEasyCoolDataOperator
{
private const string SingleStringFiledName = "SingleStringForAll";
public static void SetDataToElement(string id, object o, Element e)
{
SchemaBuilder sb = new SchemaBuilder(new Guid(id));
sb.SetSchemaName(id.Replace("-", ""));
FieldBuilder fb = sb.AddSimpleField(SingleStringFiledName, typeof(string));
XmlSerializer xml = new XmlSerializer(o.GetType());
using (StringWriter w = new StringWriter())
{
xml.Serialize(w, o);
Entity ent = new Entity(sb.Finish());
ent.Set<string>(SingleStringFiledName, w.ToString());
e.SetEntity(ent);
}
}
public static T GetDataFromElement<T>(string id, Element e)
{
Schema sch = Schema.Lookup(new Guid(id));
string s = e.GetEntity(sch).Get<string>(SingleStringFiledName);
XmlSerializer xml = new XmlSerializer(typeof(T));
using (StringReader r = new StringReader(s))
{
return (T)xml.Deserialize(r);
}
}
}
}
As can be seen, those complexities and impositions all go away. We do not have to specify the same schema GUIDs, scheme names, field names, data types, unit types repeatedly. We do not have to care about all those intermediate objects such as Schema, SchemaBuilder, Field, FieldBuilder, or Entity anymore either.
What we need to care about now are what we really want, the data object, the Element of concern, and the Schema identifier. If they are consistent with each other, it will be very hard to make the data storage or retrieval fail.
The Revit Addin Wizard (RevitAddinWizard) is going to provide a coder to help generate Extensible Storage code.
Recent Comments