Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to get the extents when exporting an image from a view using C# API?

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
peter.kolbe
2085 Views, 10 Replies

How to get the extents when exporting an image from a view using C# API?

Using this post
https://forums.autodesk.com/t5/revit-api-forum/how-to-export-an-image-from-a-specific-view-using-rev...
I'm able to create PNG images and store them in the local file system. The images will be created from 2D floor plans.
Now I want to know, what are the extents of the result image in local coordinates (not the count of pixel. this is an input value).
Is there a way to get that size? Or is there a way to calculate it? Or what elements will be used to create the image and is there a calculation for the border around the elements?
Thank you!
Peter

10 REPLIES 10
Message 2 of 11
jeremytammik
in reply to: peter.kolbe

Dear Peter,

 

I don't know what you mean by 'local' coordinates.

 

Do you mean the internal Revit model coordinates?

 

You can map between the Windows screen device pixel coordinates and the internal Revit model coordinates using functionality on the Revit API UIView class:

 

https://apidocs.co/apps/revit/2019/2a070256-00f0-5cab-1412-bee5bbfcfc5e.htm

 

For instance, I used that to implement my own tooltips that grab information from the Revit model:

 

http://thebuildingcoder.typepad.com/blog/2012/10/uiview-windows-coordinates-referenceintersector-and...

 

http://thebuildingcoder.typepad.com/blog/2017/01/uiview-windows-coordinate-referenceintersector-tool...

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 11
BenoitE&A
in reply to: peter.kolbe

Funny, we are just working on that.

To export you will need a ImageExportOptions object, which has a property named HLRandWFViewsFileType.

And that property can be turned on PNG. This is answer 1.

The ImageExportOptions object has another property called ExportRange. Check the values, one of them is VisibleRegionOfCurrentView. If you modify the crop region of your view you are able to export exactly what you want. This is answer 2.

And I have a bonus : to export properly you should consider changing the scale of your ViewPlan. If it is 1:100 the annotations will be very large, but if you turn it to 1:20... they will be smaller... Bonus !

I think you owe me a triple Accept As Answer 😉

 

Benoit


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 4 of 11
peter.kolbe
in reply to: jeremytammik

Hi Jeremy,

correct, I'm searching for "internal Revit model coordinates".

And it looks like that the UIView.GetZoomCorners() will return these values.

In my app there is the 3D view open and I calculate all the floor views, which should be exported as PNG.
When runing code like this

uiDoc.ActiveView = view;
UIView uiView = GetActiveUiView(uiDoc);
uiView.ZoomToFit();
IList<XYZ> zoomCorners = uiView.GetZoomCorners();
ExportToImage(doc, pngFile);

The variable zoomCorners contains values, when the 2D floor plans were open and active previously. Otherwise the zoom corner values are all equal to zero.
Do you have a hint, how to get the floor plans active and visible, so that the GetZoomCorners() will return the expected values, also if these views were not opened before running my App command?
Thank you for your help!

Best regards,
Peter

 

Message 5 of 11
BenoitE&A
in reply to: peter.kolbe

And there is another property of the view called Crop Region which is much better than using the Zoom.

You should check !!


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 6 of 11
peter.kolbe
in reply to: peter.kolbe

Hello Benoit,

just for completeness, here is my ExportToImage() and it contains the properties, you mentioned:

static Result ExportToImage(Document doc, string pngFilename)
{
    Result r = Result.Failed;
    using (Transaction tx = new Transaction(doc))
    {
        tx.Start("Export Image");
        ImageExportOptions img = new ImageExportOptions();
        img.ZoomType = ZoomFitType.FitToPage;
        img.PixelSize = 6400;
        img.ImageResolution = ImageResolution.DPI_300;
        img.FitDirection = FitDirectionType.Horizontal;
        img.ExportRange = ExportRange.CurrentView;
        img.HLRandWFViewsFileType = ImageFileType.PNG;
        img.FilePath = pngFilename;
        img.ShadowViewsFileType = ImageFileType.PNG;
        doc.ExportImage(img);
        tx.RollBack();
        r = Result.Succeeded;
    }
    return r;
}

But there is the same problem as I answered to Jeremy, the result value are invalid as long as the floor plan view were inactive and invisible. Otherwise when I open the views before running the command, the values will be returned.

What else do I have to do then 

uiDoc.ActiveView = view;

before accessing the uiView?

Thank you!
Best regards,
Peter

Message 7 of 11
BenoitE&A
in reply to: peter.kolbe

Indeed you have to activate the view.

Be careful you can only activate it OUTSIDE a transaction.

 

Benoit


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 8 of 11

Hi,

In relation to the partial solutions provided above, I tried the following code to switch to all floorplans in the document one after the other in a loop:

 

// initialize app and uiapp objects
Application app = document.Application;
UIApplication uiapp = new UIApplication(app);
UIDocument uidoc = uiapp.ActiveUIDocument;
UIView uiview = null;

IList<Element> elementSet;

/// Find all instances in the document by using category filter
FilteredElementCollector collector = new FilteredElementCollector(document);
elementSet = collector.OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements();


IList<ElementId> ImageExportList = new List<ElementId>();
            foreach (View view in elementSet)
            {
                if (view.ViewType.ToString() == "FloorPlan")
                {
                    uiapp.ActiveUIDocument.RequestViewChange(view);

                    IList<UIView> uiviews = uidoc.GetOpenUIViews();
                    foreach (UIView uv in uiviews)
                    {
                        if (uv.ViewId.Equals(view.Id))
                        {
                            uiview = uv;
                            break;
                        }
                    }
                }
            }

 

The loop works fine the first time, meaning that it switches from the open Level 0 view to Level 1 view in a new viewtab in Revit, but then it fails saying that:

 


Cannot make a template view active.
Parameter name: view

 

What am I missing here..?

Thanks!

Message 9 of 11

The message tells you the problem:

 

You are apparently trying to activate a template view.

 

You need to eliminate or skip template views from your iteration.

 

The view has an IsTemplate property:

 

https://www.revitapidocs.com/2020/bd7d3469-dc89-93b7-1cb8-848fd4f38d65.htm

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 10 of 11

Funny indeed, a Template View is not a Type in Revit.

So you should add here :

foreach (View view in elementSet)
{
    if(view.isTemplate)
         continue;
    if (view.ViewType.ToString() == "FloorPlan")
    {

Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 11 of 11

Thanks for both of you, indeed I was missing this small step 🙂

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community