I guess this is a Bonsaism but it makes sense as named profiles are
significant, and it isn't the first time materials and profiles have
been treated as "rooted" in a sense. It's also annoying to keep on
having my profile library drop off when I'm just switching profiles.
If you move a wall, and that wall has features (e.g. openings), it's
desirable to also move those openings (because they are invisible). This
is a special exception to `should_transform_children` because the
definition of the feature (opening) is inherently tied to the parent
(wall).
What wasn't considered is that this would typically then also move
subchildren of the features (e.g. fills like doors). I'm surprised
nobody caught this earlier.
I did also consider another approach where if you move a wall, it moves
all unfilled openings, and if you move a door which fills a opening, it
moves the opening too. Intuitively it sounds nice, but it doesn't work
because:
- Openings can have multiple fillings. If you move all fillings, they
all fight to move the openings.
- All logic about children goes one way: a placement may have child
placements relative to it. This breaks the convention (if moving a door
instead moves its opening) which can make brains explode.
- It starts to conflate rules about relative / referenced placements
with spatial decomposition. We assume all IFCs are valid and follows the
convention of relative placement but we cannot guarantee this. This also
leads to brain explosion.
TessellateElements patch was failing because it was relying on optionality of `edges` argument. Though argument itself is currently useless and not used in the code.
It's py.types requirement, similar to 6e2edbf
Example issue without __all__:
import ifcopenshell
import ifcopenshell.api.project
# "create_file" is not exported from module "ifcopenshell.api.project"
ifcopenshell.api.project.create_file()