I have written a Script that uses an Annotation Element, Searchs the project for all Rooms and take Information out of the room to write into the Annotation basically a Apparment annotation. It works seamless but there is a little pitfall. When using on big projects it loads for about 10 Minutes and I know why. The problem with the script is that it works like this:
Take all Annotations of the current view
For every annotation look up all rooms
filter from the rooms the assigned ones
write data into the annotion.
The problem is that it gets all Rooms all over again and again for every single Annotation instead of a accessing a global variable that has all rooms stored. these are the lines I use inside my def:
A dictionary by element ID could work well here. Woul dneed to see more of your code to help guide you in implementing it, but effectively you build a key from the roomâs identifier, and put the list of rooms into the dictionary under that key. So if the identifier was say the tenant parameter, youâd group all the rooms by tenant, build a dictionary using the sublists as the values and the unique names as the keys, and then from the annotation pull the tenant from the string, pull out the list of rooms from the dictionary, and update the values using content from the rooms.
Sadly I donât have a Revit file with âBauteilâ or âEbeneâ parameters in it, so I canât run this. The dictionary method I mentioned above should work quite well though.
Today is Tuesday; on Tuesdays we donât use Revit.
In all seriousness, hopefully this example using points and dictionaries instead of rooms and annotations will help you get sorted out, as I donât have the time to Revit model and the equivalent code to use it on.
objs = // assume my objects are your rooms
rooms;
v1 = // assume this is pulling your first parameter value
Math.Floor(objs.X);
v2 = // assume this is pulling your second parameter value;
Math.Floor(objs.Y);
vSet = // merge the parameter values into one comparable
String.Join(
" - ",
""+List.Transpose([v1,v2])
);
grpSet = //group the objects by their comparable value
List.GroupByKey(objs,vSet);
roomDict = //build a dictionary of the unique keys and groups
Dictionary.ByKeysValues(
grpSet["unique keys"],
grpSet["groups"]
);
annotationValue = //get the key from the annotations
String.Substring(annotations[annotations.Keys],0,5);
annotationGroups = //get the collection of objects for each annotation
roomDict[annotationValue];
annotationGroupSums = //get what you want from the objects
Math.Sum(annotationGroups.Z);
annotationGroupCounts = //get what you want from the objects
List.Count(annotationGroups@L2<1>);
annotationString = //build the new annotation string
String.Replace(
annotationValue + ": " + Math.Round(annotationGroupSums,3),
"000",
""
)+ " units of elevation in " + annotationGroupCounts + " different points.";
updatedAnnotations = //update the annotation
Dictionary.SetValueAtKeys(annotations, annotations.Keys, annotationString);
I use the script to fill all values of the annotation automaticaly for the whole project,
it shows the room number, the total flat area, and different outdoor areas, the Level is used for schedule
Ah so basically you âtagâ an entire appartment and put that stamp somewhere on your drawing or make seperate appartment drawings?
Iâve never used Areaâs but I think if you only use them for appartments they could be functional here too.
In that case I would create an ID code for your annotation (Element.ID can change between synchronising) and connect it to the view or appartment ID. Then sort the rooms like that and get the Element.GetParameterValue that way. This way, no view needs to be opened and data transfer should be much quicker.
You could also use TuneUp to detect which nodes delay the most
For the script you could also filter the Annotation Elements so you more manually /selectively update them, say 10 at the time. Per floor / level for instance
OR you put a binary parameter to the annotation element that once it has ran, it puts it on completed so the next time it wonât run it again and will only update the new ones.
I could help more but I would have to see an example sheet and dyn script. Hopefully these tips will help
I do, and could have here to speed things up. However when sharing something as a teaching tool I find it best to give the person asking the question the chance to review individual steps - you can always convert to a definition once you understand the concept.
Actually it works quite well right now, I donât want to change so much at the scripts logic. It takes the Top Number which is written into the annotation, and filters rooms which has the same value for the parameter top number. this is how it finds the right rooms.
I think the main bottle neck is that it goes through all rooms everytime it goes through an annotation instance.
thanks i believe i got it now. So I basically âPresortâ all data by going through the rooms and after that i loop through all annotations and write the respective data to the annotation
Yep - once youâre grouped and pushed into a dictionary you use the value from the annotation to get the collection you want out of the dictionary and pull the data you want from each object.