Anyone who has ever visited a gymnasium for any purpose other than a basketball game has probably noticed the backstops stored up and out of the way. It’s funny… when they are down in the playing position, one doesn’t even think about it. But fold them up into an unnatural position, and you can spot the few mechanical types in the crowd—staring up at the ceiling, tracing the cable from pulley to pulley, taking note of the bends and twists, and eventually finding the winch somewhere in the maze. The looks on their faces begin as uncertainty, but slowly give way to understanding. They have figured it out, and can now concentrate on other matters. Admit it—you know who you are!
Among other things, my company manufactures such backstops, which get bid on before and during the construction phase. At this point, I should back up and state for the record that we use Autodesk Inventor®. Part of the bid process requires submittal drawings, and the program I’d like to highlight in this article arose out of a need for a “tool,” or program, which would automate some rather monotonous tasks in Inventor.
One such program is what we lovingly refer to as the Cable Routine. It allows the CAD designer to sit back and watch while it creates, on the fly, a new part (a cable) within the context of the backstop assembly. For the most part, once launched, the program runs by itself, pausing only to inform the user that it has finished. Only when a cable has to veer off in some strange direction will the user be asked to point the way—the redirection will come in the form of a click here or there on the next pulley or winch.
The Cable Routine started out in life as a VBA program. A click on a custom toolbar button loaded the program and executed the main macro. When finished, it unloaded itself. But because of the uncertainty of VBA’s future, we moved all our VBA code to “dot net.” In its current form, this program is an Inventor add-in, created in VB.net, compiled, and available for use on a custom tab on the ribbon.
Creating a part in place is an adventure. If that part is a cable that wraps around several pulleys, it gets downright scary. Rather than bore you with line after line of code, I thought the best thing to get the point across would be to outline the steps taken to get from start to finish. You can then tailor the steps to your own needs.
To find a starting point, let’s look at the process in reverse, starting with the desired result and working backwards. The goal is to create another component, a cable in this case, which runs from a winch, around some pulleys, and finally gets anchored in some fashion. The cable will be the result of sweeping a round profile along a path. The path will be created by connecting the dots on a sketch, the dots being points within critical components we find in our assembly and project onto the sketch. Our winch has a pre-defined WorkPoint for use as the cable starting point. Most of the other points are center points of pulleys or chain links which have also been projected onto the sketch. A couple of our points have to have their locations calculated and created in mid-air, but that’s just due to the nature of our product. One of the things I like about programs such as Inventor is the fact that it is “smart”—an assembly knows what’s in itself. So, after some basic housekeeping chores, the first order of business is to take inventory of the relevant components.
Now, you could loop through all the components in the assembly each time you needed to find a specific part, but that just seems inefficient to me, so I like to loop just one time and sort them out as I go, in a subroutine I like to call “SearchAndDestroy”. It does several things at once as it looks over each component occurrence. It will take note of the relevant components as it finds them and assign them to a variable. I make use of classes for the important items, so I have a Pulley class, a Winch class, a ChainLink class, and so on. These will be properties of the parent Backstop class. Each class will have an Occurrence property that gets assigned to the actual component occurrence. For some items, such as pulleys, I’ll also drill down to find the center point (this assumes the part was created with the Center Point at the center; otherwise, you can go into a part’s mass properties and get its Center of Mass point) and create a property for its proxy. (Proxies: get to know and love them!)
SearchAndDestroy( ) will also find and delete an existing cable. I found this to be a must if I were to re-run the routine on an assembly. Another benefit of this subroutine is that it will find a component that is unique to a specific model of backstop. Knowing the model comes in handy later for us. It might be for you, too.
As stated earlier, the goal is to create a new part. At this point in the program, the new part has to be inserted into the assembly as an empty part template. Its PartComponentDefinition can then be referenced for later use in building the part.
The pulleys in our backstop assemblies do not appear in the top-level of the browser. Instead, they’re buried, sometimes nested three or four levels deep inside sub-assemblies and weldments. It’s like looking for a needle in a haystack. How do you find these? The answer is: recursion! FindOccurrence is one of the hardest-working subroutines I have. There are variations of this theme out there if you look, but it basically goes like this: Give it the name (or portion of the name) of the component for which you’re searching, the top-level assembly being searched, a Boolean flag to indicate when the item has been found, and an empty variable to hold the result. Here is my version:
Once the major components have been identified and the relevant WorkPoints harvested, the next step is to convert the WorkPoints into SketchPoints (either 2D or 3D), and project them onto a sketch. If all your points lie within a plane, you can get by with a planar sketch, which has its advantages, but it’s possible that you’ll need a 3D sketch. Our backstops and their cables are such that the vast majority of the cables can be created with a planar sketch. However, there are occasions when the winch will be located off to the side and a 3D sketch will be required, at least for the portion that zigzags through extra pulleys.
The code gets routed through a function, DetermineIf3D, which compares some relevant planes to see whether or not they are coplanar, and then returns either true or false.
If the cable is found to require a 3D portion, it means I have to show it where the extra pulleys and winch are located. The subroutine SelectPulleys returns a collection or list of component occurrences. It loops through a selection process, which filters out all but those few part numbers recognized as either pulleys or winches. The user is prompted to pick the pulleys in order, ending with the winch. Once it sees the winch, the loop is exited and the collection is returned. The relevant points are harvested from these component occurrences in the list, converted into SketchPoints3D, and projected onto the sketch. Simple!
Once all the sketch points are in place, connect the dots with an array of SketchLines…
Planar sketches are nice in that the two SketchLines that meet at a SketchPoint can be sent off to a subroutine to RoundTheCorners.
Given the desired radius and a few other parameters, a SketchArc can be inserted, and its resulting center relocated to the original vertex. This will make the eventual cable look like it’s conforming to the pulley, as illustrated below.
3D Sketches, with their properties and methods, do not allow this technique. While it is possible to fillet the corners, the fillet’s center information is “Read Only” and cannot be relocated to the original vertex like their 2D counterparts (at least that I have found). Left with the choice, I have opted to leave them alone, so the resulting corners require a bit more imagination on the part of the observer. Even if the corners could be rounded and the resulting fillet moved to look like it wrapped around the pulley, the challenge of orienting the pulley to look like it is being pulled in the correct direction is still there. In my example, the pulley and chain are a pre-built subassembly and can’t be manipulated, except to spin it around the mounting tube. Like a lot of things, the further away you get, the better it looks!
Once the SketchLine is complete, it is used to create the path:
We next have to focus on the cable’s cross section. Once again working backwards, it will require a sketch, which will require creating a WorkPlane, normal to the path at its endpoint.
Define a new WorkPlane at the endpoint. Then, use the SetByNormalToCurve method to re-orient this new WorkPlane:
Then, create the circle, profile, and sweep:
In case you need to know the length of your new cable, try this as a property in your Cable class:
Obviously, I have left out a lot of code in my program, but hopefully, you get enough of the idea to take the ball and run with it. The sample code included with Inventor’s Help is a great resource for finding a lot of the missing pieces.