XMLfiles are everywhere. Andin the BIM world, we have to deal with a range of different xml file schemas, such as BCF, Navisworks Clash Reports and Viewpoints, and so forth. Hiding inside these XMLs there is some very useful information. For example, BCF files often have Element IDs in the viewpoint.bcfv component, and Navisworks XMLfiles often have point XYZ values. Can we easily get access to this information for usein Dynamo, and then inRevit?
Yes, we can! There were one or two ways to do this in Dynamo before, but here is my take on it…
Dynamo ships with IronPython, which in turn ships with an XML handler called ElementTree. I have created some basic nodes that give us access to ElementTree functions in Dynamo. Along the way, I learnt a bit about encoding and character sets. It turns out that Navisworks often inserts tricky characters into the XML (like the diameter symbol), so as a workaround (for now) I do a string encoding roundtrip to get rid of these problematic characters. In the same node, I create the ElementTree object: this is a special object that essentially represents structured information about the XML data. The initial import looks like this:
Once we have this ElementTree object in hand, we can start to do some interesting things, like: Iterate through tree to get individual XML elements
andShow a hierarchical representation:
With the individual elements, we can Get Attribute names and values, and the Get the children of those elements:
Obviously, you can immediately do some nice lookups against these lists in Dynamo, depending what information you want. However, on large XMLs this can be quite slow. Happily, ElementTree provides some basic XPATH support, which looks a bit like this:
With the XPATH supportand an understanding of the xml hierarchy, I have created a node to do XPATH calls straight to the ElementTree object:
Now that we can ‘snip’ out useful information from the XML, we can do interesting things with it, like make some points:
When it comes to BCF, its a little bit more challenging. I haven’t figured out how to unpack the bcfzip directly to memory (yet), so we have do that manual step first. Once we have a ‘folder’ from the BCFZIP, we can get the bcfv files from inside it and then get information from them, like this:
So, in the latest Bakerypackage are the nodes needed toread a variety of XMLfiles, get information from them, and do some useful things with that information. It was a learning experience for me, and I hope its useful to you 🙂
I’ve had a bit of struggle with Package Manager lately, but I’m happy to report I was able to get a new version of Bakery uploaded today. I’m pretty sure my issue was ‘too many backups in the dyfbackup folder’, so that may help you if you are having problems uploading. The new version is 2015.10.291:
Recently, I have made an effort to reduce dependencies, but there are still a couple like archi-lab and Clockwork.
Here is a list of my main nodes, with these comments
some have been forked or imported directly from other packages (see note about dependencies above), and full credit goes to those people who made the original versions
some are sub-nodes of main parent nodes that I have yet to go through and hide from the library. I have a big habit (bad?) of making nodes to handle one item and then using them in List.Maps.
Anyhow, here they are: Boolean Input to Variable String Output Bruteforce Get Elem ID and Two Parameters and Make List of Strings Bruteforce Get Parameter Value by Name Bruteforce Get Parameter Values when Multiple Entries Bruteforce Get Parameter via String Split for Single element Bruteforce Get Parameter via String Split V2 Bruteforce Get Two Parameters and Join to One String Built In Name Lister Check DYF folder for Dependencies in Package Folders Check for Duplicate Parameter Values and Make Selection Set Check for SetParameter Nulls and Report Info on Elements Check if Elements are Inplace ( In-place Families ) Check Project Shared Parameter against benchmark GUID Check Reference Level Offsets against a Tolerance Input Check Specific Shared Parameter has correct GUID Clean List of Indices to Remove Negative Values Clean Warning Types from Error Report HTML Collect all FamilyInstance using Element Types Collect All Tags in Project Collect Elements from List of Category Names Collect Elements in Rooms and Show Detailed List Collect from Link using Category and Parameter Value Collect Tag Elements in Specific View and Send Ids to Clipboard Combine Column from Three Excel Files into One Long Column Compare Two Columns From Excel and Report Differences Compare Two Lists by Item and Return Item Differences Compare View Filters added to Two Views or Templates Convert Category Name to Built In Category Name Convert List into List of Strings with Line Breaks Convert String with Line Breaks into List of Strings Copy Parameter to Parameter in List of Elements Copy Parameters Node for Nesting Process Copy Property to Parameter for List of Elements Copy Workset Name to Target Parameter Create Floors From Rooms v1 Create Floors From Rooms v2 Cycle Entries of one List by List of Lengths Cycle One Item Into List to Match Length of Other List Design Option Summary Design Option and Design OptionSet Document Design Option Sets Document Design Options Document Phases Does this Document Contain Category Duplicate View and Isolate Elements Duplicate View and Rename and Isolate Elements Duplicate View and Rename and Isolate for System Types Element List check for Inplace Families Element Name Universal Element Type for Element Lists Element Type for Linked File Element Lists Element Type for Linked File Large Lists Enumerate Worksharing Display Modes for Document Example FFE Category List for a project Export Family and Type Name with One Type Parameter to Excel Export Images using many input variables Export to Image using Directory and View Parameter Extract Specific Tag Entries from XML as Unique List File List from File Path showing Files in SubDirs File List from File Path File Size in MB from File Path Filter a List by a Given Value with second list passthrough Filter Element List by Parameter Value Filter Element List by Type Parameter Value Filter Items in List by String Contains and Return List and Unmatched Filter One List by String Search in Another List Filter Revit Selection to View Crop Elements and Names Filter Views with Two Criteria and Return Views Find Nearest Revit Level for a Given Z value Find Pipe Insulation on Workset – Get Host Pipes – Save to Selection Find Revit Level for Points by Elevation Find Sheets and Views Where an Element is Visible Find Worksets that contain Revit Link Instances Flat List to List of Strings Flatten List and Replace Null with NULL VALUE From File Path into RVT Build Information Get Actual Elements from Linked Tag Ids Get All Revisions Get All Revit Links as Element List Get Boundary Curve for One Room by Perimeter Get Boundary Curves from Room List Get Build Number and Worksharing from RVT file Get Build Number from All RVTs in a Folder Get Categories from Elements Get Categories with Builtins Get Categories Get Design Option Element by Set Name and Option Name Get Element Parameters and Split to Names and Values Get Element Position Rotate Mirror Get Element Room parameter from API Get Elements and Types for Certain Categories in Links Get Elements from Link Document Using Category Get Elements in Link using Name Search and Category Get Elements Parameter List and Show Unique Values Get Family and Type List for Project Get Family from Element Get Family List for this project Get Host Pipe ID from Pipe Insulation Get Indices of Null Values Get Info from a Linked Element Tag Get Link Document from Link Instance Id Get Linked Element from Element Id and Doc Get Linked RVT Documents Get List of Elements at OriginalNestingLevel Get list of GUIDs for a Specific Shared Parameter Name Get List of Linked Elements from Id and Doc Get Open Worksets and Write to View Parameter Get Open Worksets Get Project Location Details Get Pure Filename from Revit Link Name String Get Revit Link Names from an Element List Get Revit Selection and Delete Get Room Geometry and Filter by Level Elevation Get RVT Link Filenames with Element and Type Workset Info Get Sheet Element from View Get Standard Views as single list Get System Related Properties of Element Get Tagged Linked Element Id Get Two Parameters and Join to One String Get Type Parameter for Tagged Linked Element Get View Dependency as Internal not String Get View Parameter and Parse for Locate32 Search Get View Template for View Get Viewport Elements Using View Name Search Get Workset Info for RVT files without opening Get Worksets with all Properties If Equal Return Index using IndexOf ImageSettings Export Ranges ImageSettings File Types ImageSettings Fit Direction Type ImageSettings Image Resolution ImageSettings Zoom Fit Type Inplace Family Check Faster Is Family Instance InPlace Join Two single Strings to One single String List All Views List Design Option Information List Detailed View Information for a List of Views List Duct and Pipe Related Elements List DWG Link Information List Elements in View across Revit Links List Groups List Import Information List Nodes in DYFs for an Entire Folder List of Duct and Pipe Categories as Built in names List of float double to list of Int List of Model Elements simplified with Annotation removed List of Model Elements simplified List of System Related Categories List Parameter Info with Shared Parameter GUIDs List Phase Information List Revit Link Instances Visible in Active View List Revit Links Visible in View List Room Names from API and show failures List Shared Parameter GUIDs only List the View Worksets of All Tags in Project List Unique Categories Present in Set of Elements List View Filter Information for View or Template List Views not on Sheets List.RemoveItemsFromOtherList Load Selection Set as Elements Make Unique Identifier and Set it to Parameter Match Link Level with Level in Host using Elevation Mirror an Element Mirror Element Using Origin and Normal Vector One Face to Polycurve Outline one Room to its PolyCurves Parse and Split String to a List Parse CSV Text of Elem IDs to Actual Revit Elements Parse Error Report and Provide Summary List Parse IFC File Parse Revit Error Report HTML and Output Summary Parse Revit Journal File Place Family by Point Cloud Place Free Instances to Match Project by Category Polycurve to Nearest Revit Level by Elevation Process Family Type Excel Sheet and Get a Value To Write Project Base Point Details Read CSV to Flat List Remove Characters from end of single String Remove Chars from End of Single String Remove Empty Strings from List Remove Equal Items from List and Preserve Counts Remove First and Last Characters from String Remove First Revision from Each Sheet Remove List from List by Item not Value Remove Revision From Sheet subnode for listMap Rename Families by Replacing Prefix Rename Families with a Prefix Rename View by Replacing Prefix Rename Views by Appending Selected Suffix Report Dynamo Package Details by Folder Report on Inplace Families Report Revit Link Worksets Report RVT Links Visible in Views on Sheets Room to Element Geometry Test for Preflight Rooms to PolyCurves Rotate Families Around Origin by Angle RVT Information for All RVTs in a Folder Search for Certain Build Number in Folder of RVTs Search for Generic Annotation on Sheet and Copy Id to Clipboard Search for Type Parameter Value in List of Elements and Return Elements Search One List Based on Second List and Get Values Select based on a single builtin name Send Element IDs to Clipboard Set Design Option by View Parameter Set Instance Parameter by Type Parameter Set List of Values to List of Elements for One Parameter Set One Parameter to Many Elements Set OriginalNesting Level Parameter for all FamilyInstances Set OriginalNestingLevel Parameter to Element Set Parameter of View based on a Character in Sheet Number Set Visible RVT Links to Parameter for Current View Set Workset for a Single Element Set Worksharing Display Mode for View Show Dependency Nodes for one DYF Show Element Workset as Internal db name Show List of Revit Links that are never visible on Sheets String Replace using RegEx String Search All Element.Parameters for a Single Element Summary and Node Search for a Folder of DYFs Summary of Selected Parameter Values for Duct and Pipe Elements Summary of System Related Elements Summary of Unique Values present in List Transpose Data within Excel Sheet UUID GUID Generator for Lists View Statistics View Templates for View List Write Empty Linked Tag Information to Excel Write Parameters from One Element List to Another Write Shared Parameter Check to Excel Write to Excel using only Data and File Path Inputs
It uses a two different methods to get Room Boundary outlines: first try is with a Clockwork node, next try is by Element.Geometry. It also sets the Room Number to the newly created Floor Comments parameter.
Just letting you all know that this new node has just been published in the Bakery package: Create Floors From Rooms v1.dyf
The scope: This ‘version 1’ node takes the Room elements, converts to Element.Geometry, grabs the face at the host level, gets the curves from the face, uses Konrad Sobon’s Group Curves node to assist with making the Polycurves, then matches the right Polycurve with the outer boundary using a bounding box method. Then, it feeds the outline to a Floor creation node (after matching link Level-host Level if necessary), and then sets Element Id, Room Number and Room Name as one string to the parameter you select.
You can use it across links with some other Bakery nodes too, which would look something like this:
Unfortunately, sometimes the builtin Element.Geometry node will fail to convert the Room to a solid. This warrants further investigation, but only affected about 15 rooms of 718 in this particular test. In the meantime, I simply report which rooms fail in the ‘geometry failure’ output:
Future improvements needed:
handle Element.Geometry failures with some other method
cut out Floor Openings where voids are present in the Room space
match Base Offsets by moving created floors to correct height
get approximate Room Height by Volume and drive or report desired Floor Thickness
Konrad has put together some very handy nodes to work with Revisions in Dynamo and Revit. I have packaged up a simple implementation of these in my Bakery package that takes a list of sheets, gets the first revision from that sheet, and then removes it (ie. unticks the Revisions on Sheet parameter). It looks like this:
This is useful for when you have copied or inserted sheets into your model, and they have automatically adopted a revision. You want to clean them up? Use the above, but make sure you filter that list of sheets first.
I use some a couple of these nodes from Bakery to grab views, filter them, then get the sheet from the view:
Also, for deleting revision entries from the Revision table: I have an alternate version if you want to test it. I made one that splits off the list of revisions away from the first revision (otherwise you get an error – presumably because Revit needs at least Revision there). You might need the custom node Eraser from the package manager. I used the Eraser tool and a giant list.create to make a tool that deletes everything unwanted from incoming models (ie, sheets, views, tags, schedules, lines, etc) but I’m still testing it. Essentially the code is the same as the attached one. As usual use this how you wish and post if you like. Regards, Troy
It is pretty difficult to change the Workset of Pipe Insulation. The Properties Palette allows you to change them one at a time (but not multiple), while the method I posted about previously can change multiple Pipe Insulations to a different Workset, but it didn’t have a nice filtering mechanism.
Enter Dynamo… I made a custom node that takes a list of Pipe Insulations and gives you the Host Pipe element:
Then, I packaged this up in another node that collects all Pipe Insulations, checks their Workset, finds their Host Pipe, and then saves those Pipes to a SelectionSet:
So, if you have Pipe Insulations on the wrong workset: 1. Install Bakery package in Dynamo 2. Run definition as in image above 3. Close Dynamo 4. Load the Saved Selection 5. Group these Pipes (which groups the Insulations too) 6. Change workset (it will have already adopted the current workset) 7. Ungroup 8. Done
Thanks to Konrad and Andreas for archi-lab and Clockwork packages respectively. I get a few comments about my Bakery package having a lot of dependencies, but I like the fact that I just need to install Bakery and I get archi-lab, Clockwork, Lunchbox etc. Its like a rough and ready deployment solution…
Oh, one more thing. You may notice in recent versions (like 0.8.2 RC) that there is now some custom path management for Dynamo resources:
Update Method 1: after seeing my post, Troy Wright kindly shared his take on this. It uses only one custom node – Eraser by Julien – and it also works for Revisions that have been ‘ticked’ as issued, so this is probably the more powerful method.
As always in Revit, it leaves behind the first row in the Revision Schedule… However, this method is more robust than deleting Revision Clouds as it also removes items appearing based on the “Revisions on Sheet” schedule. It is also much faster than laboriously using the Merge Up command one by one in the Revision Schedule.
Make a View parameter (Text) in Revit that will hold the list of RVT Links that are visible in a given view
Install Dynamo and my Bakery package
Go to the required View
Set up your definition as below and run it:
This will create a list and convert it to a single string with a line break between each entry, meaning that the resulting view Label in your View Title needs to account for it to ‘grow’ (vertical align to Top or Bottom as required).
This will need to be run each time you want to ‘update’ the visible Revit link parameter.
From here we could export a list of Element IDs to CSV, make a Selection Set by Elements using Clockwork, or use one of the Select in Revit nodes.
As you can see, to make a string list in a code block, you need to enclose list in curly brackets, divide with commas and use quotation marks around the entries themselves. More about code blocks at: http://dynamobim.com/cbns-for-dummies/
Its a long-winded title, but its only one Dynamo node… Just added to the Bakery package, called Collect Elements in Rooms and Show Detailed List. Basically, it takes a list of Rooms and a list of Elements and then tells you which Rooms those Elements are in. It also works across linked files, so you can have a fixture model, link in the Architectural containing Rooms, and use those to do the comparison.
Once we have the Room that an element lives in (mostly thanks to Konrad’s work on Family.InRoom, which I have altered a little bit here), we can do lots of things. I used a Cycle and LaceShortest to get a 1:1 list of Room:Element. This makes it easier to do things with the resulting combined lists. Like, one of the outputs of the node is a detailed 6 index list, which can be directly exported to Excel. The list in Excel can then be filtered by Room. You can choose two parameters from Rooms, two from the Elements, and it also gives you the Element Ids of both:
I could have added headers to the list in Dynamo, but I didn’t do it for this first version (yet):
We can also take a parameter from a Room (like Room Name or Room Number) and then write it directly into a parameter in the Elements, like this:
This shows the Mark parameter populated with Room Name:
Or, we can take two parameters from linked Architectural rooms, and drive two Shared Parameters in every element in the current model. I ran the following node to set parameters for about 2500 elements in just a couple of minutes:
Or, we can use another Bakery node to do a wildcard search and collect elements from one Category across multiple links, and then check against these:
While this is a basic implementation at this stage (and no doubt there may be some hiccups), it demonstrates a powerful concept: to be able to take a mixture of linked Rooms and/or linked Elements and determine their relationship, then export that data or use it to instantly drive other parameters in Revit.