Find Views in which an element is visible (by geometry or actual visibility)

Find Views in which an element is visible (by geometry or actual visibility)

Anonymous
Not applicable
4,930 Views
13 Replies
Message 1 of 14

Find Views in which an element is visible (by geometry or actual visibility)

Anonymous
Not applicable

Here is what I would like to do:

Given any particular element (by extenstion, perhaps a set of elements):

Find all views in the project in which the element is visible.

 

For example, if I select a specific door, then I want to find all the floor plan views that include the door, plus section views that show the door (cut or projection), any elevation views that show the door, etc.

 

Without having given this too much work yet, it would seem that there are two general issues here, and I am guessing that Revit might deal with them differently:

a) given the geometric location of the element, does it occupy the space that is visible in any given view (considering clipping, etc)

b) given the visibility parameters, filters, etc - is the element shown/hidden due to its category, paramter, etc.

 

In my situation what I really would like to find at the moment is: If all visibility of all model elements is on, then what views would show the element.

 

Thanks in advance for whatever clever insights people may have on this.

 

Abba Lustgarten

Abba CAD Abba Inc.

 

 

0 Likes
4,931 Views
13 Replies
Replies (13)
Message 2 of 14

jeremytammik
Autodesk
Autodesk

Dear Abba,

 

Lucky you, asking the right question.

 

This one, we can answer, and already have, including a dedicated external command CmdViewsShowingElements to prove it to The Building Coder samples::

 

http://thebuildingcoder.typepad.com/blog/2014/05/views-displaying-given-element-svg-and-nosql.html#6

 

http://forums.autodesk.com/t5/Revit-API/Revision-help-which-views-show-this-object/m-p/5029772

 

https://github.com/jeremytammik/the_building_coder_samples

 

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/C...

 

Please let us know how it works for you and how you make use of this.

 

Thank you!

 

Cheers,

 

Jeremy

 



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

Message 3 of 14

Anonymous
Not applicable

Jeremy

Thanks for your reference to the sample code and the brief history of this.

 

Your link: http://thebuildingcoder.typepad.com/blog/2014/05/views-displaying-given-element-svg-and-nosql.html#6

 

I am just going to give this a try, and will let you know how it works for me.

As I do so, I just have this question:

 

You mentioned that your initial solution for this involved looping through views and using a filteredelementcollector (with a view_ID parameter) to check for object visibility.  Colin pointed out the potential slowness of this, and your note implied that he had come up with what you considered to be a 'better way'.

 

From my first glance, it looks to me like this sample also loops through a series of views and uses a view-specific filteredelementcollector to check for element visiblilty in each view.  I don't see your original code to compare, but I am wondering if Colin's code does in fact overcome the efficiency problem that he pointed out, or if he just found a better way to implement the approach.

 

I am only asking to make sure I am not missing something, and to make sure I don't go too far down the wrong path as I am bringing my revit API skills up to speed.

 

Abba Lustgarten

Abba CAD Abba Inc.

 

 

0 Likes
Message 4 of 14

jeremytammik
Autodesk
Autodesk

Dear Abba,

 

I think the blog post is pretty clear on that: "Here is the CmdViewsShowingElements implementation including Colin's two extension methods:..."

 

What more can I do to clarify?

 

Please note that the GitHub repo is maintained and contains the most up-to-date code.

 

Cheers,

 

Jeremy



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

0 Likes
Message 5 of 14

Anonymous
Not applicable
Hi Jeremy,

What I wanted to clarify was this:

