Automating View Filters in Revit with a Custom Macro

Recently, I worked on improving my Revit workflow by building a custom macro that automatically creates view filters based on wall types. Later it creates a view where it applies all these filters with cut patters with random colours.

We improve our lives one automation at a time!
public void CreateWallTypeFiltersTemplate() {
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
using(Transaction t = new Transaction(doc, "Create WallType Filters Template")) {
t.Start();
// 1. Collect wall types + Type Marks
List < string > typeMarks = new List < string > ();
var wallTypes = new FilteredElementCollector(doc)
.OfClass(typeof (WallType))
.Cast < WallType > ();
foreach(WallType wt in wallTypes) {
Parameter p = wt.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_MARK);
if (p != null) {
string val = p.AsString();
if (!string.IsNullOrEmpty(val) && !typeMarks.Contains(val)) {
typeMarks.Add(val);
}
}
}
if (typeMarks.Count == 0) {
TaskDialog.Show("Error", "No Type Marks found.");
t.RollBack();
return;
}
// 2. Get Solid Fill pattern
FillPatternElement solidFill = null;
foreach(FillPatternElement f in new FilteredElementCollector(doc).OfClass(typeof (FillPatternElement))) {
if (f.GetFillPattern().IsSolidFill) {
solidFill = f;
break;
}
}
if (solidFill == null) {
TaskDialog.Show("Error", "Solid fill pattern not found.");
t.RollBack();
return;
}
// 3. Create / get View Template
View template = null;
foreach(View v in new FilteredElementCollector(doc).OfClass(typeof (View))) {
if (v.IsTemplate && v.Name == "Temp_ViewTypes") {
template = v;
break;
}
}
if (template == null) {
ViewFamilyType vft = new FilteredElementCollector(doc)
.OfClass(typeof (ViewFamilyType))
.Cast < ViewFamilyType > ()
.First(x => x.ViewFamily == ViewFamily.FloorPlan);
Level level = new FilteredElementCollector(doc)
.OfClass(typeof (Level))
.Cast < Level > ()
.First();
ViewPlan vp = ViewPlan.Create(doc, vft.Id, level.Id);
vp.Name = "Temp_ViewTypes";
template = vp;
}
// 4. Random generator
Random rnd = new Random();
// 5. Create filters + apply overrides
foreach(string mark in typeMarks) {
string filterName = "WallType_" + mark;
// ---- Check existing filter
ParameterFilterElement filter = null;
foreach(ParameterFilterElement f in new FilteredElementCollector(doc).OfClass(typeof (ParameterFilterElement))) {
if (f.Name == filterName) {
filter = f;
break;
}
}
// ---- Create if not exists
if (filter == null) {
ElementId paramId = new ElementId(BuiltInParameter.ALL_MODEL_TYPE_MARK);
FilterRule rule = ParameterFilterRuleFactory.CreateEqualsRule(paramId, mark, false);
IList < FilterRule > rules = new List < FilterRule > {
rule
};
// Wrap rules into ElementFilter
ElementFilter elementFilter = new ElementParameterFilter(rules);
IList < ElementId > categories = new List < ElementId > {
new ElementId(BuiltInCategory.OST_Walls)
};
filter = ParameterFilterElement.Create(doc, filterName, categories, elementFilter);
}
// ---- Add filter to template
if (!template.GetFilters().Contains(filter.Id)) {
template.AddFilter(filter.Id);
}
// ---- Random color
Color color = new Color((byte) rnd.Next(50, 255), (byte) rnd.Next(50, 255), (byte) rnd.Next(50, 255));
// ---- Override settings
OverrideGraphicSettings ogs = new OverrideGraphicSettings();
ogs.SetCutForegroundPatternId(solidFill.Id);
ogs.SetCutForegroundPatternColor(color);
// optional (safer visually)
ogs.SetCutBackgroundPatternId(solidFill.Id);
ogs.SetCutBackgroundPatternColor(color);
template.SetFilterOverrides(filter.Id, ogs);
template.SetFilterVisibility(filter.Id, true);
}
t.Commit();
}
TaskDialog.Show("Done", "Template + filters created successfully.");
}
Written on May 31, 2026