Following up on the previous post, here is how to put all the pieces together to find a door’s glass area above 2′
- Find the glass area of the door as-is
- Edit the door family
- Create a void to eliminate the bottom 2′ of glass
- Reload the door into the project
- Find the glass area of the modified door
- Rollback the changes to the door and the reloading of the door into the RVT

public void MesaureGlassArea()
{
Document doc = this.ActiveUIDocument.Document;
UIDocument uidoc = new UIDocument(doc);
FamilyInstance instance = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as FamilyInstance;
// Get the surface area of glass in the family
string info = "Total glass area in door = " + getGlassAreaInFamily(instance) + "\n";
// Open and edit the family document
Document familyDoc = doc.EditFamily(instance.Symbol.Family);
// The family geometry is going to be edited (to create the void to cut off the bottom 2' of glass) and then reloaded into the RVT.
// After this is done, call getGlassAreaInFamily to get the modified glass area.
// But in the end we don't want to keep all the transactions created by CreateExtrusionAndCutGlass.
// A transaction group can be used to rollback all the transactions that were committed inside the transaction group.
using (TransactionGroup transactionGroup = new TransactionGroup(doc,"Glass measurement"))
{
transactionGroup.Start();
// Cut off the bottom 2 feet of glass
CreateExtrusionAndCutGlass(familyDoc);
// Load the modified family back into the RVT
// FamilyLoadOptions tells Revit to overwrite the existing family instances in the RVT
FamilyLoadOptions loadOptions = new FamilyLoadOptions();
familyDoc.LoadFamily(doc,loadOptions);
// Get the surface area of glass in the modified family
info += "Glass in door above 2 feet = " + getGlassAreaInFamily(instance);
// Rollback the transaction group so that the reloading of the family and modifications to the family are discarded.
transactionGroup.RollBack();
}
TaskDialog.Show("Material info", info);
// Close the family document. False means do not save the file
familyDoc.Close(false);
}
private double getGlassAreaInFamily(Element element)
{
foreach (Material material in element.Materials)
{
if (material.Name == "Glass")
return element.GetMaterialArea(material);
}
return 0;
}
// FamilyLoadOptions tells Revit what to do when loading the family into a document that already contains the family
public class FamilyLoadOptions : IFamilyLoadOptions
{
// Always return true so that all existing families and their parameters are overwritten with the new family
public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
return true;
}
public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
source = FamilySource.Family;
return true;
}
}
private void CreateExtrusionAndCutGlass(Document doc)
{
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
// Height of the void extrusion
double height = 2;
// Four points to define corners of the rectangle to extrude
XYZ pnt1 = new XYZ(-10, -10, 0);
XYZ pnt2 = new XYZ(10, -10, 0);
XYZ pnt3 = new XYZ(10, 10, 0);
XYZ pnt4 = new XYZ(-10, 10, 0);
// Create the four lines of the rectangle
// These are internal "Line" elements, not model lines or detail lines
Line line1 = app.Create.NewLine(pnt1, pnt2, true);
Line line2 = app.Create.NewLine(pnt2, pnt3, true);
Line line3 = app.Create.NewLine(pnt3, pnt4, true);
Line line4 = app.Create.NewLine(pnt4, pnt1, true);
// Put these lines into a CurveArray
CurveArray curveArray = new CurveArray();
curveArray.Append(line1);
curveArray.Append(line2);
curveArray.Append(line3);
curveArray.Append(line4);
// Put this array into a CureArrArray (an array of CurveArrays)
// Extrusion creation uses a CureArrArray so you can extrusion multiple loops
CurveArrArray curveArrayArray = new CurveArrArray();
curveArrayArray.Append(curveArray);
// Create a plane at the origin with a normal in the up direction
XYZ planeNormal = XYZ.BasisZ;
XYZ planeOrigin = XYZ.Zero;
Plane plane = app.Create.NewPlane(planeNormal, planeOrigin);
Extrusion extrusion = null;
using (Transaction t = new Transaction(doc, "Create Extrusion"))
{
t.Start();
// Create a sketch plane to be used for the extrusion
SketchPlane sketchPlane = doc.FamilyCreate.NewSketchPlane(plane);
// Create the extrusion. The "false" specifies that it will be a void
extrusion = doc.FamilyCreate.NewExtrusion(false, curveArrayArray, sketchPlane, height);
t.Commit();
}
// Cut the other 3D elements with the new void using CombineElements and a CombinableElementArray
CombinableElementArray ceArray = new CombinableElementArray();
// Add the new void extrusion to the CombinableElementArray
ceArray.Append(extrusion);
// Add all GenericForm elements with the Glass subcategory to a CombinableElementArray
foreach (GenericForm genericForm in new FilteredElementCollector(doc).OfClass(typeof(GenericForm)).Cast<GenericForm>())
{
Category category = genericForm.Subcategory;
if (category != null && category.Name == "Glass")
{
ceArray.Append(genericForm);
}
}
using (Transaction t = new Transaction(doc, "Combine Elements"))
{
t.Start();
// Combine the elements so that the void will cut the solids
GeomCombination geomCombination = doc.CombineElements(ceArray);
t.Commit();
}
}
Like this:
Like Loading...