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.
Things become super easy and cool with the Revit Data Operator, however it does not support the Revit UV type directly. Do not worry! We are going to address the issue in this post.
A simple wrapper needs to be created. After that, the data with the Revit UV type can be used almost the same way as .NET simple types.
Here is the UV wrapper:
public class UVWrapper
{
private UV mUV;
public UVWrapper()
{
}
public UVWrapper(UV uv)
{
mUV = uv;
mValues = new double[] { uv.U, uv.V };
}
public UV GetUV()
{
return new UV(mValues[0], mValues[1]);
}
private double[] mValues;
public double[] Vaules
{
get
{
return mValues;
}
set
{
mValues = value;
}
}
}
Here is the code to write the data to a selected Element:
UVWrapper uvWrapper = new UVWrapper(new UV(1.1, 2.2));
RevitAddinWizard.SuperEasyCoolDataOperator.SetDataToElement(
"DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", uvWrapper, CachedDoc.GetElement(picked));
Here is the code to read back the data from the same Element:
UVWrapper uvWrapper = RevitAddinWizard.SuperEasyCoolDataOperator.GetDataFromElement<UVWrapper>("DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", CachedDoc.GetElement(picked));
UV uv = uvWrapper.GetUV();
Once again, we only need two lines of code to get the work done.
Through adding two more lines of code as follows,
string str = string.Format("U: {0}\nV: {1}", uv.U, uv.V);
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