FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix #8603: drawing underlay renders the previously active drawing's objects by theoryshaw · Pull Request #9307 · IfcOpenShell/IfcOpenShell · GitHub

Fix #8603: drawing underlay renders the previously active drawing's objects - #9307

Open
theoryshaw wants to merge 2 commits into
IfcOpenShell:v0.8.0from
theoryshaw:fix-8603-underlay-render-visibility
Open

Fix #8603: drawing underlay renders the previously active drawing's objects#9307
theoryshaw wants to merge 2 commits into
IfcOpenShell:v0.8.0from
theoryshaw:fix-8603-underlay-render-visibility

Conversation

Copy link
Copy Markdown
Member

Fixes #8603.

The bug

A drawing created after a different drawing was created earlier in the session gets an underlay showing the previous drawing's objects, rendered with the current drawing's camera. A ROOF plan rendered after a 1ST FLOOR plan comes out as the floor plan seen from the roof camera — the roof is simply absent, so you see down to the slab. The first drawing of a session is always correct.

Root cause

Blender.sync_render_visibility wrote hide_render with bpy.data.objects.foreach_set(...). foreach_set writes the DNA directly and skips the RNA update, so nothing tags the depsgraph — the evaluated visibility stays a render behind and bpy.ops.render.render() draws the previous drawing's object set. The camera is unaffected, since camera changes go through normal RNA assignment.

This is why it resisted diagnosis: visible_get(), obj.hide_render and context.visible_objects all read the DNA we had just written, so every python readback reports correct state. Instrumenting right up to the render.render() call showed the correct camera and the correct 276-object renderable set — and it still rendered the other drawing.

It also explains why the previously attempted workarounds all failed (use_persistent_data = False, view_layer.update(), evaluated_depsgraph_get(), frame_set(), warm-up renders, toggling the render engine): they flush or rebuild, but nothing re-tags objects that were never marked dirty.

The fix

Assign hide_render through RNA so each object is tagged, with an equality check so only objects that actually change are written.

Cost on a 3041-object model: 0.65s for the first drawing (2982 changes), 0.06s for the next (248 changes). Note the visible_get() scan still runs over every object, exactly as before — that part is unchanged.

Verification

Tested on a real model (Highland Haven), on both bpy.ops.bim.create_drawing and SHIFT+click print_all batches.

Both underlays render at the same 246 px/m, so aligning them on camera position and pixel-diffing is a direct measure of "is this the other drawing's image":

before after
ROOF underlay vs 1ST FLOOR underlay, aligned 0.99% of pixels differ 67% differ
topmost building object at render time IfcWall/Wall.079 (floor plan) IfcRoof/Roof.007

Controlled A/B: the renderable fingerprint going into the render was byte-identical between the failing and passing runs (n=276 md5=c819482e421d), same camera, same clip band. The only variable changed was foreach_set → RNA assignment, and the output flipped from wrong to correct.

Second commit

Unrelated bug noticed in the same code path: CreateDrawing saves should_use_underlay_cache into a local that is never read again — and does it inside the loop, so each drawing overwrites it. Any batch print left the user's underlay cache setting disabled until they toggled it back by hand. Hoisted the save/disable out of the loop and restored the value alongside the existing active-drawing restore.

Note on the previous diagnosis

The original issue attributed this to bpy.ops.render.render() carrying state across calls under EEVEE-Next and suggested an upstream Blender report. That was wrong — see #8603 (comment). In particular, re-running a single drawing does not fix it (the rerun produces a pixel-identical wrong image), and the visible-object sets were never identical. Draft PR #8900 restructures print_all into a modal operator on that basis; it does not address this, since the failure reproduces across two separate operator invocations with a full event loop in between.

🤖 Generated with Claude Code

theoryshaw and others added 2 commits August 15, 2026 08:59
…'s objects

sync_render_visibility wrote hide_render with
bpy.data.objects.foreach_set(), which writes the DNA directly and skips
the RNA update. Nothing tags the depsgraph, so the evaluated visibility
stays a render behind: after switching drawings, bpy.ops.render.render()
draws the previous drawing's object set with the new drawing's camera.
For a roof plan rendered after a floor plan, the underlay came out as the
floor plan seen from the roof camera.

The camera was always correct and every python-visible flag read back
correct, because visible_get() and hide_render read the DNA we had just
written - only the evaluated copy was stale. That is why clearing
use_persistent_data, calling view_layer.update(), evaluated_depsgraph_get(),
frame_set() or toggling the render engine made no difference, and why
rendering the same drawing twice reproduced the same wrong image.

Assign hide_render through RNA instead, which tags each object. The
equality check keeps it cheap by only writing objects that actually
change: on a 3041 object model this is 0.65s for the first drawing
(2982 changes) and 0.06s for the next (248 changes).

Verified on both bpy.ops.bim.create_drawing and print_all batches by
aligning the two underlay PNGs on camera position at equal px/m and
diffing: the roof underlay went from 0.99% of pixels differing from the
floor plan underlay (ie. the same image) to 67%.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CreateDrawing disables should_use_underlay_cache so every drawing in a
print_all batch is re-rendered, but it saved the original value into a
local that was never read again - and it did so inside the loop, so each
drawing overwrote it. The user's setting was left disabled after any
batch print until they toggled it back by hand.

Hoist the save and the disable out of the loop, and restore the original
value alongside the existing active-drawing restore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

Drawing underlay renders the previously active drawing's objects (stale hide_render)

1 participant


Back | FazBrowse Home | New Git URL