Some of you may be familiar with the selector syntax. It looks like this: .IfcWall
means you want to select all IfcWalls (and subtypes). .IfcWall[Name=Foo]
means you want to select all walls named Foo. It is used in a number of places: drawing object filters, model loading filters, clash set filters, IfcCSV export filters, Blender saved search groups, IfcPatch recipes, etc.
The selector syntax was created at a time when nothing existed and I tried to do my best to come up with a way to select objects that could handle attributes and properties, and slowly things like materials, guids, and so on were bolted on. Since then, I have learned a lot about how people have used the syntax and I feel as though it has a lot of flaws that make it inconvenient. In addition, a lot of people have been asking for an improved user interface for these selectors and also the ability to have saved searches. There is a really complex UI already built with a lot of effort but I feel it could be heavily simplified:
I've been working on redesign a new selector syntax intended to supersede the old one for most common users. The goals is to be simple to read, simple to write, and much more useful with the tradeoff that it is less explicit and doesn't accommodate complex AND/OR groupings. It is inspired by the "facets" in IDS, which have been designed over many months by buildingSMART working groups who have collectively worked out usecases on how to do "applicable entity filters". Although it is very similar to IDS (which is another benefit, since IDS specifies contractual requirements you want to be able to recreate those applicability filters) it also contains a few upgrades of my own (my personal complaints about the shortcomings in IDS).
It works like this, you can specify a list of "filters" separated by commas. A filter can filter an individual instance, a class, attribute, type, material, property, classification, or location. Filters are chained one after another. Let's see some examples:
# All IfcElements. Yep, that's it! Nothing else. Literally just "IfcElement".
IfcElement
# All walls and slabs.
IfcWall, IfcSlab
# All walls and slabs made out of concrete (checks any IfcMaterial with matching name or category)
IfcWall, IfcSlab, material=concrete
# A single element. Yep, just the GlobalId, nothing else! Easy.
325Q7Fhnf67OZC$$r43uzK
# A bunch of arbitrary elements.
325Q7Fhnf67OZC$$r43uzK, 2VlJ7nbF5AFfQQuRvSWexT
# All walls except that one element.
IfcWall, ! 325Q7Fhnf67OZC$$r43uzK
# All elements except for walls.
IfcElement, ! IfcWall
# Any doors named D01, notice how attributes match the IFC Attribute naming exactly
IfcDoor, Name=D01
# Any doors with the naming scheme of D followed by two numbers:
IfcDoor, Name=/D[0-9]{2}/
# Any 2 hour fire rated wall
IfcWall, Pset_WallCommon.FireRating=2HR
# Any load bearing structure
IfcWall, IfcColumn, IfcBeam, IfcFooting, /Pset_.*Common/.LoadBearing=TRUE
# Any element with a fire rating property
IfcElement, /Pset_.*Common/.FireRating != NULL
# Any walls of wall type WT01 on level 3 (we quote Level 3 since it has a space)
IfcWall, type=WT01, location="Level 3"
# Any maintainable product according to Uniclass tables
IfcElement, classification=/Pr_.*/
# Notice how there are intuitive rules that class and instance filters are OR whereas other filters are AND
# So here is any wall or slab except that one element that has a material of concrete and has a 2 hour fire rating
IfcWall, IfcSlab, ! 325Q7Fhnf67OZC$$r43uzK, material=concrete, /Pset_.*Common/.FireRating=2HR
# Finally, you can union facet lists together. So here is all concrete slabs, as well as all doors (regardless of concrete)
IfcSlab, material=concrete + IfcDoor
# Here's another example of unioning facet groups.
# All doors and window, and all concrete walls and slabs, plus that one random element
IfcDoor, IfcWindow + IfcWall, IfcSlab, material=concrete + 325Q7Fhnf67OZC$$r43uzK
# Locations bubble up the hierarchy. So if a pump is in a space and that space is on Level 3, then you can say "all pumps on level 3" which will include that pump in the space.
IfcPump, location="Level 3"
I hope you can see from the sample that it is a lot more intuitive and uses names rather than GlobalIds were possible (in the old selector for example selecting things like "stuff on level 1" is very difficult). It's also much easier to read (no nested brackets () and | and & and little dots . that people keep on missing) and easier to copy paste (no # prefix on GlobalIds). Despite the lack of explicit AND/OR I believe the chaining and unions should satisfy most usecases. It's also "shorter" for many usecases compared to the old selector. Also you can either leave values unquoted e.g. material=concrete or quoted material="Isn't this great" or regex material=/CON[0-9]*/.
This also means that it will now be easier to make a gentler UI for it :) Saved searches here we come!