Boolean operations can be great time saving procedures for constructing objects in Rhino. But, for the beginner, they seem to often mysteriously fail, and it is difficult to understand why. Hopefully this FAQ explanation will clarify things a bit. If you don't want to wade through all the following info, you can also try John Brock's short Fixing Boolean Problems.
To understand why Booleans fail, first you must understand how they work. They are not a magic tool for putting objects together. They are simply semi-automatic operations that combine several manual commands into one process. The Boolean operations basically do four things:
- Intersect two or more objects
- Split them at the found intersections
- Delete (discard) the parts not wanted
- Join everything back together
Everything you can do with Boolean operations you can also do manually by using the above four commands. Using a Boolean operation only speeds things up by making it one procedure –- when it works…
So, the first thing to keep in mind is that a solid understanding of how the component operations of Booleans work is necessary. When all else fails, you can get the job done with these commands:Intersect, Split, Delete, and Join. Try undoing a successful Boolean operation and redoing it manually using those commands. Get comfortable with the fact that this procedure will always get you where you want to go even if your Boolean attempts fail.
Boolean operation failed...
OK, why do Booleans fail? First, it is the intersection operation that will determine the success or failure of a Boolean operation. If a correct intersection is found, the rest is easy. But if Rhino has problems finding the intersection, the Boolean operation is guaranteed to fail. So the key is to help Rhino find a good and complete intersection. You can do this by setting up your model and file correctly, and also by understanding some of Rhino’s quirks and limitations.
Intersecting two closed (solid) objects should produce at least one completely closed intersection curve (i.e. a loop). It’s possible there may be more than one loop if the object intersects in multiple spots -– no problem if they’re all closed. If even one is open, however, the Boolean operation will fail. This is because the intersection curve does not completely cut through the objects. Rhino doesn’t know how to finish the cut, so it stops and gives you an error message.
Note: Doing Boolean operations on open objects is also possible, but a bit more complicated, so we’ll assume at first that all objects are closed. Open objects will be covered later.
So, taking the above into account, if your Boolean operation fails, the first thing you should do is check the intersection of the objects. Select your objects and call Intersect. First, look at each intersection curve on the screen. Does it look correct? Are there any visible gaps or extra segments or other things that look strange? If so, find out why. If the intersection looks OK, but the Boolean still fails while the intersection curve is still selected, go into Properties > Details or use the command What. The resulting info box should tell you all you need to know about the curve. Does it say the curve is open? Then thats your problem area. More than one curve? You need to find out why there are either gaps or overlaps in your intersection.
Intersection problems, solutions, and limitations
What causes gaps or problems in your intersection? There are many possibilities. Some are due to modeling errors or inaccuracies. Some are due to Rhino’s limitations. Let’s look at the common errors first:
If you think your intersection should be closed, but it’s not, select the curve, and call CrvStart, which places a point at the start of the curve. Normally this will correspond with one side of the gap.Zoom in closely and see if you can see the gap on the screen. Why is there a gap there? Maybe you think that your objects are closed, but they’re really not. The intersection may cross a gap between surfaces, and that will cause an open curve. If you have forced together your object usingJoinEdge, that may also happen, even though the object says closed. The other thing to check is your modeling tolerances (see Understanding Tolerances). If they are too large, this may prevent the intersector function from finding a complete intersection, even though all else is well. Try tightening your tolerances and running the Boolean again. Once you get a full closed intersection, your operation should work…
If you can’t get Rhino to automatically produce a closed intersection curve, even after you have fixed your object the best you can, it may be time to go back to manual. Get the best intersection curve you can and try editing it until you have a closed object. You may need to add or change a segment, do some point editing, take out overlapping segments, or something like that. Once you have this curve, you can try trimming your objects individually. You need to explode your polysurfaces to trim with the intersection curve. Trim out the parts you don’t want and join all back up.
Known Rhino limitations
Coincident seams – All objects have seams. Sometimes when the seams on two objects are at exactly the same place, Rhino has trouble with the intersection. Solution: Either try to move the seam, or try moving one object just a tiny, tiny bit (if you can without making your model inaccurate). Or try to do the operation manually.
Coplanar faces /color – If two faces of an object are on the same plane, Rhino may not be able to calculate the intersection. This is a fairly common occurrence. Avoid building your model this way if you can. Solution: As above, you may move the object slightly if possible. If not, you may have to do this operation manually.
Nearly tangent surfaces – Like the intersection of two equal diameter pipes at an angle. The intersection often fails at the point where the surfaces are tangent. Currently, there is no easy fix for this problem.
Invalid objects – If one of the objects you're trying to work with is invalid, Boolean operations will often fail. Check for invalid objects by using the command SelBadObjects. If one highlights, you need to fix it first before proceeding. It is also recommended that you turn on automatic object checking. If invalid objects are created in the course of your work (or imported), Rhino will tell you immediately. To do this, simply type CheckNewObjects. This is a toggle, running the command again turns it off.
Non-manifold polysurfaces – Although Rhino doesn't currently flag these objects as bad, they can cause failure. Rhino shouldn't create these types of structures, but under certain conditions it does, especially with V4. The only way to find them currently is to check the properties of the object.
Boolean operations on open objects
As mentioned above, Boolean operations can also be performed on open objects. The principle is the same, but since the objects are not closed, we have a couple of extra things to do and understand. Rhino V4 and later provides a tool that makes the following procedure much easier if you have only two objects. See the command: Boolean2Objects
First, it is necessary to understand the concept of surface normals and direction. Every surface object has a “sided-ness”, that is, a front side and a backside. This is called the direction in Rhino and can be shown with the Dir command. Try using Dir on several different surfaces and see what happens. The direction arrows point to the outside of the surface, and they also show the local normal direction, i.e. they are at 90º to the surface locally.
For each surface, you can flip the direction of the normals (i.e. invert the sided-ness of the surface. To do this, while you're in the Dir command, you either type F and enter, or just click once on the surface. You will see the direction arrows flip sides. You can also do this outside the Dir command by using the command Flip (you will not see any arrows, though).
Note: Curves in Rhino also have a direction which can be shown by the Dir command. In this case, Flipexchanges the start and end points and reverses the curve direction.
When surfaces are joined, Rhino tries to standardize the surface normals of the object. That is, it tries to keep all adjacent surfaces having the same front/back orientation. So when you have an open set of joined surfaces (an open polysurface), it will still have one uniform front/back and not be a patchwork quilt of surfaces facing in different directions.
Experiment 1: Make a square. Extrude it into a 4-sided open box. Explode it into separate surfaces. Using Dir, flip two of the surfaces' directions to the inside. Now window select them all and use Join to make them into a 4-sided polysurface again and use Dir again to see what happened to the surface directions.
When an object is closed in Rhino, the program automatically flips all the surfaces to the outside. It assumes we don't care about the inside anymore, because the object is closed (solid). Closed polysurfaces cannot have their normals facing inside (try to see if you can with Dir). If you do manage to flip the normals of a closed polysurface to the inside, either it isn't really closed, or, you have discovered a (very rare) bug.
Experiment 2: Make a cube. Explode it into separate surfaces. Using Dir, flip a few of the surfaces' directions to the inside. Now window select them all and use Join to make them into a polysurface again, and see what happens to the surface directions.
How surface direction affects Boolean operations
OK, now you understand surface normals and direction. Why is this important in Boolean operations? When Rhino is instructed to perform a Boolean operation, it looks at the surface normals to determine which parts to keep and which parts to throw away. Essentially, Boolean Union, Difference, and Intersection are all the same operation. Just different parts of the objects are kept at the end. With Boolean Union, for example, the parts that overlap are thrown away and the rest joined together. With Intersect, it is exactly the opposite.
Booleans with solids (closed polysurfaces) are predictable, because all surface normals always point to the outside. But with open polysurfaces the results can seem unpredictable, as we don't immediately know which is the front or back of each object without using the command Dir.
Note: If you are doing Boolean operations on closed polysurfaces and they don't react the way you think they should (i.e. the wrong parts disappear), probably one or more of your objects aren't really closed and have the normals pointing inward. Use Dir to see.
Tip: One way to always know which way surfaces are facing is to set up your display to show backfaces in a different color from front faces. In V5, it's Options>View>Display Modes>Shaded>Backface Settings. Then choose Set single color for all backfaces, and choose a color. Note, this only works if you are working in Shaded Viewport mode. In Wireframe, Ghosted, or Rendered you will not see this.
Let's imagine the simplest open Boolean operation. You have one solid closed polysurface that is fully intersected by a single surface. You can easily create this by making any kind of solid object, then using the CutPlane command and drawing a cut line through your object in any direction.
Now, try BooleanDifference (BD). Select the solid as the first set and the cut plane as the second. One side or the other of the solid will be cut off and the hole filled by the plane. But which side???
You can't know unless you call Dir on the surface. Look at the direction of the surface normal. Then do your difference. Undo, flip the direction of the surface using Dir , then try the difference again. The direction of the surface normal of the plane determines which piece gets left.
In general, if you want to BD between an open (poly) surface and a solid to work as if it was two solids, the surface normals of the open object should point towards the solid object, as if it were also a solid.
What to do if fillets fail?
The two primary commands for filleting surfaces in Rhino are:
- Creates a tangent surface between multiple polysurface edges (joined) with optional varying radius. values, trims the original faces, and joins the resulting surfaces together.
- Is not limited to just two surfaces.
- Can fill in corners between adjacent fillets.
- Is limited to exactly three surfaces meeting at a point. (V4 only. V5 handles multiple surfaces at a single point.)
- The radiuses used can not be so large that they overlap each other and completely consume any surface they are following.
- Creates a tangent surface between two surface edges (joined or not) with a constant radius, and optionally trims and extends the original surfaces.
- Works on exactly two surfaces at a time
- Does not fill in corners between adjacent fillets
Why is my object not closed? How do I get a solid model?
There has been quite a lot of good help offered in the production of STL files. The most important is simply this:
The Rhino object must be a closed solid before a valid STL file can be generated.
A solid has no naked edges. That's a concise definition. Another way to understand a solid is to see it as a balloon. If there is even a pin prick size hole, it will deflate. Thus it is not air/watertight, not volumetric. A solid is a volume. A solid is its outer surfaces, once they are completely joined.
The term “solids” seems to confuse a lot of people and there are often discussions about it, in particular with relation to getting watertight solids for rapid prototyping. Some people worry that if you slice a solid in Rhino, you do not get surface planes or salami slices, but just an outer boundary curve at each slice. This is normal. The rapid prototyping software/machine fills these slices in for you. Also remember, that it is not the Rhino NURBS object that is being sliced by the rapid prototyping process, but a mesh in the form of your object, via an STL file. And guess what? Meshes are no more solid than Rhino NURBS objects… When you slice them, you still get just boundary curves.
Tolerances play a role in creating closed volumes
An understanding of absolute tolerance is required so that valid solids are generated. A good rule to follow is change the absolute tolerance from the default value of .01 to .0001 or .001. I start out all my jewelry size projects at .0001, then I have room to loosen the tolerance if necessary.
Keeping stuff lined up
Using snaps and object snaps is extremely helpful, possibly essential to get edges to join up.
Info on your object
Analyzing a Rhino object is an important part of the process. I find that the quickest way to check whether an object is a solid (closed polysurface) is to click on the details button in Properties. I leave this open and docked on the right side of the screen, with the Layers panel docked right beneath it.
Get solid advice
Post the objects you have trouble joining to the Rhino Newsgroup. You will get it if you keep trying. Just look for the naked edges and zoom way in on them. You will see what is not joined. Experience and practice bring understanding. It's basic stuff. Just keep modeling with an eye to producing solids from the beginning, and not as an afterthought.
Once you have a valid solid, export it as an STL file. If you use the default 0.01 for the Maximum Distance, Edge to Surface, the stl file will be just fine for any machine currently out there. You can test your STL by reading it back into Rhino and doing ShowEdges with the Naked Edges option. Creating a valid solid to export from is the tricky part. That's what you need to be working on. There's no mystery here for producing stl files. They are nothing more than a mesh made up of triangles.
Other tips for getting valid solids
Join as you go
Join parts and check your work as you model. Use the ShowEdges>Naked Edges command. If you catch some you need to go back and figure out why they happened and correct the problem. It's a lot easier to correct as you go rather than try to fix things after you're all done modeling. Some late corrections may cost you hours of work at the end when they would have only been a few minutes to fix earlier on.
Things that may cause naked edges
Watch out for the way you trim surfaces. Rhino will trim surfaces with curves according to the active CPlane, and those curves don’t necessarily have to lie on the surface. The trim edge may then not be exactly where you think it is and this may not show up in an orthographic view. It’s best to trim surfaces with the other surfaces you're joining them to if it’s possible. Sometimes this may not work, and if you are forced to trim with curves, make sure the surfaces do join up afterward.
Rebuilding surfaces. This may cause the edges to change enough to be too far away to join, so be very careful here.
The act of joining itself may cause naked edges. Paradoxical but true. At certain areas where there are complex multisurface joins (usually done by window selecting many surfaces and running Join), Rhino may occasionally produce naked edges where none should be. In this case, you need to undo your join and go in and see what happens if you try to join one by one instead of all at once. In stubborn cases, you may need to slightly adjust one or more of the surfaces to be joined.
The JoinEdge crutch
This command allows you to force edges together that are too far apart to join normally. Use this command sparingly and with discretion. It does not make your model more accurate and it does not correct your geometry. It simply allows Rhino to override the absolute tolerances at that point and create an average edge somewhere between the two real edges. In doing so, the meshing commands can bridge the gap to create a watertight mesh object, and your .stl service bureau might be happier. If it is being exported as a surface or solid format for downstream engineering, however, it may all come apart later, so JoinEdge is best avoided in these cases.
The RebuildEdges command
This command will reset the edges of surfaces to (more or less) the way they were originally before joining. This may be important, as when edges are forced out of alignment by JoinEdge or something similar, they can be restored.
The dreaded one naked edge
If you get this, you have a problem. Usually naked edges are in pairs. You can often join the pairs with JoinEdge (even though the joins are thus out of tolerance, the seam will be closed). But if you have only one naked edge, there is nothing to join to. In this case, there's a bit of work ahead of you. You will often need to unjoin all the edges around the problem area, RebuildEdges on all, and see what's misaligned and correct it. Often you need to zoom way in to see what's going on.
Make sure it's valid!
Make sure you've got a valid object. When you go in and start editing edges, you can often cause the object to go invalid (even though it’s closed.) This may cause problems with meshing as well as more modeling down the line. My suggestion is to turn on CheckNewObjects in Rhino and leave it on. That way, if you do create an invalid object by editing, you'll know it immediately.
What do all those numbers mean? How should I set them in Rhino?
The subject of file tolerances frequently comes up in new user questions. Many modeling programs don't allow you to set your tolerances. They are determined for you whether you like it or not. Rhino gives you the advantage of letting you set your own tolerances according to your needs, but it takes a bit of experience and understanding to set them correctly.
1: Understanding tolerances
Tolerance is simply a way of stating how much precision you need, or conversely, how much error you are willing to accept in your project. Nothing is 100% accurate or perfect. Different projects and sizes of objects will have widely varying needs for accuracy. You wouldn't build a building to the same level of micron precision as a Swiss watch, and the inverse would be equally ridiculous (that is to say impossible).
Engineering methods for specifying tolerances are precise and involved. We will not go into that kind of detail here. We are simply a guide to set up your projects for modeling in Rhino. Depending on which template you choose currently, Rhino sets your absolute tolerances at 0.01 or 0.001 units (whatever units you are using, inches, mm, meters, etc.). You can also create your own templates with other tolerances. But what does absolute tolerance mean, really?
2: Absolute tolerance settings in Rhino
In Rhino's terms, the absolute tolerance setting dictates the greatest permissible distance apart that two objects or elements can be and still considered close enough. Close enough means that two surfaces or curves are capable of being joined or that an approximate operation like a sweep will generate a surface whose edges follow the rails to within the specified absolute tolerance.
What is an approximate operation?
Some objects are possible to define mathematically perfect to the limits of what your computer's floating point math is able to calculate. Generally, you don't need to worry about extremely tiny tolerances. Yet, some commands rely on approximations to fit or match curves or surfaces to other curves or surfaces. The more exact solution you need, the more time it takes to calculate, even to the point of locking up your computer. The absolute tolerance tells Rhino at what point you think it's good enough and to stop trying to calculate a closer solution.
Another downside of specifying a higher than needed absolute tolerance is that Rhino will then generate things like sections or intersections with many, many control points. Control points which are heavier (bigger data size), noisier (not as smooth), and harder to edit.
Which operations are approximate?
Any command necessary to find the intersection between curves and surfaces is an example. Specific commands include (but are not limited to): Trim, Split, Intersect, Contour, Section, Offset (curves and surfaces) Project, Sweep 1 and 2 Rails, all the Boolean operations, FilletSrf, FilletEdge.
So, why don't I just model with loose tolerances?
The advantage of a looser (larger) tolerance is that computing time and data size may be reduced, but at the expense of your model's accuracy. This is precisely why you need some experience to set your tolerances. It is always necessary to find a good compromise.
For example, the Intersect command creates a curve at the intersection of two surfaces. The curve is guaranteed to lie, within the absolute tolerance, on each of the two surfaces.
Try the Intersect command and save the resulting curve off to one side. Then add a zero to the tolerance setting and run Intersect again. Now turn on the control points for both curves. The second curve will have more control points, will be heavier, and will stay closer to the two surfaces. Is one curve better than the other? It depends on your needs. If your manufacturing process can't benefit from the more closely fitting part, then the first lighter curve is better since it results in a smaller file, faster calculations, and better parameterized surfaces.
Different objects and scales may require widely differing tolerances. For example, if you are designing the general form for a car body (which might have important details in the 1.0 mm range) a file tolerance of 0.1 mm might be good enough. But for smaller details on that same car, even 0.01 mm may not be enough, and the inner workings of the motor will certainly need a file tolerance of 0.001 or even 0.0001 in the case of bearing surfaces.
Another rule of thumb: Use a tolerance setting equal to or one order of magnitude tighter than (1/10 of) the best tolerance you can hold through your manufacturing process – or one order of magnitude tighter than your smallest modeled detail, whichever is smaller.
Overriding or making custom tolerances
Some commands may let you individually specify the tolerance for that particular operation as in NetworkSrf or MatchSrf. You will have a dialog box with tolerance options you can set within the command, overriding the general tolerance. Using the Refit option also allows you to specify your own tolerance within certain commands.
And last, there are commands like JoinEdge that let you exceed the absolute tolerances locally if you think it might be useful. Use this with caution!! You are deliberately saying it's OK to be inaccurate here!
3: Angular and relative tolerances in Rhino
There are two other tolerance settings in Rhino: angular and relative. The relative tolerance is used on few commands and can generally be left alone. The angular tolerance is important in that it tells Rhino at what point you want two curves or surfaces to be considered tangent. The default setting of 1 degree is rather large for fine modeling. Surfaces that are 1 degree out of tangency can still show a visible fold or line. I find a setting of 0.1 degree or even finer to be better.
4: How tolerances can affect your project and workflow
An important thing to note is that tolerances should be set at the beginning of the modeling process, for, although you can change the tolerances while you work, objects which were previously modeled with lower tolerances will not be fixed if you raise them. A good practice is to continuously check your work by joining up elements as you create them. If they join, you're within your tolerance limits. If they don't, you need to go back and find out why and correct the situation immediately. This avoids ending up with a finished model with problem areas or inaccuracies which may be hard to fix at that late stage without completely rebuilding certain sections.
Operations that involve the intersecting function, such as Intersect, Split or the Boolean operations, can also be quite sensitive to tolerance settings. Often, if the absolute tolerance is set too low, complete intersections may not be found. Splitting or Boolean operations may fail as a result. (Note that tolerances are not the only reason for these operations to fail.) Too tight a tolerance setting may also be harmful. Besides creating overly long calculation times, Rhino may even crash. In general you should keep the absolute tolerance setting in the range of 0.01 to 0.0001. And never set it below 1.0e-5. If you need a tighter tolerance, use smaller units instead.
5: Exporting to other (downstream) programs
If you are going to export objects to another downstream application (such as CAM software or a solid modeler), it is important to take into account the precision that these programs require for imports to be successful. Experience is the only guide here. When in doubt, ask on the Rhino support newsgroup. Someone who has had the experience can give you guidelines. In general, MCAD applications seem to appreciate higher precision objects, so if that's your target, error on the more precise side if possible! Your entire modeling process from start to finish needs to be done at this level of precision to be successful with your export.