We have programmatically created various Revit elements using the Revit .NET Creation APIs, specifically those New or Create methods. We also created a non-leaning Pisa Tower using all those Revit .NET Creation APIs that have been demonstrated in detail separately.
Here is how the resultant Pisa Tower looks beautifully in Revit after being rendered.
The ColumnCreation class along with its useful methods have been fine tuned a
bit when used to create the non-leaning Pisa Tower. Here is the latest
code.
public class ColumnCreation
{
public static IOrderedEnumerable<Level> FindAndSortLevels(RvtDocument doc)
{
return new FilteredElementCollector(doc)
.WherePasses(new ElementClassFilter(typeof(Level), false))
.Cast<Level>()
.OrderBy(e => e.Elevation);
}
public static IEnumerable<Family> FindColumnFamilies(RvtDocument doc)
{
return new FilteredElementCollector(doc)
.OfClass(typeof(Family))
.Cast<Family>()
.Where(e => e.FamilyCategory != null
&& e.FamilyCategory.Id.IntegerValue == (int)BuiltInCategory.OST_Columns);
}
public static FamilySymbol GetFirstSymbol(Family family)
{
return (from FamilySymbol fs in family.Symbols select fs).FirstOrDefault();
}
public static FamilyInstance InsertColumn(Document doc, XYZ location)
{
FamilySymbol symbol = GetFirstSymbol(FindColumnFamilies(doc).FirstOrDefault());
FamilyInstance famInst = doc.Create.NewFamilyInstance(location, symbol, StructuralType.Column);
return famInst;
}
public static FamilyInstance InsertColumn(Document doc, FamilySymbol symbol, XYZ location, Level topLevel, double topOffset, Level baseLevel, double baseOffset)
{
FamilyInstance famInst = doc.Create.NewFamilyInstance(location, symbol, baseLevel, StructuralType.Column);
famInst.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(topLevel.Id);
famInst.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(topOffset);
//famInst.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(baseLevel.Id);
famInst.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(baseOffset);
return famInst;
}
public static void TestCreateColumn(Document doc, XYZ location)
{
FamilySymbol symbol = ColumnCreation.GetFirstSymbol(ColumnCreation.FindColumnFamilies(doc).FirstOrDefault());
IOrderedEnumerable<Level> levels = FindAndSortLevels(doc);
Level toplevel = levels.Last();
Level baseLevel = levels.ElementAt(levels.Count() - 2);
InsertColumn(doc, symbol, location, toplevel, 0.0, baseLevel, 0.0);
}
public static FamilyInstance InsertColumn_crash(Document doc, FamilySymbol symbol, XYZ location, ElementId topLevel, double topOffset, ElementId baseLevel, double baseOffset)
{
FamilyInstance famInst = doc.Create.NewFamilyInstance(location, symbol, StructuralType.Column);
famInst.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(topLevel);
famInst.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(topOffset);
famInst.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(baseLevel);
famInst.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(baseOffset);
return famInst;
}
public static List<FamilyInstance> InsertColumnsInRectangularArray(Document doc, FamilySymbol symbol, Level topLevel, double topOffset, Level baseLevel, double baseOffset, XYZ center, double l1, double l2, int num1, int num2)
{
List<FamilyInstance> list = new List<FamilyInstance>();
XYZ leftBottom = center - new XYZ(l1 / 2, l2 / 2, center.Z);
double xDist = l1 / (num1 - 1);
double yDist = l2 / (num2 - 1);
for (int i = 0; i < num1; i++)
for (int j = 0; j < num2; j++)
list.Add(InsertColumn(doc, symbol,
leftBottom + new XYZ(xDist * i, yDist * j, center.Z),
topLevel, topOffset, baseLevel, baseOffset));
return list;
}
public static List<FamilyInstance> InsertColumnAroundCircle(Document doc, FamilySymbol symbol, Level topLevel, double topOffset, Level baseLevel, double baseOffset, XYZ center, double radius, int num, double startAngle)
{
List<FamilyInstance> list = new List<FamilyInstance>();
for (int i = 0; i < num; i++)
{
double angle = startAngle * Math.PI / 180 + Math.PI * 2 / num * i;
XYZ location = center + new XYZ(radius * Math.Cos(angle), radius * Math.Sin(angle), center.Z);
FamilyInstance famInst = InsertColumn(doc, symbol,
location,
topLevel, topOffset, baseLevel, baseOffset);
Line axis = doc.Application.Create.NewLine(location, XYZ.BasisZ, false);
ElementTransformUtils.RotateElement(doc, famInst.Id, axis, angle);
list.Add(famInst);
}
return list;
}
public static Family LoadColumnFamily(Document doc, string name)
{
string libPath = doc.Application.GetLibraryPaths()["Imperial Library"];
string path = Path.Combine(libPath, @"Columns\" + name + ".rfa");
Family family;
doc.LoadFamily(path, out family);
return family;
}
public static FamilyInstance InsertMetalCladColumn(Document doc, XYZ location, Level topLevel, double topOffset, Level baseLevel, double baseOffset)
{
Family family = ColumnCreation.FindColumnFamilies(doc).FirstOrDefault(e => e.Name == "Metal Clad Column");
if (family == null)
family = LoadColumnFamily(doc, "Metal Clad Column");
FamilySymbol symbol = ColumnCreation.GetFirstSymbol(family);
return InsertColumn(doc, symbol, location, topLevel, topOffset, baseLevel, baseOffset);
}
public static void TestCreateMetalCladColumn(Document doc, XYZ location)
{
FamilySymbol symbol = ColumnCreation.GetFirstSymbol(ColumnCreation.FindColumnFamilies(doc).FirstOrDefault());
IOrderedEnumerable<Level> levels = FindAndSortLevels(doc);
Level toplevel = levels.Last();
Level baseLevel = levels.ElementAt(levels.Count() - 2);
InsertMetalCladColumn(doc, location, toplevel, -2.0, baseLevel, 2.0);
}
public static FamilySymbol GetFirstSymbol(Family family, string name)
{
return (from FamilySymbol fs in family.Symbols where fs.Name == name select fs).FirstOrDefault();
}
public static FamilySymbol GetCreateMetalCladColumnType(Document doc, double diameter)
{
Family family = ColumnCreation.FindColumnFamilies(doc).FirstOrDefault(e => e.Name == "Metal Clad Column");
if (family == null)
family = LoadColumnFamily(doc, "Metal Clad Column");
double adjustedDiameter = ((int)(diameter * 12.0)) / 12.0;
string name = string.Format("{0}' {1}\"", (int)adjustedDiameter, (int)((adjustedDiameter - (int)adjustedDiameter) * 12.0));
FamilySymbol symbol = ColumnCreation.GetFirstSymbol(family, name);
if (symbol != null)
return symbol;
symbol = ColumnCreation.GetFirstSymbol(family).Duplicate(name) as FamilySymbol;
symbol.get_Parameter("Diameter").Set(adjustedDiameter);
return symbol;
}
public static FamilyInstance InsertMetalCladColumn(Document doc, XYZ location, Level topLevel, double topOffset, Level baseLevel, double baseOffset, double diameter)
{
FamilySymbol symbol = GetCreateMetalCladColumnType(doc, diameter);
return InsertColumn(doc, symbol, location, topLevel, topOffset, baseLevel, baseOffset);
}
}
Revit
Addin Wizard (RevitAddinWizard) provides various wizards, coders and
widgets to help program Revit addins. It can be downloaded from the
Download link at the bottom of the blog index page.