Commit Graph

20435 Commits

Author SHA1 Message Date
Stephen Boddy 7036ea5c33 Fix ty-ios type-check errors (ifcopenshell-python side)
poe ty's sequence only reaches ty-ios once ty-bonsai passes, so these
never surfaced until now:

- util/alignment.py: drop the stale `include_referent=False` kwarg from
  add_zero_length_segment() - that parameter was removed from the function's
  signature in 45ea5eb07 but this caller in a different file was missed,
  leaving a latent TypeError if this code path is ever exercised.
- ifcopenshell_wrapper.pyi: add the optional trailing `logger` parameter to
  parse_ifcxml/open/construct_iterator*, matching the real SWIG signatures
  in src/ifcwrap/*.i (all declare `Logger& logger = Logger::Root()`) that
  the hand-maintained stub never picked up.
- ifcopenshell/__init__.py: remove a stale `ty: ignore[unknown-argument]`
  comment that ty confirms is no longer suppressing anything.
- assign_cost_item_quantity.py: OPERATORS mixes 2-arg binary operators with
  the 1-arg `operator.neg` (for ast.USub), but FormulaEvaluator has no
  visit_UnaryOp so USub can never reach this lookup via visit_BinOp.
  Suppressed at the call site rather than touching the dict, since this
  looks like scaffolding for unary-minus support rather than dead code.
- Explicit submodule imports (ifcopenshell.geom / api.alignment / util.unit
  / api.aggregate / api.context / api.spatial) added where accessed but
  only reachable by accident of import order.

(cherry picked from commit d5e890bccd)
2026-07-25 23:15:22 +10:00
Stephen Boddy 17177d5f1c Fix remaining ty type-check errors in tool.py, product.py, railing.py
- tool.py: drop the `-> int` annotation on the Parametric interface's
  get_geom_generation stub; its `pass` body implicitly returns None, which
  ty can't reconcile with the runtime @interface/@abstractmethod rewriting
  it never sees statically. Matches the file's other stubs (-> None).
- railing.py: qualify the "BIMRailingProperties" string annotations as
  "prop.BIMRailingProperties" on the two functions using it, since the bare
  name was never imported into this module's namespace.
- product.py: suppress ty's missing-argument errors on
  copy_z_rotation_to_selected's Surveyor.get_z_rotation/set_z_rotation
  calls with targeted ty: ignore comments. The function is unused and its
  two dependencies were never implemented on the concrete Surveyor tool;
  left as-is rather than deleted or implemented.

(cherry picked from commit 9f848a73e1)
2026-07-25 23:15:22 +10:00
Stephen Boddy a941c664e1 Fix ty type-check errors: missing imports and unresolved names
- gizmos.py: TYPE_CHECKING-guard `import bmesh` for the string-literal
  annotation in build_schematic_mesh; suppress the still-unresolved
  gizmo_textures import in TexturedQuadGizmoMixin (WIP dependency, not dead
  code).
- model/__init__.py: register the `decorator` submodule, which unregister()
  already calls (would have raised NameError on addon disable).
- mep.py / tool/model.py: add explicit imports for bonsai.core.geometry and
  bonsai.core.model, previously only reachable by accident of import order.
- Test files: add explicit ifcopenshell.api.pset / ifcopenshell.util.element
  submodule imports used but not imported.

(cherry picked from commit 4fb8af2278)
2026-07-25 23:15:22 +10:00
Richard Brice a674dc5641 Fixes bug with fallback position introduced in 206cd6bb
(cherry picked from commit ade03b171a)
2026-07-25 23:15:22 +10:00
Richard Brice 9fc01de468 Stationing referent can optionally be located relative to the basis_curve (default) or the alignment curve
(cherry picked from commit b5c1b81ede)
2026-07-25 23:15:22 +10:00
Richard Brice 26c6281cc7 Locates positioning referent on the alignment curve, not the basis curve
(cherry picked from commit 47a20f0c7c)
2026-07-25 23:15:22 +10:00
Richard Brice 3cb614485a Fixes double unit conversion when convert-back-units are used
(cherry picked from commit 52d894298e)
2026-07-25 23:15:22 +10:00
Petru Conduraru 9621388953 ifcpatch: correct the AGS2IFC docstring example
The example block was copy pasted verbatim from ExtractPropertiesToSQLite,
so it named the wrong recipe and wrote a .sqlite file. These docstrings are
what ifcpatch surfaces as CLI and UI help, so anyone following the example
for AGS2IFC got a recipe name that does not match the one they selected.

Also state that the input file is not read and that a new IFC4X3 model is
built, since that is not obvious from the signature and the recipe creates
its own project rather than patching the one passed in.

Generated with the assistance of an AI coding tool.
2026-07-25 19:46:32 +10:00
Petru Conduraru 89523999b3 Bonsai: fix UnboundLocalError crash in polyline angle calculation
angle_round_threshold was only assigned inside the `distance > 0`
branch of calculate_distance_and_angle, but read unconditionally
whenever should_round is True. When the mouse sample coincides with
the last placed point (distance == 0), such as the first mouse move
after placing a wall's start point on a YZ plane view, this crashed
the modal wall tool.

angle_round_threshold is a fixed cutoff unrelated to whether distance
is currently zero, so it is now assigned once before the branch.

Fixes #8597.

Generated with the assistance of an AI coding tool.
2026-07-25 13:57:51 +10:00
Petru Conduraru 51ab38de27 Fix ci-bonsai-daily: configure unmerged_blobs mock in git_mergetool tests (#8574)
test_returns_none_when_report_file_absent/empty build a MagicMock repo
without configuring index.unmerged_blobs(), so it returned a truthy
MagicMock and git_mergetool's load-bearing "unresolved conflicts remain"
fallback (tool/ifcgit.py:646-647) returned that list instead of None -
failing "assert [] is None". The production fallback is correct and
intentionally left untouched; the tests just misrepresented the
"mergetool resolved cleanly" scenario they are named for. Set
mock_repo.index.unmerged_blobs.return_value = {} in both.

Verified in headless Blender: test/tool/test_ifcgit.py::TestGitMergetool
2 failed / 1 passed -> 3 passed.

This change was made with the assistance of an AI tool.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 23:21:18 +01:00
Petru Conduraru fbe36532a0 ifcdiff: fix crash when exporting property diffs to JSON
DeepDiff's dictionary_item_added/set_item_added results are a
deepdiff.helper.SetOrdered instance, which subclasses orderly_set's
StableSetEq rather than the OrderedSet class json_dump_default checked
for, so the property relationship check always crashed export() with
"Object of type SetOrdered is not JSON serializable". Check against
StableSet, the common base class shared by every orderly_set set
flavour, instead.

Fixes #8905

Generated with the assistance of an AI coding tool.
2026-07-25 07:47:13 +10:00
Andrej730 2f1b2f9638 ifcwrap: use swig shadowing for keeping reference to Element 2026-07-24 21:51:21 +05:00
Andrej730 9001cca078 ifcwrap: exclude internal geometry pointers
Still available as `int(xxx.this)`.
2026-07-24 21:51:21 +05:00
Andrej730 018695a2a9 file.ctor: use swig shadowing 2026-07-24 21:50:49 +05:00
Andrej730 2b7f55c1a0 stub: fixes after data model changes 2026-07-24 21:50:49 +05:00
Andrej730 9a62bf3c11 stub: updates after plugins were introduced 2026-07-24 21:50:49 +05:00
Andrej730 34f8a2c54e Serialized.setFile: use file ref instead of pointer for safety 2026-07-24 21:50:49 +05:00
Andrej730 310eaedc8e stub: group plugin search paths methods 2026-07-24 21:50:49 +05:00
Andrej730 3c381b0d00 stub: add updated get_info_cpp 2026-07-24 21:50:49 +05:00
Andrej730 4dd39ee918 downstream: stub: drop abstract_arrangement (158756e921)
And also gnore delete_same_facet_edge_pairs as it's more of an interanl API.
2026-07-24 21:50:49 +05:00
Andrej730 af32884731 downstream: stub: add logger_or_root arg type 2026-07-24 21:50:49 +05:00
Andrej730 a20c7484e5 downstream: stub: add missing arrange_polygon_settings (158756e921) 2026-07-24 21:50:49 +05:00
Andrej730 f7aa4504ec ifcwrap: ignore schema registry and plugins related structs and functions 2026-07-24 21:50:49 +05:00
Andrej730 c91d6d54bc new_IfcBaseClass: use ref for safety 2026-07-24 21:50:49 +05:00
Andrej730 189eeae719 register_schema: use ref to avoid segfaults
E.g. `register_schema(None)` from Python was resulting in a segfault
2026-07-24 21:50:49 +05:00
Andrej730 a954170927 downstream: ifcwrap: exclude interal geometry pointers
Still available as `int(xxx.this)`.
2026-07-24 21:50:49 +05:00
Andrej730 6fb5a619df downsteram: IfcSchema: provide arg names for register_schema, schema_by_name 2026-07-24 21:50:49 +05:00
Andrej730 849123acee downstream: ifcwrap: hide guess_file_type from Python as unused 2026-07-24 21:50:49 +05:00
Andrej730 9544641e41 downstream: stub: sync added/removed symbols 2026-07-24 21:50:49 +05:00
Andrej730 ec558dc57e stub: add logger_or_root arg type 2026-07-24 18:37:25 +05:00
Andrej730 2db5658386 ifcwrap: hide guess_file_type from Python as unused 2026-07-24 18:22:59 +05:00
Andrej730 88c8bd032f ifcwrap: fix breaking validate_stub (824c1fc)
It's ignoring underscore prefixed functions as not actually used.
Removing underscore to keep it happy without adding new exceptions.
2026-07-24 18:00:54 +05:00
Andrej730 3d8654acfd ifcwrap: ignore newly added conversion settings structs (183e4c4) 2026-07-24 17:59:44 +05:00
Andrej730 4a20b67038 IfcSchema: provide arg names for register_schema, schema_by_name 2026-07-24 16:48:51 +05:00
Andrej730 a586c7f695 black . 2026-07-24 15:43:59 +05:00
dependabot[bot] 1906481a01 Bump svelte from 5.53.6 to 5.55.8 in /src/ifctester/webapp
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.53.6 to 5.55.8.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/svelte@5.55.8/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.55.8
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 15:06:42 +05:00
dependabot[bot] 73bf238232 Bump uuid and hyperid in /src/ifctester/webapp
Removes [uuid](https://github.com/uuidjs/uuid). It's no longer used after updating ancestor dependency [hyperid](https://github.com/mcollina/hyperid). These dependencies need to be updated together.


Removes `uuid`

Updates `hyperid` from 3.3.0 to 4.0.0
- [Release notes](https://github.com/mcollina/hyperid/releases)
- [Commits](https://github.com/mcollina/hyperid/compare/v3.3.0...v4.0.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 
  dependency-type: indirect
- dependency-name: hyperid
  dependency-version: 4.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 15:06:21 +05:00
dependabot[bot] a85d5cc990 Bump lxml from 4.9.1 to 6.1.0 in /src/ifcopenshell-python
Bumps [lxml](https://github.com/lxml/lxml) from 4.9.1 to 6.1.0.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-4.9.1...lxml-6.1.0)

---
updated-dependencies:
- dependency-name: lxml
  dependency-version: 6.1.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 15:04:15 +05:00
dependabot[bot] c16aec2cb0 Bump ws and engine.io-client in /src/ifctester/webapp
Bumps [ws](https://github.com/websockets/ws) and [engine.io-client](https://github.com/socketio/socket.io). These dependencies needed to be updated together.

Updates `ws` from 8.17.1 to 8.21.0
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.17.1...8.21.0)

Updates `engine.io-client` from 6.6.3 to 6.6.6
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io/compare/engine.io-client@6.6.3...engine.io-client@6.6.6)

---
updated-dependencies:
- dependency-name: ws
  dependency-version: 8.21.0
  dependency-type: indirect
- dependency-name: engine.io-client
  dependency-version: 6.6.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 15:03:56 +05:00
dependabot[bot] 76be31561e build(deps-dev): bump immutable in /src/ifctester/webapp
Bumps [immutable](https://github.com/immutable-js/immutable-js) from 5.1.5 to 5.1.9.
- [Release notes](https://github.com/immutable-js/immutable-js/releases)
- [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/immutable-js/immutable-js/compare/v5.1.5...v5.1.9)

---
updated-dependencies:
- dependency-name: immutable
  dependency-version: 5.1.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 15:01:00 +05:00
dependabot[bot] a111c68d44 Bump devalue from 5.6.4 to 5.8.1 in /src/ifctester/webapp
Bumps [devalue](https://github.com/sveltejs/devalue) from 5.6.4 to 5.8.1.
- [Release notes](https://github.com/sveltejs/devalue/releases)
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/devalue/compare/v5.6.4...v5.8.1)

---
updated-dependencies:
- dependency-name: devalue
  dependency-version: 5.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 14:59:19 +05:00
dependabot[bot] 279e16f2ab build(deps-dev): bump tar from 7.5.16 to 7.5.21 in /src/ifctester/webapp
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.16 to 7.5.21.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.16...v7.5.21)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.21
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 14:58:54 +05:00
dependabot[bot] 3d68d0f0e5 build(deps-dev): bump postcss in /src/ifctester/webapp
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.4 to 8.5.22.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.4...8.5.22)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.22
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 14:58:50 +05:00
Petru Conduraru e759135608 Bonsai: cache-bust webui static assets so shipped JS/CSS changes reach users
Browsers were caching /static/js and /static/css for the standalone
webui (costing, gantt, drawings, index, demo pages) indefinitely, so a
shipped JS fix (e.g. the Download CSV button) would only reach a user
after a manual hard refresh.

Two changes, applied consistently across all five webui pages.

1. Every locally served link/script tag in the pystache templates now
carries a ?v=<bonsai version> query string, falling back to a static
asset mtime hash when BONSAI_VERSION isn't set (e.g. running
sioserver.py standalone). Since get_bonsai_version() includes the
build's commit hash, the token changes on every shipped update.

2. Responses under /static/ and /jsgantt/ now carry
Cache-Control: no-cache, must-revalidate. This covers what query
stamping alone can't reach: cost.js and gantt.js statically import
utilities/costui.js by a fixed relative path with no query string, so
that nested module still needed server side revalidation to pick up
changes.

Verified against a live aiohttp instance of sioserver.py: rendered
HTML for all five routes shows the stamped URLs, and the token
changes when BONSAI_VERSION changes between two server runs. A
conditional GET against a static file with a stale If-Modified-Since
header confirms the cheap 304 revalidation path still works.

Also used this instance plus a real headless Chromium (Playwright) to
click test the previously untested Download CSV button on the costing
page. The ribbon renders it correctly, and clicking it (with a
synthetic cost-items table injected into the DOM to stand in for a
connected Blender's data) triggers a real Blob download with the
correct filename and CSV content. No bug found, the button works as
intended.

AI-generated with Claude Code.
2026-07-24 11:32:34 +02:00
Petru Conduraru 1df738d968 ifc5d: match cost schedule export columns to the Bonsai cost panel (#6251)
Stefano's final ask on #6251 was specific: the ODS/XLSX export should
show exactly what the cost panel shows, ID (Identification), Name,
Quantity, Value, Total Cost, no more, no less. The previous fix in
this PR removed the internal bookkeeping columns but still exported
Description, Unit and a per-category cost breakdown (Labor Cost,
Material Cost, etc), none of which appear in the panel.

Presentation formats (.ods/.xlsx) now use an explicit allow-list of
columns instead of a block-list of internal ones, and relabel headers
to match the panel's own wording (ID / Value / Total Cost). The .csv
format is unchanged: csv2ifc still reads back the extra bookkeeping
columns for the import round trip, which is why it keeps them.

Also add a "Download CSV" button to the browser costing view
(Generate spreadsheet browser), which previously only offered a
clipboard-based Copy Selected. It reuses the already-rendered table
(respecting the user's column visibility settings) and triggers a
real file download, dropping only the UI-only Actions column.

AI-generated with Claude Code; reviewed and tested by Petru Conduraru.
2026-07-24 11:32:34 +02:00
Petru Conduraru 98c28a1f30 ifc5d: professional grade ODS/XLSX cost schedule export #6251
Three defects reported against the Costing tab export:

1. XLSX export crashed with ModuleNotFoundError: xlsxwriter was never
   bundled with Bonsai. Port the writer to openpyxl, which ifccsv
   already uses and Bonsai already ships, so it works out of the box.
2. Every ODS cell was written as a string (numbers as text), and the
   formula branch was dead code: it compared against 'Total Price' /
   'Rate Subtotal' while the headers are 'TotalPrice' / 'RateSubtotal'.
   Numeric columns are now typed float cells and TotalPrice becomes a
   real formula: Quantity*RateSubtotal on leaf items, SUM over the
   direct children's TotalPrice cells on sum items.
3. Internal bookkeeping columns (Id, ItemIsASum, Hierarchy, Index,
   Quantities) leaked into the presentation formats. ODS/XLSX now hide
   them; CSV keeps them since csv2ifc consumes them for the round trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 11:32:34 +02:00
Petru Conduraru 21122c0d28 Resolve nested complex quantity paths in the selector (#2041)
get_element_value could not reach the members of an IfcPhysicalComplexQuantity
(or IfcComplexProperty) by their natural path. util.element expands a complex
quantity into a dict whose nested members live under a "properties" sub-dict,
but the selector's dict navigation only looked at the top level, so
"Qto_Custom.Layer1.Width" returned None and IfcCsv exported nothing for it.
Only the internal "Qto_Custom.Layer1.properties.Width" path worked.

When a key is not a direct member of the value dict, descend into its
"properties" sub-dict so nested quantities/properties resolve with the
natural "Set.Complex.Nested" path. Direct keys still take priority, so the
explicit ".properties." path stays backward compatible and the regex branch
is untouched.

Verified: Qto_Custom.Layer1.Width -> 0.1 and Layer1.Height -> 2.5 (were
None), the sibling simple NetArea still resolves, the legacy .properties.
path still works, and IfcCsv now exports the nested value. test_selector.py:
38 passed (adds test_selecting_a_nested_complex_quantity).

Generated with the assistance of an AI coding tool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 10:31:38 +02:00
falken10vdl d63a99b70c Merge pull request #8342 from falken10vdl/style-flat-pretty-toggle
Style flat pretty toggle
2026-07-24 09:56:24 +02:00
falken10vdl f2d8f17f88 Remove unused has_any_textures return from restore_material_style_types 2026-07-24 09:47:16 +02:00
falken10vdl e9b619e3fb Remove unused _get_shader_label helper method 2026-07-24 09:41:23 +02:00