OCTOBER 11, 2019

If you want to add the cs files from one Visual Studio solution (or project) into another, without duplicating the cs files or moving them over, you can simply use the Add > Existing file.. option, making sure that instead of selecting the files and clicking Add (which would copy the files over to your project folder duplicating them) you click on the small arrow and click Add As Link. The files will be linked to your project as a reference to the other project, and editing them will change their code for both Visual Studio projects.

SEPTEMBER 5, 2019

Revit allows you to import PDF and image files from its Ribbon menu. After clicking either button (Import PDF or Import Image) you get the same window, really, just with a different extension pre-selected.

You import a file and place it into a view, and if the file happens to be a PDF file you select a page and a rasterization resolution (in DPI).

Internally, Revit uses the PDFNet library made by PDFTron to manipulate PDF files. One of the operations it seems to use it for is to rasterize the contents of a PDF to be able to display it on a view. This process makes the image data (of the image itself or a rasterized PDF) available inside of Revit. By using the Revit Lookup add-in, I found that the ImageType class offers a GetImage() method which returns a Bitmap object containing that image data.


Remember that, when you pick an existing imported image or PDF, you are selecting what's called an object of the ImageInstance class, which wraps an ImageType object. So we need to get the ImageInstance element, access its ImageType, then get its image data.


Let's see the code.

// This code goes somewhere in your Revit add-in
// Prompt user to pick a Revit Element
Reference pickedObject = UIDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);

// Get Element
Element element = Doc.GetElement(pickedObject.ElementId);

// Get Element Type
ElementId elementTypeId = element.GetTypeId();
ElementType elementType = Doc.GetElement(elementTypeId) as ElementType;

// Do something if object selection exists
if (pickedObject != null)
{
    // Check if picked element is an ImageInstance
    if (element is ImageInstance)
    {
        // Cast types for ImageInstance and ImageType
        // ImageType Id = ImageInstance Id - 1
        ImageInstance image = element as ImageInstance;
        ImageType imageType = elementType as ImageType;

        // Get image properties
        var filename = image.Name; // eg. FloorPlan.pdf

        // Get imported file path from ImageType
        var filepath = imageType.get_Parameter(BuiltInParameter.RASTER_SYMBOL_FILENAME).AsString();
        var pixelWidth = imageType.get_Parameter(BuiltInParameter.RASTER_SYMBOL_PIXELWIDTH).AsInteger();
        var pixelHeight = imageType.get_Parameter(BuiltInParameter.RASTER_SYMBOL_PIXELHEIGHT).AsInteger();

        // Get image data
        Bitmap bitmap = imageType.GetImage();

        // Save image to disk
        bitmap.Save(@"C:\users\username\Desktop\image.bmp");
    }
}

Before you go

If you found this useful, you might want to join my newsletter; or take a look at other posts about code, Revit, C#, TypeScript, and React.

SEPTEMBER 3, 2019

If you are inside of a function which uses a type parameter—T—you can do a Console.WriteLine, for instance, to inspect what type is being used on a given function call.

Console.WriteLine(typeof(T));
// System.object or other type

Want to see older publications? Visit the archive.

Listen to my Podcast.