Making Lines Not Print (with Events)

A recurring question that has come up at least twice at AUGI (here and here) and many other times over the years has been how to put things in your Revit model that will not print. There were good reasons in the early days of Revit that we had a strong commitment to WYSIWYP (What You See Is What You Print) and there are also good reasons why Revit users do not want to print everything that they see in Revit. These “hide” options in the Print dialog are good, but often you will want to go beyond this.

printhide

Two API functions to the rescue!

  1. The ability to modify line colors defined in Object Styles and Line Styles
  2. Events, which let you run API commands before and after various file actions such as open, close, save, print

In this example, a Revit model contains two annotation families where the lines are assigned to a subcategory named “Do Not Print”

family

For this application, use two events:

  1. DocumentPrinting – runs API code just before Revit prints
  2. DocumentPrinted – runs API code just after Revit prints

Before Revit prints, the myPrintingEvent will change this subcategory’s line color to white.
After Revit prints, the myPrintedEvent will change this subcategory’s line color to black.

objectstyle

To enable the magic, run the macro PrintingEventRegister. This associates a function with each of the two print events mentioned above.

public void PrintingEventRegister()
{
    // myPrintingEvent will run just BEFORE Revit prints
    this.Application.DocumentPrinting += new EventHandler<DocumentPrintingEventArgs>(myPrintingEvent);

    // myPrintedEvent will run just AFTER Revit prints
    this.Application.DocumentPrinted += new EventHandler<DocumentPrintedEventArgs>(myPrintedEvent);
}

// These macro is private, instead of public, because it will not be run from the Macros dialog
// It will only be available to other macros
private void myPrintingEvent(object sender, DocumentPrintingEventArgs args)
{
    // set color to white (255, 255, 255)
    CategoryLineColor(new Color(Byte.MaxValue,Byte.MaxValue,Byte.MaxValue));
}

private void myPrintedEvent(object sender, DocumentPrintedEventArgs args)
{
    // set color to black (0, 0, 0)
    CategoryLineColor(new Color(Byte.MinValue,Byte.MinValue,Byte.MinValue));
}

The results of printing are shown in the PDF on the right side of this screenshot. The lines in the families are “invisible” because they are white! After the printing is completed they are set back to be black.

print

And here is the code for the CategoryLineColor function that sets the line color.

private void CategoryLineColor(Color newColor)
{
    Document doc = this.ActiveUIDocument.Document;

    // Get all categories in the document
    Categories categories = doc.Settings.Categories;

    // The "Generic Annotations" category
    Category genericAnnotations = categories.get_Item("Generic Annotations");

    // The ""Do Not Print" subcategory of the "Generic Annotations" category
    Category doNotPrint = genericAnnotations.SubCategories.get_Item("Do Not Print");

    // Create transaction, with the value of the color (0 or 255) in the transaction name
    using (Transaction t = new Transaction(doc,"Do Not Print color = " + newColor.Blue))
    {            
        t.Start();
        // set the style's line color to the "newColor"
        doNotPrint.LineColor = newColor;                
        t.Commit();
    }            
}

16 thoughts on “Making Lines Not Print (with Events)

  1. Oh yeah, great post! now THAT is what the Revit API was built to do! I have been avoiding creating this add-in in my own office because I didn’t want my users to get use to having a “non-plot” layer (like AutoCAD) but seriously I don’t see too much harm in it (and I would be a hero of sorts!)

  2. One last note, you might want to change the line color to (254,254,254) because white lines will typically default to “black” when you print them.

  3. This is awesome. I have a use right away for this, except its a bit different. I have a generic annotation which includes text and labels that needs to be hidden when printed. Unfortunately, Revit doesn’t allow putting text and labels on a sub-category. Is it possible to select all instances of the family and override the color of the text and labels to white instead? How about the leaders also?

    • Hi Troy – Glad you like it. What you are trying to do seems a bit more involved. Unlike a line’s subcategory, the family’s text style is not inherited by the project. We can still use Events but inside the event we would need to edit the family and hide/unhide the text. I’d be happy to discuss developing this for you if you’d like.

      • Currently the process I use for this is a yes/no type parameter linked to the text/label visibility parameter. This requires someone to go into the type properties of the family, uncheck the parameter before printing and then reverse the process after printing. I suppose its possible for me to modify the parameter value using the print event handler instead of changing the text color. I’ll give it a try and let you know.

      • I’m wondering if you couldn’t create coding to do what you’re suggesting; uncheck the parameter of a particular family before printing. You’d probably have to explicitly say which family you’re adjusting the property (yes/no) to within the coding. Sounds feasable, but then again, I’m a novice with the coding and API.

  4. That all works great if the background is in fact white. What happens if you have the same situation you were showing above with a floor tile pattern? You’d see the white line. I’d say a good number of situations this works well. However, I can think of a handful that it wouldn’t. Tell me, if you’re able, are we not able to access the system line style ? I guess in the code you’ve presented here, you’re not changing the line style. You’re simply changing a property of the line style. Too bad you aren’t able to adjust the transparency of object styles within the main category. I could see that as a possible attempt to make a line style completly transparent, solving the situation I mentioned above…

  5. Adding a ‘no-print’ parameter to any item in Revit must be programmatically possible, right? And everyone wants it, right? So why does autodesk continually NOT provide what all the paying customers want? I completely hate this compnay and their products either because they won’t do something so basic, of because they are too stupid to do so. I’ve also assembled a list of an additional 135 BASIC items that autodesk refuses to add to revit, but that’s only because I got sick of listing them.

  6. User be warned – an issue with this method is that if any of these lines cross another printable line it’ll essentially mask-out the printable line…

Leave a comment