Model Creation with RevitAPI
In this article, we will talk about the use of Revit API to create a model with most of the commonly used elements. Let's take a simple model which will look like below.
As you can see, the elements used are
There are a few indirect elements used
Now that we have a fair bit of an idea about what needs to be built, let's see what are the prerequisites for building the model with API.
Assuming that you have the tools, we will start with the model building.
Application & Document
Application and document are top-level classes in the hierarchy of objects. The Document object is our window to the Revit model and provides access to document properties. We have to get the handle to document object
//commandData is ExternalCommandData which is the parameter we receive in //the Execute method of IExternalCommand implementation
UIApplication uiApp = commandData.Application;
Autodesk.Revit.DB.Document doc = app.NewProjectDocument(UnitSystem.Metric);
Next set the Units on the Document
//settings the units is an activity you will have to carry out in //Transaction, so make sure you have one open transaction
Units u = new Units(UnitSystem.Metric);
Nodes & Members
Create the node(point) by using XYZ class
XYZ point1 = new XYZ(0,0,0);
XYZ point2 = new XYX(10,0,0);
//and so on...
Once you get the node, the next task is to create a connection between the nodes or as well call it a member.
Line member1 = Autodesk.Revit.DB.Line.CreateBound(point1, point2);
Next, we create the Level(s)
Level topLevel = Level.Create(doc, elevation);
//where elevation is a elevation in the Model where we want to have //level created
//for example for each Floor in your model, you can have one level or some //business decision will drive this.
Once we have the basic skeleton-level elements in the form of points & and lines, we move on to Family. Let me explain it with an example.
Family
Suppose the model we are building is a Steel Structure containing ISMB100 (Indian Standard Medium Beam). This family will either have to be loaded in the document or you can also create a Family through API and then load it in the document.
The second method is a bit complex but if you want complete control or if you just have the raw data ready to build a family from scratch then of course you can build it.
There are nice articles and code samples available on how to go about the second approach. Autodesk Labs is a good starting point. For now, let's leave it out.
Recommended by LinkedIn
FamilySymbol fs = null;
string rfa_path = "{PATH_TO_RFA_FILE}"
doc.LoadFamily(rfa_path , out fs);
//reference to the method is
https://www.revitapidocs.com/2017/67277d5a-0ddf-b617-c9c9-911ecb928af9.htm
Once you have loaded the family, the next step is to create a Family instance by using NewFamilyInstance ( there are 3 methods available. We are using one most suitable for us at the moment)
The snippet to create the instance is as below
FamilyInstance fi = doc.Create.NewFamilyInstance(point1, fs, topLevel, st);
Parameter baseLevelParam = fi.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
if (baseLevelParam != null){
baseLevelParam.Set(baseLevel.Id);
}
Parameter topLevelParam = fi.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
if (topLevelParam != null){
topLevelParam.Set(topLevel.Id);
}
After creating the instance, we go through the Parameters that are set on the Family for base level and top level params. If we have them, we will set the values accordingly.
StructuralSection
The next step is to assign the StructuralSection to the Family. Revit has a variety of sections e.g. StructuralSectionRectangleHSS,StructuralSectionLAngle, StructuralSectionRoundHSS and so on.. You can read more about name under
Autodesk.Revit.DB.Structure.StructuralSections
These structural sections can be created if you have your custom properties for thickness, diameters, widths, etc. One sample call is shown below
StructuralSection cssShape = new StructuralSectionRoundHSS(
diameter,
wallNominalThickness,
wallDesignThickness,
.......
)
//once we have the structual section, we assign it to the family we //created earlier
fi.Symbol.SetStructuralSection(structuralSection);
Material
The next step is to get or create the material that we want to use in the Model. We can either get it from in-built materials from Revit via below code snippet below using element collectors
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Materials));
var MaterialElement = from element in collector
where element.Name == name
select element;
if (MaterialElement.Count() == 0)
return null;
else
return MaterialElement.First<Element>() as Material;
If we can't find the material in the Revit DB or we want to use custom materials, Revit API comes to the rescue
ElementId idNew = Material.Create(doc, material_name);
materialNew = doc.GetElement(idNew) as Material;
materialNew.Color = new Autodesk.Revit.DB.Color(255, 0, 0);
materialNew.MaterialClass = "Metal";
materialNew.MaterialCategory = "Metal";
StructuralAsset structuralAsset = new StructuralAsset("My Steel", StructuralAssetClass.Metal);
structuralAsset.Behavior = StructuralBehavior.Isotropic;
structuralAsset.Density = XXX;
structuralAsset.YoungModulus = XXX;
PropertySetElement pse = PropertySetElement.Create(doc, structuralAsset);
materialNew.SetMaterialAspectByPropertySet(MaterialAspect.Structural, pse.Id);
What are we doing?
3. Next for assigning the custom structural properties like Young's Modules, Density, and other such, we have to first create StructuralAsset and assign the properties on it.
4. The last step is to assign the StructuralAsset to Material.
Once we have the material, we can assign it to the SectionFamily Category
fi.Category.Material = materialNew;
BoundaryConditions
To create the boundary conditions (BC) or supports , we need to have a "Reference" at which the BC is to be created , the fixity values in 6 degrees of freedom and values for each fixity value.
Reference columnReference = null;
AnalyticalModel columnAnalyticalModel = column.GetAnalyticalModel() as AnalyticalModel;
columnReference = columnAnalyticalModel.GetCurve().GetEndPointReference(0);
// Create the Point Boundary Conditions for the start point
BoundaryConditions condition = doc.Create.NewPointBoundaryConditions(columnReference,
TranslationRotationValue.Fixed, 0,
TranslationRotationValue.Fixed, 0,
TranslationRotationValue.Fixed, 0,
TranslationRotationValue.Release, 0,
TranslationRotationValue.Release, 0,
TranslationRotationValue.Release, 0);
That's it. We have created the entire Revit Model using the powerful Revit API. Please give it a try and feel free to revert in case of any doubts/questions and I will help!!