Back

Trial, Error, Success

Not too long ago, I worked for a 3D laser scanning company that used laser scanners to capture point cloud data and then used that data to create 3D As-Built models.  These models needed to be extremely accurate that matched the point cloud—down to millimeters at times.  The company I worked for was just budding into the Autodesk® Revit® world, and we soon realized that modeling imperfect, non-level, non-plumb objects in Revit was quite a struggle.  Revit likes things to be neat, square and orderly, so matching size, shape, and position of real-world objects, and doing it efficiently, can be tremendously challenging.

Many of our clients required us to model the exact points of connection to valves and piping.  The valves had to match the size and shape exactly, even down to the valve handle size and position.  I scoured the Revit Family Library and the Internet and found some decent valves, but none of them were quite what I needed.  For our specific application, we needed something custom; as I was the person with the most Revit family building experience, the task of creating custom families for our users fell to me. I used what I learned from looking into other valve families as a rough starting point, and though trial and error ended up with an efficient and useful valve family that met our needs.

My initial instinct was to create a fully customizable, parametric valve family. Users could simply modify the parameters to adjust the valve’s size and shape.  It had instance parameters for controlling the valve’s geometry, including valve length, valve stem height, and valve handle diameter that were to be input by the user. 

For the main valve body, I made a cylindrical extrusion and set its radius equal to a parameter called pipe connector radius.  I then added pipe connector elements onto each side of the valve body extrusion, and set their radii to be equal to the pipe connector radius parameter as well. 

This valve ended up not working for us, because every time it was placed it had to be completely adjusted manually to make it look even remotely natural.  A good start, but not quite what we needed.

In my next version, I decided to try to make the valve automatically adjust its sizing and proportions based on the size of pipe on which it was placed.  For the main valve body, I wanted it to behave similar to the way a Revit pipe elbow behaves as it sizes its outer diameter to automatically match the pipe diameter.

There are a few different ways to automatically size things, but I chose to stay along the lines of how Revit sizes them—with lookup tables.  I created my own lookup table that was based on an existing Revit lookup table, but with a few tweaks to suit our specific needs.  For me to get this idea to work, I had to change how I thought about those pipe connector elements and the pipe connector radius parameter.  Instead of the user dictating the pipe connector radius parameter value, I wanted the pipe connector to dictate the value.  I essentially reversed the pipe connector radius parameter from being a receiver of information input by the user, to a sender of information, automatically inherited from the pipe on which it was placed.  When the valve is placed onto a pipe, the size of the pipe would change the size of the pipe connector element automatically. It would drive the pipe connector radius parameter that was pushed through the lookup table and then drive the size of the valve’s geometry. 

Now that I was using the pipe connector radius parameter as a reporting parameter, I used a parameter called valve outside diameter to take the place of the pipe connector radius parameter and control the geometry of the valve’s body.  To do this I edited the valve body extrusion, removed the pipe connector radius parameter and added the valve outside diameter parameter to control it.

I realized through experimenting with valves and pipe system types, that, as in the field, the pipes were rarely actually the nominal diameter that they claimed to be; i.e., a 2” pipe does not actually have a 2” outside diameter.  The actual outside diameter of a pipe is usually a bit larger than the nominal diameter, and I needed to get the valve body’s outside diameter to match with the pipe’s outside diameter so it would display correctly and size according to the Revit pipe system families.  To ease the strain of converting parameters back and forth from radius to diameter, and to act a stepping stone from the pipe connector radius parameter to the lookup table formulas, I created a parameter called nominal diameter, and set it equal to pipe connector radius * 2.

This is the parameter that I would use in the lookup tables and their formulas.  Valve outside diameter was being driven by this lookup table formula, and it ended up being the parameter that I used as a basis to size the valve’s geometry parameters’ formulas.  So the information was being passed from the pipe connector element to pipe connector radius, then converted to nominal diameter, then run through the lookup table formula to drive the valve outside diameter parameter.

Below you can see the general breakdown of these parameters.  For the formula for valve outside diameter, I mimicked a Revit formula that it uses for pipe elbows, which is pretty standard.  For the lookup table, I used my custom table with my additions, and for the other ancillary geometry of the valve, I multiplied nominal diameter times a factor to get them to look appropriately sized and proportioned.

I wish that I could say that I scientifically came up with the factor numbers, but in reality I completely made them up.  I refined the numbers to be just right through trial and error by flexing the valve’s size in the family environment from the smallest to the largest size, and making sure that the valve always looked proportional and correct.

Now that I had this valve that auto-adjusted when you placed it, I felt pretty good.  But I could no longer manually change the valve when I needed to.  Ideally, I wanted the valve to auto-size when placed, then if needed the user could manually tweak the size of the valve handle, etc. 

Enter the If-Then formula!  After thinking about it for a while, I realized that the only way to get the valve to behave in that way was to cleverly use an If-Then formula.  To keep my precious existing formulas intact and have them be adjustable, I had to implement placeholder parameters.  I created three instance parameters for this:  Valve Length User Input, Stem Height User Input, and Handle Radius User Input. 

Next, to make the switch between auto-adjust and manual adjust, I created two Yes/No instance parameters:  Valve Length Is Adjustable, and Valve Handle Is Adjustable.

The If-Then formulas basically say:  If the Adjustable checkbox is checked, then use the user-inputted value; if not, then use the original auto-sized value.  This combination worked beautifully.  The user could place the valve, have it auto-size to get it close, then the user could check the Adjustable checkbox and tweak the size as needed. 

To further aid in the ease of manual adjustment, I added some reference planes and dimensions, setting the dimensions equal to the three user input parameters.  This made grips show up when in a project, so the user could graphically drag the grip to size the user input parameters instead of repeatedly inputting numerical values to try to match the point cloud.

For additional flexibility of the valve family, I wanted to make it rotate along the pipe.  As it sat, the user could rotate it in 90-degree increments by clicking the small rotate icon when the valve is selected, but I wanted more.  I wanted it to be rotated in any direction, at any angle.  To achieve this, I nested this family into a second family.

I learned the hard way that you must have the original family modeled as a face-based family for this to work.  After remodeling the entire original family, I had a family that was prepared to be nested into the final fully rotatable family.  I first set up a jig that would rotate my nested family.  I created a reference line and locked the endpoint to both axis of the origin.  Then I put an angular dimension from the X axis to the reference line and assigned it to a parameter valve rotation.  Next, I loaded the nested family into the host family and I hosted it to my reference line rotation jig.

To get the valve’s geometry to size, I simply created the necessary parameters and linked them with the nested family’s parameters.  I also added pipe connector elements and set their radii equal to the newly created pipe connector radius parameter.

Again, to ease in the manual adjustment of the valve handle, stem height, and so on, I created some reference planes to make the grips appear when in a project environment.

With this combination, I had finally reached my goal.  I had a family that had the best of both worlds:  It would auto-size when users needed it to, and also be adjustable if users needed that.  I was able to meet the niche needs of our company and make life easier and more efficient for the users.

Kyle Schicker is an electrical BIM/CAD technician with The Schemmer Associates.  He has more than 15 years of experience with AutoCAD and more than 5 years of experience with Revit.  With work experience in architectural, structural, mechanical, and electrical disciplines, Kyle has a unique versatility with multidisciplinary practices.  Serving on Schemmer’s CAD Committee, he helps improve the BIM and CAD workflow by creatively collaborating with the BIM Manager and other disciplines.  He loves pushing the limits of Revit, and building advanced and complex families.  In his spare time Kyle enjoys mountain biking, playing guitar, and tinkering with 3DS Max to create realistic renderings.

Appears in these Categories

Back