Drilling Holes in Beams and Other Projects

I am working on a few side projects and proofs of concept for my own and other teams, so I find myself challenged finding enough time for blogging and monitoring the forum at the same time:

RvtParamDrop Exports Visible Element Properties

The first recent side project was RvtParamDrop.

It simply exports all properties of all elements visible in a selected view for comparison and verification of all expected parameter values, generating a count and a csv output file.

One interesting aspect is that all referenced elements and all their properties also need to be included, recursively.

Here is the specification in slightly more detail:

A small number of parameters can be ignored as redundant:

Include parameters from both elements and their types, i.e., both instance and type parameters.

Actually, it's more complicated than that. Anything that is visible in the view will include its instance and type parameters. If an instance or a type has a parameter that refers to another Element, its instance and type parameters are also exported, regardless of whether it is visible or not. That is recursive, so if X references Y references Z references W, then W's parameters are exported if X, Y, or Z is visible. We follow all references. Who are we to say that a referenced Element isn't useful?

I hope you find this interesting and useful.

RvtLock3r Validates BIM Element Properties

Another on-going project is still WIP, and also an exercise getting started with the Revit API for my new colleague Caroline.

RvtLock3r validates that certain specified BIM element properties have not been modified.

Here are some notes from the current state of the project repository readme:

Motivation

Revit does not provide any functionality to ensure that shared parameter values are not modified.

RvtLock3r stores a checksum for the original intended values of selected shared parameters and implements a validation function to ensure that the current values compute the same checksum.

The validation function is initially implemented as an external command.

It may later be triggered automatically on opening or saving a document to notify the user that undesired tampering has taken place.

Validation

RvtLock3r reads a set of ground truth data from some storage location. It contains a list of triples:

The add-in iterates over all elements and shared parameters specified by these triples, reads the corresponding shared parameter value, calculates its checksum and validates it by comparison with the ground truth value.

Discrepancies are logged and a report is presented to the user.

The add-in does not care what kind of elements or shared parameters are being examined. That worry is left up to whoever creates the ground truth file.

In the initial proof of concept, the triples are simply space separated in individual lines in a text file.

Preparation

There are various possible approaches to prepare the ground truth input text file, and they can be completely automated, more or less programmatically assisted, or fully manual.

In all three cases, you will first need to determine up front what elements and which shared parameters on them are to be checked. Retrieve the corresponding parameter values, compute their checksums, and save the above-mentioned triples.

Storage

The ground truth data triples containing the data required for integrity validation needs to be stored somewhere. That could be hard-wired directly into the add-in code for a specific BIM, stored in an external text file, within the RVT document, or elsewhere; it may be JSON formatted; it may be encrypted; still to be decided.

Two options are available for storing custom data directly within the RVT project file: shared parameters and extensible storage. The latter is more modern and explicitly tailored for use by applications and data that is not accessible to the end user or even Revit itself. That seems most suitable for our purpose here. Extensible storage can be added to any database element. However, it interferes least with Revit operation when placed on a dedicated DataStorage element, especially in a worksharing environment. Creation and population of a DataStorage element is demonstrated by the named GUID storage for project identification sample.

Drilling Holes in Beams

Getting back to real-life issues, Richard RPThomas108 Thomas explains how to drill a hole in a beam in a family definition using an opening by face in the Revit API discussion forum thread on how to create different unattached families to a .rft file without stacking it:

Question: I'm coding a tool to drill holes to beams (structural framing). Each beam will host 2 drills, one at each end. To create my void extrusion to cut the host, I create an Arc at the coordinate (0, 0, 0) and extrude it in my Metric Generic Model.rtf located in the C:\ProgramData\Autodesk\RVT 2020\Family Templates\English directory. Then, I load the family into the document with the beams to be drilled and get the FamilySymbol like this:

  Family family = familyTemplateDoc.LoadFamily(doc);

  FamilySymbol familySymbol = family.GetFamilySymbolIds()
    .Select(x => doc.GetElement(x) as FamilySymbol)
    .FirstOrDefault();

In my document I insert the family instance using NewFamilyInstance at the desired coordinate and finally AddInstanceVoidCut the beams. I'm facing the following issue (I moved the voids up so we can see it easily):

Stacked voids

Apparently, each time I extrude a new Arc I am stacking it (the thicker cylinder is above for visualisation, it would overwrite the thinner one). The next beam to be drilled will keep stacking the void forms. So if I select 4 beams, the 8th hole will be done by the 8 void forms stacked. What could I be doing wrong? The extrusion needs to be created at the origin so it can be easily found and modified.

Answer: This sounds like a case of wrong type of family template and wrong NewFamilyInstance overload. There are easier ways to create holes in beams:

Note also there is no need to even create a family for this, you can create an opening by face:

Response: I wanted to use voids in order to learn it; I'm new at the API and I was overcomplicating the solution. It's kinda overkill what I was trying to do...

Switched up to NewOpening and it works like a charm! Thank you.

Many thanks once again to Richard for contributing all his reliable in-depth help and experience in the forum!