In the 'original' code, (which I haven't seen), Colin raised the concern
that when checking each view for element visibility, Revit would essentially
have to open the view and this could take a long time, especially if a lot
of views are being checked.



In the posted code, do you think this problem is overcome? Or would the
implementation of the filteredelementcollector still be 'opening' the views,
with the potential time problem.



In my case, I am likely to be looking at hundreds of views, so this could be
significant.



Practically speaking, as you advise, I am working on the assumption that the
github posted sample is most recently 'reccommended' approach. Thanks for
putting it there and helping me find it.



Thanks in advance for your thoughts on this.



Abba
0 Likes
Message 6 of 14

Anonymous
Not applicable
Hi Abba,

Revit will open all the views and its going to take ALOT of time if you have alot of views within a complex project.

I've just run into that problem and ended up here.

Revit caches the results for a while so if you ask for the same thing one more time its going to go alot faster, but if you change your input, you are going to have to wait again.

Im seeing times of 11 sek when Im going through 560 views.
I dont think the filteredelementcollector is designed with this in mind...

If I find another way, I'll post it here.
0 Likes
Message 7 of 14

Anonymous
Not applicable
Hi erikeriksson5686,

Thanks for your contribution for this,



So far, there isn't an alternative that I can see easily. It seems that the
key for me will probably be to 'pre-filter' the list of views that I want to
check.

For example, by the name of the view, or by the type of view (only Floor
Plans, or Section Views, etc).



I built an interface that does this and gives me a list of 'eligible' views
and lets me select the ones I want to check for element visibility. This is
mostly for testing the whole mechanism at the moment, since I don't totally
trust the filter mechanism yet.



This is all a bit preliminary, (got dragged off onto some other things.) but
I found that if I select something like a Stair, or a wall, it seems to
reliably find it in views. However I tried selecting some other things,
like a mullion on a curtain wall, etc, and that doesn't seem to register as
visible to the filtered element collector, even though it seems to be
visible in the view. If and when I find a more clear pattern, I will post
something about it, and if I don't, I will post something about it.



As for the performance, I also noticed that 'cache' effect, so that running
the filter repeatedly on the same view is much faster.

I am actually seeing the REVIT interface show me that it is regenerating the
view (at the bottom of the screen) when it is big and takes a while.



I have a question for you,

You mentioned 560 views taking 11 seconds. Did that mean 11 seconds to scan
all of them, or 11 seconds per view?

i.e. are you getting through 50 views per second?

I am looking at quite a large model with some fairly big and complex views,
but it is averaging a few views per second on small ones and a few seconds
per view on big ones.

For my purposes, 11 seconds for 560 views would be ok.



Again, thanks for your contributions. I would be eager to hear if you have
something working well for you.



Abba Lustgarten

Abba CAD Abba Inc.
0 Likes
Message 8 of 14

Anonymous
Not applicable
Ok, yes. Minimising the views are key, I also prefilter alot.

Yes, the 11 sek are for all 560 views and thats the total time for prefiltering as well, so I might be getting little less than 10 seks for the views.

However I might have found another way that looks really promising.

By taking comparing BoundingBoxes of views and the target elements (intersections) I was able to get results in under a second for all views.
However, in constrast to the FilteredElementCollector way this requires some testing and setup to get accurate results.
You need to make sure that the view has cropping enabled and set correct height of the view boundingbox and some more.
Furthermore, I noticed viewsections needs some special care.

I havent finished my tests, but like I said, it looks promising.


0 Likes
Message 9 of 14

Anonymous
Not applicable
Does sound promising. I was planning on using the bounding box idea, but I
am somewhat new at the REVIT API, and have not dealt with the bounding box
of views yet. Somehow I suspect there is a level of complexity once you
factor in different coordinate systems (e.g. shared coordintates, etc?) view
clipping, floor level heights, etc.



If you have found some of these pitfalls, I would love to hear about them.



Good luck.
0 Likes
Message 10 of 14

jeremytammik
Autodesk
Autodesk

Hi guys,

 

Thank you for a valuable discussion, especially Erik with his in-depth real-world experience.

 

The note on the huge speed-up using bounding boxes is of fundamental importance.

 

You absolutely must be aware of the difference between quick and slow filters.

 

The bounding box check is a quick filter.

 

Quick filters can be executed without regenerating the views and without fully loading the nitty-gritty detailed data of a huge model:

 

http://thebuildingcoder.typepad.com/blog/2015/12/quick-slow-and-linq-element-filtering.html#6

 

Cheers,

 

Jeremy

 



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

0 Likes
Message 11 of 14

Anonymous
Not applicable

Hi Jeremy,

actually Im not using the quick filter. I tried to, but the boundingbox of the views need altering because the Z values are not correct (for viewplans atleast). Im prefiltering alot with quick filters, but when it comes to the actual boundingbox comparision I've expanded the views into memory. You can see this in the code in the bottom.

 

Anyway, I've perfected my boundingbox filter into something that works for me. I tried to get it to work in viewsections, but that was just too big of an obstacle for me today, the client didnt need that in the end, so I just skipped that part. The problem was figuring out the boundingbox since the coordinatesystem shifts in viewsections.
I tried to look a the transform of the boundingbox, and shift it accordingly, but it didnt work.

 

Maybe you can shine some light on whats wrong or how to accomplish it, Jeremy?

 

The performance of the boundingbox version is extreme in comparison, using a stopwatch I measured the following times:

~22 seks for the traditional way and 125 ms for the boundingbox way.

 

Anyway, here is the extensionmethod I use now:

Snippet

public static bool IntersectsBoundingBox(this View view, BoundingBoxXYZ targetBoundingBox)
{
 
    
 
    var viewBoundingBox = view.CropBox;
 
    if (!view.CropBoxActive)
    {
        using (Transaction tr = new Transaction(view.Document, "Temp"))
        {
            //If the cropbox is not active we cant extract the boundingbox (we rollback so we dont change anything and also increase performance)
            tr.Start();
            view.CropBoxActive = true;
            viewBoundingBox = view.CropBox;
 
            tr.RollBack();
        }
    }
    
    Outline viewOutline = null;
    if (view is ViewPlan)
    {
        var viewRange = (view as ViewPlan).GetViewRange();
 
        //We need to change the boundingbox Z-values because they are not correct (for some reason). 
        var bottomXYZ = (view.Document.GetElement(viewRange.GetLevelId(PlanViewPlane.BottomClipPlane)) as Level).Elevation + viewRange.GetOffset(PlanViewPlane.BottomClipPlane);
        var topXYZ = (view.Document.GetElement(viewRange.GetLevelId(PlanViewPlane.CutPlane)) as Level).Elevation + viewRange.GetOffset(PlanViewPlane.CutPlane);
 
        viewOutline = new Outline(new XYZ(viewBoundingBox.Min.X, viewBoundingBox.Min.Y, bottomXYZ), new XYZ(viewBoundingBox.Max.X, viewBoundingBox.Max.Y, topXYZ));
    }
 
    
    if(!viewBoundingBox.Transform.BasisY.IsAlmostEqualTo(XYZ.BasisY)) //this is where I try to hand viewsections. But I cant get it to work!!
    {
        viewOutline = new Outline(new XYZ(viewBoundingBox.Min.X, viewBoundingBox.Min.Z, viewBoundingBox.Min.Y ), new XYZ(viewBoundingBox.Max.X, viewBoundingBox.Max.Z, viewBoundingBox.Max.Y ));
 
    }
 
 
    using (var boundingBoxAsOutline = new Outline(targetBoundingBox.Min, targetBoundingBox.Max))
    {
        return boundingBoxAsOutline.Intersects(viewOutline, 0);
    }
 
 
 
}

 I hope someone finds it useful and good luck Abba!

 

/Erik

Message 12 of 14

Anonymous
Not applicable
Thank you Erik. I will hopefully soon have a chance to dig into this in
full. Right away, I can see a few major tricks that I am sure would have
taken me quite a while to uncover.



In particular, needing to make the cropbox active to get the bounding box,
and thus using a transaction and rolling it back in order to do this.
Question: if the cropping box is NOT active on a particular view, is the
bounding box really what reflects the visibility of an object in it?



My gut told me that levels, transforms, etc would be necessary to filter
views according to their geometrical extents. This seems to have been
right, and I haven't gotten my hands very wet with those yet. Jeremy, can
you give a brief tutorial (or point to a sample or previous overview) on:



- Bounding Boxes (views / elements)

- Coordinate systems and their relationship to levels

- Transformations of coordinates



It turns out that section views are probably the most important for me, so
it would be great to have a 'universal' view extent calculator method.



It does make sense that filtering by the geometrical extents would be much
faster, even with slow filters, since we are considering the extents of only
a few objects (view, cropping box, element?), compared with many thousands
of elements that must be processed in some way when a view is actually
opened, as seems to happen when the filteredelementcollector goes at it.
However, I think it will be critical to make it work reliably on all
appropriate types of views.



Thanks especially for the snippet. If and when I get this working, I will
post whatever extent-getter I come up with.



Abba
0 Likes
Message 13 of 14

Anonymous
Not applicable
Im glad you found some useful bits.

I dont think that revit is using the boundingbox to calculate of the element is visible in the view, its far too slow for that (select element by id and press show, for instance...). Its just another way of doing it, maybe they dont do it because they too know they cant rely on the boundingbox extents and the fact that it must be turned on or maybe we'll see a much faster way of showing elements in the UI in the coming version of Revit =P

Im sure there is a way of using this method with viewsections and from what I've seen, Jeremy is a whole lot better at this type of math than I am 😃

By looking at the boundingbox of the viewsection its pretty clear that the Z values are messed up here to (or have some other meaning, that I cant comprehend).

God, while writing this I started investigating alittle bit more.
I wrote a Room drawing generator last year and that had some heavy lifting when it came viewsections and figuring out and changing their cropboxes.

This is a theory: but if you skip the original cropbox and use the "new" GetCropRegionShape using the CropManager. You get the crop in lines in project coordinates and then you can create a Solid by extrusion (using the far clip offset) using the GeometryCreationUtils and then use the SolidUtils and calculate solid intersections. That would probably be alot faster.
This has an obvious problem and that is that there could still be elements hiding your elements in the views. That is a problem I have in my boundingbox version to.
This is just me thinking out loud, there might be other problems with this workflow, what do you think, Jeremy?

/Erik
0 Likes
Message 14 of 14

jeremytammik
Autodesk
Autodesk

Dear Abba and Erik,

 

Sorry that I never answered your questions, guys, and left some open ends dangling.

 

I hope we can resolve them by and by.

 

I published this discussion as it now stands, in the hope that others will want to discover, test and refine the approaches you suggested:

 

http://thebuildingcoder.typepad.com/blog/2016/12/determining-views-showing-an-element.html

 

Looking forward to hearing what you think and what further progress you made in the meantime.

 

Thank you!

 

Best regards,

 

Jeremy



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

0 Likes