The wonderful thing about working in 3d is that every view is just a view of the same database. The horrible thing about delivering drawings from a 3d model is that every view is just a view of the same database. So when there is a revision to already issued drawings how do I find all the views that need revision clouds? ...
Does anyone know of a way in the API to find all views showing an object with a given ID number? I'm thinking a first sweep maybe comparing views on sheets and their depths to object geometri, then a second sweep checking visability against views with view templates, and a third checking for view specific overrides. Otherwise this kind of thing would take forever.
Ideas anyone? I'd like to add this to my list of API projects ...
The wonderful thing about working in 3d is that every view is just a view of the same database. The horrible thing about delivering drawings from a 3d model is that every view is just a view of the same database. So when there is a revision to already issued drawings how do I find all the views that need revision clouds? ...
Does anyone know of a way in the API to find all views showing an object with a given ID number? I'm thinking a first sweep maybe comparing views on sheets and their depths to object geometri, then a second sweep checking visability against views with view templates, and a third checking for view specific overrides. Otherwise this kind of thing would take forever.
Ideas anyone? I'd like to add this to my list of API projects ...
Dear Duncan,
This might be a lot simpler than you think.
One overload of the FlteredElementCollector constructor takes a view element id as an input argument and returns all visible elements in that view.
You could therefore simply cycle through all views, instantiate a view-specific element collector for each, and check whether the elements it returns include your target element.
Best regards,
Jeremy
Dear Duncan,
This might be a lot simpler than you think.
One overload of the FlteredElementCollector constructor takes a view element id as an input argument and returns all visible elements in that view.
You could therefore simply cycle through all views, instantiate a view-specific element collector for each, and check whether the elements it returns include your target element.
Best regards,
Jeremy
Hi Jeremy
Great news. I thought someone would know how to do this. I'll see if we can convince someone to implement this functionality (my coding skills are still pretty hopeless.)
Duncan
Hi Jeremy
Great news. I thought someone would know how to do this. I'll see if we can convince someone to implement this functionality (my coding skills are still pretty hopeless.)
Duncan
Hi Duncan,
Please provide a sample model and an exact description of the required input, user interaction and output.
That will enable interested parties to take a look at it.
Thank you.
Cheers,
Jeremy
Hi Duncan,
Please provide a sample model and an exact description of the required input, user interaction and output.
That will enable interested parties to take a look at it.
Thank you.
Cheers,
Jeremy
The solution as Jeremy suggested is certainly possible, BUT in a model with many views, it can take an extremely long time to run.
The reason for this is, (as far as I can tell), when using a view-specific FilteredElementCollector, Revit effectively opens that view and checks whether the element is visible in the view.
The result of this is that getting a list of views where an element is present takes the same amount of time as opening every view that is checked.
That being said, here is the code that I have for this:
public static IEnumerable<View> FindAllViewsWhereAllElementsVisible(this IList<Element> elements) { if (elements == null) throw new ArgumentNullException("elements"); if (elements.Count == 0) return new List<View>(); Document doc = elements.First().Document; IEnumerable<View> relevantViewList = doc.FindAllViewsThatCanDisplayElements(); List<ElementId> idsToCheck = (from el in elements select el.Id).ToList(); return (from v in relevantViewList let idList = new FilteredElementCollector(doc, v.Id) .WhereElementIsNotElementType().ToElementIds() where !idsToCheck.Except(idList).Any() select v); }
Helper function:
public static IEnumerable<View> FindAllViewsThatCanDisplayElements(this Document doc) { ElementMulticlassFilter filter = new ElementMulticlassFilter(new List<Type> { typeof(View3D), typeof(ViewPlan), typeof(ViewSection) }); return new FilteredElementCollector(doc).WherePasses(filter).Cast<View>().Where(v => !v.IsTemplate); }
If you can't tell, I'm a big fan of LINQ... Let me know if you need me to explain anything that's happening here.
Colin
The solution as Jeremy suggested is certainly possible, BUT in a model with many views, it can take an extremely long time to run.
The reason for this is, (as far as I can tell), when using a view-specific FilteredElementCollector, Revit effectively opens that view and checks whether the element is visible in the view.
The result of this is that getting a list of views where an element is present takes the same amount of time as opening every view that is checked.
That being said, here is the code that I have for this:
public static IEnumerable<View> FindAllViewsWhereAllElementsVisible(this IList<Element> elements) { if (elements == null) throw new ArgumentNullException("elements"); if (elements.Count == 0) return new List<View>(); Document doc = elements.First().Document; IEnumerable<View> relevantViewList = doc.FindAllViewsThatCanDisplayElements(); List<ElementId> idsToCheck = (from el in elements select el.Id).ToList(); return (from v in relevantViewList let idList = new FilteredElementCollector(doc, v.Id) .WhereElementIsNotElementType().ToElementIds() where !idsToCheck.Except(idList).Any() select v); }
Helper function:
public static IEnumerable<View> FindAllViewsThatCanDisplayElements(this Document doc) { ElementMulticlassFilter filter = new ElementMulticlassFilter(new List<Type> { typeof(View3D), typeof(ViewPlan), typeof(ViewSection) }); return new FilteredElementCollector(doc).WherePasses(filter).Cast<View>().Where(v => !v.IsTemplate); }
If you can't tell, I'm a big fan of LINQ... Let me know if you need me to explain anything that's happening here.
Colin
Hi Colin,
Thank you for the very nice enhancement!
I like it!
You also seem to like extension methods, performance optimisation and the ElementMulticlassFilter.
So do I.
I therefore integrated your code into The Building Coder samples and implemented a new external command CmdViewsShowingElements to exercise it:
http://thebuildingcoder.typepad.com/blog/2014/05/views-displaying-given-element-svg-and-nosql.html#6
Cheers,
Jeremy
Hi Colin,
Thank you for the very nice enhancement!
I like it!
You also seem to like extension methods, performance optimisation and the ElementMulticlassFilter.
So do I.
I therefore integrated your code into The Building Coder samples and implemented a new external command CmdViewsShowingElements to exercise it:
http://thebuildingcoder.typepad.com/blog/2014/05/views-displaying-given-element-svg-and-nosql.html#6
Cheers,
Jeremy
Can't find what you're looking for? Ask the community or share your knowledge.