Last week I went to Belo Horizonte for a quick Revit API Training. It was a good time visit my university campus and remember the good times as a Civil Engineer student (and we’re about to celebrate 10 years now, time flies!).
If you haven’t visit this part of the word, here is a quick view of the Church of Saint Francis of Assisi (Igreja de Sao Francisco de Assis) designed by famous Brazilian architect Oscar Niemeyer. Is a nice piece of curved concrete (now it’s the Civil Engineer speaking).
During the Revit API training we used the 2015 version of our training material with the Visual Studio template. I enjoy doing training where we have a problem to solve, which is a good background to teach some API concepts. The problem in hand is: for a 3D view with equipments (represented by generic models), create individual views for each equipment and export to DWG files.
One way is by the code below. Basically we get all generic model instances on the active view, then the respective families. Now create a view using each family name. This was the easy part…
To make the view show only the specific family instance, we need to create and set a view filter. Actually Jeremy did a similar code that we reused and adjusted here. Finally export all the created views.
Check the code below, the comments should help understand the steps.
// get the active document from the command Execute param
Document doc = commandData.Application.ActiveUIDocument.Document;
// get all generic models on the current 3D View
FilteredElementCollector collGenericModels =
new FilteredElementCollector(doc, doc.ActiveView.Id);
collGenericModels.OfClass(typeof(FamilyInstance));
collGenericModels.OfCategory(BuiltInCategory.OST_GenericModel);
// but we need the families of these generic models,
// so let's create a list with the family IDs
List<int> genericModelsFamiliesIds = new List<int>();
foreach (FamilyInstance equip in collGenericModels)
{
ElementId symbolId = equip.Symbol.Id;
if (!genericModelsFamiliesIds.Contains(symbolId.IntegerValue))
genericModelsFamiliesIds.Add(symbolId.IntegerValue);
}
// get the active view
View3D activeView = doc.ActiveView as View3D;
if (activeView == null)
{
// the active view is required in this case
// as it will be duplicated with
message = "Please run command from a 3D View";
return Result.Failed;
}
// control copy numbers
int copy = 1;
// this list will store the views created
List<ElementId> viewIds = new List<ElementId>();
foreach (int genericModelId in genericModelsFamiliesIds)
{
// get the family
FamilySymbol famSymbol = doc.GetElement(
new ElementId(genericModelId)) as FamilySymbol;
// create the view by duplicating the active view
ElementId genericModelViewId = activeView.Duplicate(
ViewDuplicateOption.Duplicate);
// and add to the list
viewIds.Add(genericModelViewId);
// and open for further processing
View3D genericModelView = doc.GetElement(
genericModelViewId) as View3D;
// here you can adjust the view name
// according to internal rules
string viewName = string.Format("MM-{0}", famSymbol.Name);
try
{
// try apply a name
genericModelView.ViewName = viewName;
}
catch
{
// should not happen, except for
// wrong project standard
viewName = string.Format("{0} - Copy ({1})", viewName, copy);
genericModelView.ViewName = viewName;
copy++;
}
// the new view may come without the categories
// configured for generic models, so let's set all
// as Visible=false, then set GenericModel=true
foreach (Category cat in doc.Settings.Categories)
{
try { genericModelView.SetVisibility(cat, false); }
catch { /* não aplicável */}
}
Category catGenericModel = doc.Settings.Categories.
get_Item(BuiltInCategory.OST_GenericModel);
genericModelView.SetVisibility(catGenericModel, true);
// now create a new filter using the view name
// and prefixed by F_
ParameterFilterElement newFilter =
ParameterFilterElement.Create(
doc, string.Format("F_{0}", viewName),
new[] { catGenericModel.Id });
// with a rule to show only the family we filter
FilterRule rule = ParameterFilterRuleFactory.
CreateNotEqualsRule(
new ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME),
famSymbol.Name, true);
// and apply the rule
newFilter.SetRules(new[] { rule });
// last step is add the filter and set as false
// as the Rule is Not Equals
genericModelView.AddFilter(newFilter.Id);
genericModelView.SetFilterVisibility(newFilter.Id, false);
}
// finally we have all views, one for each element
// let's export it to DWG files using the view id list
DWGExportOptions options = DWGExportOptions.GetPredefinedOptions(
doc, "Standard");
doc.Export("c:\\temp_rvt\\", "GenericModels", viewIds, options);