Skip to content

Bonsai: find a sheet's drawing by path when its data-id is stale - #9469

Open
theoryshaw wants to merge 1 commit into
IfcOpenShell:v0.9.0from
theoryshaw:pr/remove-drawing-stale-data-id
Open

theoryshaw wants to merge 1 commit into
IfcOpenShell:v0.9.0from
theoryshaw:pr/remove-drawing-stale-data-id

Conversation

@theoryshaw

Copy link
Copy Markdown
Member

Closes #9468.

The problem

SheetBuilder.remove_drawing locates a drawing's <g> by comparing data-id against the reference's STEP id:

for g in layout_root.findall(f"{SVG}g"):
    if g.attrib.get("data-id") == str(reference.id()):
        layout_root.remove(g)
        break

layout_tree.write(layout_path)

STEP ids only mean anything while the file keeps the numbering it had when the drawing was placed. Merging a project — or any round trip that renumbers entities — leaves every data-id in every layout pointing at nothing.

The loop then matches nothing, and layout_tree.write() runs regardless. The model loses the IfcDocumentReference while the layout keeps the drawing, and the layout is reserialised on the way out: a changed mtime and a whole-file diff for a removal that never happened. Since the Sheets panel reads the IFC, it shows the drawing gone, so the divergence stays invisible until something built from the layout disagrees.

The change

Look the group up by drawing path when the id lookup fails. The file a drawing points at survives renumbering; the id does not. Layout hrefs are relative to the layout and URL-encoded, so they are unquoted and joined before comparison.

Two smaller changes come with it:

  • Nothing is written when no group is found. The previous unconditional write is what disguised the failure as activity.
  • A warning names the layout that was left alone, instead of returning silently.

The same <g> already carries data-drawing (the drawing's GlobalId), and update_drawing_sizes resolves drawings through it — remove_drawing was the one place keyed on the unstable half of the pair. Matching on the path rather than the GlobalId keeps this self-contained: no reference-to-drawing lookup is needed, and it works on layouts written by any earlier version. Happy to switch it to a GlobalId match if you would rather add that lookup.

Testing

Three unit tests in src/bonsai/test/tool/test_sheeter.py: data-id match when ids are current, path fallback when they are stale, and None when the drawing is not on that sheet.

Also exercised on a real project whose ids had been renumbered by a merge. With the id match alone, none of the sheet's references resolved to a group; with the fallback, all of them did. Removing drawings from that sheet then emptied its layout as expected, with no warnings, and the removals showed up in a downstream tool that reads layouts — which is how the divergence was noticed in the first place.

Closes IfcOpenShell#9468.

SheetBuilder.remove_drawing located the drawing's <g> by comparing data-id
against the reference's STEP id. Those ids only mean anything while the file
keeps the numbering it had when the drawing was placed: merging a project, or
any round trip that renumbers entities, leaves every data-id in every layout
pointing at nothing.

The loop then matched nothing and layout_tree.write() ran anyway, so the model
lost the IfcDocumentReference while the layout kept the drawing - and the layout
was reserialised, giving a changed mtime and a whole-file diff for a removal
that never happened. Bonsai's own Sheets panel reads the IFC and showed the
drawing gone, so the divergence stayed invisible until something built from the
layout disagreed.

Look the group up by drawing path when the id lookup fails; the file a drawing
points at survives renumbering. Nothing is written when no group is found, and a
warning names the layout that was left alone rather than failing silently.

The same <g> already carries data-drawing (the drawing's GlobalId), and
update_drawing_sizes resolves drawings through it, so remove_drawing was the one
place keyed on the unstable half of the pair. Matching on the path rather than
the GlobalId keeps this self-contained - no reference-to-drawing lookup is
needed - and works on layouts written by any earlier version.

Tested on a project whose entity ids had been renumbered by a merge: with the
id match alone none of its references resolved, and with the fallback all of
them did. Removing four drawings from a sheet then emptied the layout as
expected, with no warnings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bonsai: removing a drawing from a sheet silently leaves it in the layout when data-id no longer matches the reference's STEP id

1 participant