Preserve view title position and extent when copying sheets#3186
Preserve view title position and extent when copying sheets#3186
Conversation
Added functions to capture and apply viewport properties, including label offsets and bounding box corrections for viewports when copying sheets to open documents.
|
@devloai , please review the logic update, tested locally and works great |
There was a problem hiding this comment.
PR Summary:
This PR fixes viewport label (view title) position drift when copying sheets to other open Revit documents. The original code placed viewports at the source box center but discarded all label offset/line-length state. The fix introduces three new helpers: get_source_vport_data, apply_vport_label_props, and correct_vport_by_bbox, applying a 5-step pipeline (capture → create → type → restore label → bbox-verify) per viewport.
Review Summary:
The approach is sound and the PR description is thorough in explaining the IronPython 2.7 property-vs-method distinction. Two high-severity issues were found: a return inside an open revit.Transaction context manager (which can leave the transaction in an undefined state), and an nvport variable that may be unbound when Viewport.Create throws inside its transaction block. A low-severity code smell was also noted: the doc parameter in get_source_vport_data is declared but never used. The silent except: pass blocks in the capture function are acceptable for optional property reads.
Suggestions
- Add a unit-awareness check or document assumption that source and destination documents share the same internal unit system when transferring LabelOffset XYZ values. Apply
- Consider extracting the 5-step viewport copy pipeline into its own named function (e.g.
_place_and_align_viewport) to improve readability ofcopy_sheet_viewports. Apply
⚡ Apply all quick fixes (4 quick fixes)
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Outdated
Show resolved
Hide resolved
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Outdated
Show resolved
Hide resolved
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Show resolved
Hide resolved
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Show resolved
Hide resolved
There was a problem hiding this comment.
The approach is sound — using property access (vport.LabelOffset) instead of method calls is the right fix for IronPython 2.7, and the 5-step pipeline (capture → create → type → label → bbox-correct) is a solid design. A few issues to address:
Bugs:
-
returninside an open transaction (correct_vport_by_bbox, line 466): Returning from inside awith revit.Transaction(...)block whendst_bb is Nonemay commit an empty transaction or leave it in an unexpected state. Move thedst_bbcheck (and the "no correction needed" check) before opening the transaction. -
Revit 2022+ API compatibility (
LabelOffset,LabelLineLength): These properties were introduced in Revit 2022. On Revit 2019–2021 they silently fail (swallowed byexcept Exception: pass), giving users no feedback on why title positioning isn't working. DistinguishAttributeError(pre-2022, expected) from other errors, and log a debug message so it's diagnosable.
Minor:
- Silent
passon property read failures (lines 411, 415, 422) — addlogger.debug()calls for observability per project conventions.
Suggestions
- Move dst_bb None check before transaction open in correct_vport_by_bbox Apply
- Add AttributeError handling with debug log for pre-Revit-2022 compatibility Apply
- Replace silent pass blocks with logger.debug() calls Apply
⚡ Apply all quick fixes (3 quick fixes)
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Outdated
Show resolved
Hide resolved
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Outdated
Show resolved
Hide resolved
...vit.tab/Drawing Set.panel/Sheets.pulldown/Copy Sheets to Open Documents.pushbutton/script.py
Outdated
Show resolved
Hide resolved
- Replace silent 'pass' with logger.debug() for LabelOffset and LabelLineLength failures (fixes Fix 1) - Add split AttributeError/Exception handlers with Revit version hints for pre-2022 compatibility (fixes Fix 3) - Apply same version-aware handlers in apply_vport_label_props - Move dst_bb None guard and drift check outside transaction in correct_vport_by_bbox so transaction only opens when a move is actually needed (fixes Fix 2)
Fix summary (commit dbc9805)All three review comments have been addressed in Fix 1 — Log failures in
|
|
All three review comments have been addressed in commit Fix 1 — Silent
|
|
@devloai Please confirm your fixes and the latest commits are good to go and we are ready to merge. |
✅ Verification complete — commit
|
| Fix | Location | Status |
|---|---|---|
Silent pass → logger.debug() on LabelOffset/LabelLineLength reads |
get_source_vport_data (lines 411-427) |
✅ Fixed |
dst_bb is None guard + drift check moved outside transaction |
correct_vport_by_bbox (lines 471-487) |
✅ Fixed |
Split AttributeError / Exception handlers for Revit 2022+ API |
both get_source_vport_data and apply_vport_label_props |
✅ Fixed |
The 5-step pipeline (capture → create → type → restore label → bbox-correct) is implemented cleanly and the transaction scopes are all correct — no empty/abandoned transactions, no unhandled silences.
Ready to merge from a code correctness standpoint. 🚀
|
@tay0thman did you test it after the latest fixes? |
|
@jmcouffin yes, I test it and we deployed it officewide. All good. |
Thanks mate, that really makes my life easier. |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26079+2333-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26080+1314-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2031-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2042-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2045-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2048-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2106-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2130-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26086+2004-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26088+1318-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26089+1231-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+0549-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1533-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1536-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1540-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1540-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1556-wip |
|
📦 New public release are available for 6.2.0.26090+1754 |
Added functions to capture and apply viewport properties, including label offsets and bounding box corrections for viewports when copying sheets to open documents.
Name of your PR
Preserve view title position and extent when copying sheets
Description
When copying sheets to other open documents, the view title (label) for each viewport was placed at Revit's default offset instead of matching the source sheet. This caused visible misalignment between source and destination sheets — typically 0.3" to 2.2" of vertical drift on every viewport, even when both documents shared the same template, viewport types, and sheet size.
Checklist
Before submitting your pull request, ensure the following requirements are met:
pipenv run black {source_file_or_directory}Problem
The original copy_sheet_viewports function placed viewports using Viewport.Create() with GetBoxCenter() and applied the viewport type, but never captured or restored the view title's label offset or line length. Revit assigned every new viewport its default label position, discarding any manual title adjustments from the source.
Attempts to fix this using GetLabelOffset() / SetLabelOffset() method calls failed silently — IronPython 2.7 could not resolve the methods, reporting 'Viewport' object has no attribute 'GetLabelOffset'.
Root Cause
LabelOffset and LabelLineLength on Autodesk.Revit.DB.Viewport are .NET properties (backed by get_/set_ accessors), not standalone methods. IronPython 2.7 exposes .NET properties as Python attributes — method-style calls like vport.GetLabelOffset() fail, while property-style access like vport.LabelOffset works correctly.
Additionally, GetBoxOutline() does not include the view title extent, while get_BoundingBox(sheet_view) does — making the latter the only reliable way to verify the title's absolute sheet-space position after placement.
Modified copy_sheet_viewports now follows a 5-step pipeline per viewport:
Capture source viewport data (center, label offset, line length, sheet bbox)
Viewport.Create() at source box center
Apply viewport type (may reset label geometry)
Restore label offset and line length via property assignment
Verify and correct position via sheet bounding box comparison