Commit Graph

20993 Commits

Author SHA1 Message Date
Ryan Schultz 9fd119bf95 Bonsai: custom display names for links
Each link row draws an editable display_name (double-click to rename)
with the file path as placeholder while unset, so several links of the
same file can be told apart. The name persists in the same Description
JSON blob as the filter and loaded state (new name key, written at
save time and by reload_link), restores on project open, and plain
legacy strings still decode unchanged. Decode tests updated to the
four-tuple with a name round-trip case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:37:57 -05:00
Ryan Schultz 94ba41d9ea Bonsai: unit tests for link filter helpers + refactor notes
Adds test/tool coverage for the pure link helpers:
encode/decode_link_filter (plain round-trip, JSON promotion for
exclude and loaded, legacy and malformed decode) and
get_link_cache_paths (legacy names, include-only hash pinned to the
pre-exclude formula so existing caches stay valid, and the
same-include/different-exclude collision case the key exists to
prevent). 12 tests, verified passing under Blender python.

Documents the deliberate undo-system exemption on the link transform
autosave handler, and records the deferred refactors in the dev note:
an upstream exclude= parameter for filter_elements (separate
ifcopenshell-python PR) and the skipped core/tool interface ceremony.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:06:15 -05:00
Ryan Schultz cd5897d10d Note STEP p21e3 as the long-term serialization target in the dev note
ANCHOR/REFERENCE sections and anchor tags (unimplemented in
ifcopenshell, #668) are the standards-track home for the link
reference and its metadata; records the migration path, the identity
and archive-transport design points the branch already conforms to,
and the scope that would remain app-level regardless.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 09:31:02 -05:00
Ryan Schultz e0b97c574b Bonsai: auto-load links that were loaded and visible at save time
At IFC save time each link reference Description gains a loaded flag
(is_loaded and not is_hidden), extending the same JSON blob that
carries the include/exclude filter; plain legacy strings decode as
no-autoload. On project open, load_linked_models_from_ifc replays
flagged links via load_link after restoring the list, warning and
skipping missing files so they cannot break the open.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 09:08:51 -05:00
Ryan Schultz 429cab8b1b Note Include/Exclude UI labels in the dev note
The displayed labels changed from Query to Include to pair with
Exclude; the property identifier stays query for script and
persistence compatibility.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 18:05:10 -05:00
Ryan Schultz 328ca6d387 changed 'Query' to 'Include' 2026-07-10 16:24:56 -05:00
Ryan Schultz 12ecdf2aba Bonsai: reload-all-links button in the Links panel header
bim.reload_all_links reloads every loaded linked model via
argument-less reload_link calls, so each link replays its stored
path/query/exclude and rebuilds its cache from disk. Unloaded links
are left alone. Drawn as a refresh button beside Link IFC.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 15:51:59 -05:00
Ryan Schultz 8f9164bf72 Bonsai: include/exclude filter pair for linked models
A single selector query cannot express set differences (the grammar
only unions groups, and the parent facet cannot negate), so links now
carry an Exclude query beside the include, mirroring the drawing
Include/Exclude pattern: final set = include (or the default set when
empty) minus exclude. Applied in LoadLinkedProject and per link in
create_drawing so prints match the viewport.

The cache key hashes both strings when an exclude exists - keying on
the query alone would let same-include/different-exclude links serve
each other's geometry. Include-only filters keep the pre-exclude hash
and empty filters the legacy names, so existing caches stay valid.
Persistence in IfcDocumentReference.Description stays backwards
compatible: a plain include is stored as-is, an exclude promotes the
value to a small JSON blob, and non-JSON decodes as a legacy include.

The Exclude field appears in Link IFC and the Reload Link dialog
(carried through the file browser round trip, SKIP_SAVE like the rest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 15:26:33 -05:00
Ryan Schultz 403308a923 Bonsai: keep linked models cut linework in BISECT cut mode
BISECT cut mode deletes the serializer cut linework and regenerates it
by bisecting Blender mesh objects, which linked models do not have -
their cuts were deleted and never regenerated, so linked elements only
appeared as projections and the .cut CSS rule never applied to them.
remove_cut_linework now only removes cut groups whose guid resolves in
the host file, keeping the serializer cut geometry for linked models.

Resolving a linked entity STEP id via tool.Ifc.get_object cross-matches
into the host session and can return an arbitrary host object (e.g. the
drawing camera), so generate_material_layers and the linework merge now
guard on element.file identity.

BISECT mode also runs move_projection_to_bottom like OPENCASCADE mode:
its own bisect cuts are appended last, but the retained serializer cuts
of linked models are emitted before the projections and would paint
underneath.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:34:08 -05:00
Ryan Schultz 236da3c75a Bonsai: draw moved and multi-linked models at their displayed locations
create_drawing opened linked IFCs raw, so a moved link serialized at
its original coordinates and its elements fell outside the drawing.
The stored link transformation is the model-space delta, so it is now
baked into the linework iterator via the model-offset/model-rotation
settings (Trans @ Rot composition matches the rigid matrix
decomposition; the plan-view Z offset adds onto the translation).

The serialization loop also collapsed same-file links into a dict
keyed by filepath, dropping all but the last link. It now iterates one
entry per link and intersects each link's drawing elements with its
selector query, so drawings show what each link displays in the
viewport. Adds tool.Project.get_link_transformation_matrix as the
shared accessor for the stored 4x4.

Verified headless: window link moved +5m appears offset by exactly
5m x scale; unmoved door link at its native position; both present.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:34:08 -05:00
Ryan Schultz cf58c675db Bonsai: match linked model documents by resolved path
get_linked_models_documents keyed documents by the stored Location, so
linking the same file first with a relative path and then an absolute
one (or vice versa) created a duplicate IfcDocumentInformation. Both
the keys and the LinkIfc lookup now normalize through resolve_uri.

Also record the PR #8242 review round decisions in the dev note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:41 -05:00
Ryan Schultz 5ea11817ad Add dev-notes for Linked_File_Features branch
Living design note per the docs/dev-notes convention: problem, key
facts (library-per-path reuse, SKIP_SAVE last-used-property retention,
IfcDocumentReference conventions, link matrix math), per-feature design
decisions, commit map, and open test items.

Generated with the assistance of an AI coding tool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:41 -05:00
Ryan Schultz 6d90048acd Bonsai: per-query caches so one IFC can be linked with several queries
Linking the same file twice with different queries previously collided
on the single shared .ifc.cache.blend: Blender reuses the loaded
library per path, so both links displayed whichever query was cached
first (and the other after reopening). Cache blend/json filenames now
include a hash of the query (tool.Project.get_link_cache_paths), so
each query gets its own library. The empty query keeps the legacy
names, and the property sqlite stays shared since it always contains
the whole file. All cache-path consumers were updated, including the
per-link selectability/visibility toggles which would otherwise affect
every link of the file at once.

Query persistence moves from the shared sidecar JSON to the per-link
IfcDocumentReference.Description (IFC4+, written by link_ifc and
reload_link), restored on project load with a legacy JSON fallback
that only applies when a file has a single link. The appended-element
placement now matches links by the queried instance root empty since
filepath alone is ambiguous with several links per file.

LoadLink and ReloadLink volatile properties are marked SKIP_SAVE:
Blender reuses last-used operator properties on the next interactive
invocation, which leaked one link's query into another's load (and
would corrupt ReloadLink's is_property_set logic the same way).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:41 -05:00
Ryan Schultz cdb594b5c2 Bonsai: fix Explore tool highlight and append placement for linked models
The queried-element highlight broke in two ways: layerset-sliced linked
meshes contain ngons, so highlight triangles are now built from
calc_loop_triangles instead of polygon vertices; and ID properties read
back as IDPropertyArrays which GPUIndexBuf rejects, so selection
geometry is converted to plain tuples. TRIS drawing is also gated on
its own data instead of piggybacking on the edges check.

Moved links now highlight at their displayed location: the ray-cast
instance matrix is passed through to select_linked_element, and
find_obj_root compares it against the empty and object matrices
combined (instanced occurrence objects have non-identity local
matrices), falling back to the collection's only instance when no
matrix is available (e.g. select by GUID).

bim.append_inspected_linked_element also places the appended element
where the moved link is displayed, using the new
tool.Project.calculate_link_delta_matrix helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:41 -05:00
Ryan Schultz 028e593939 Bonsai: per-row lock toggle with auto-saved link transforms
Link editing moves from the links header row into each list row as a
lock/unlock toggle. Unlocking (bim.enable_editing_link) frees the
handle for moving; any transform is persisted immediately by a
depsgraph_update_post handler, so bim.edit_link and its explicit save
step are removed. Locking (bim.disable_editing_link) saves the current
location and locks the handle instead of restoring the old position -
cancel/restore semantics no longer exist.

The save math from EditLink now lives in
tool.Project.save_link_transformation. Enable/disable operators accept
a link_index (default -1 = active link), so several links can be edited
at once and script calls stay backward compatible.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:41 -05:00
Ryan Schultz 42a05cf976 Bonsai: full load options in the Reload Link dialog
The reload_link dialog previously only exposed the query. It now also
offers Use Relative Path (defaulting to the stored path form), Use
Cache (default off, matching the old always-rebuild behavior), the
False Origin Mode project settings, and an editable file path with a
browse button.

Since a file browser cannot open from inside a props dialog, the browse
button runs a new bim.select_link_filepath operator that opens the
browser preselected at the current file and reopens the reload dialog
with the chosen path, carrying the in-progress dialog state through the
round trip.

Changing the path updates the link name/filepath and, when a host IFC
exists, the IfcDocumentReference.Location and document name - so
ReloadLink is now a tool.Ifc.Operator to keep those edits transactional.
Script calls without arguments still preserve all stored link values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:40 -05:00
Ryan Schultz a97276b8b1 Bonsai: load external styles and layerset slicing for linked IFC models
Linked models previously flattened every style to a flat diffuse-color
material. Now, styles carrying an IfcExternallyDefinedSurfaceStyle that
points to a .blend file get the referenced material appended into the
link's .cache.blend, in both the chunked and instanced loading paths.
Relative style locations resolve against the linked IFC, and appended
materials are deduplicated and stripped of stale IFC ids.

Multi-layer elements (IfcMaterialLayerSetUsage) are now routed through
the instanced path and sliced with slice_layerset_mesh so each layer
shows its material style, using the external material when available.
slice_layerset_mesh gained a pluggable style-to-material resolver and
no longer appends duplicate materials for layers sharing one style.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:31:40 -05:00
Gorgious56 9ae79b42dd Merge pull request #8398 from Gorgious56/batch-array-duplicate-helper
Batch array duplicate helper
bonsai-0.8.6-alpha2607081328
2026-07-08 15:27:53 +02:00
Gorgious56 c01433cb6c Bonsai: spec typed test doubles for Blender + dataclass mocks
Convert bare Mock() to Mock(spec=bpy.types.Object) for Blender-object
stand-ins in TestRecalculateWallsWithNewConnections, TestMEPActionGuards,
and TestRecreateAggregateIteratesAllNew so typos on the Blender API
fail loudly instead of silently returning a MagicMock.

Replace the ad-hoc Mock() ConnectionRecord stand-in in
TestRecreateConnectionsZipsPairs with a real ConnectionRecord instance,
which pins field names at construction and catches drift if the
dataclass fields ever get renamed.

IFC entity mocks remain bare Mock() intentionally: entity_instance
attributes are schema-driven at runtime rather than defined statically
on the class, so spec= would refuse the .GlobalId / .HasFillings /
.ConnectedTo attribute writes the tests need.

Relates to #8088.

Generated with the assistance of an AI coding tool.
2026-07-08 15:02:21 +02:00
Gorgious56 da50d22ed5 Bonsai: route array-regen selection through tool.Blender utilities
Rewrite tool.Array.select_only_parent as a thin call to
tool.Blender.select_and_activate_single_object; drop the ad-hoc
per-child deselect loop and the unused parent_element parameter.

Replace the tail parent_obj.select_set(True) in _regenerate_array_body
with tool.Blender.set_object_selection, which wraps select_set in the
hidden-object try/except the utility already owns.

Relates to #8088.

Generated with the assistance of an AI coding tool.
2026-07-08 14:53:29 +02:00
Gorgious56 9191baf067 Bonsai: hide array-child gizmos + converge regen selection
Add tool.Array.is_array_child helper. Port decorator and MEP
action gizmos (lock, pen, join) hide on array children — writes
on children get wiped by the next regen, and the port topology
is inherited from the parent.

Introduce tool.Array.select_only_parent and wire it into both
bim.regenerate_array and bim.finish_editing_array so post-regen
state converges on parent-only-selected + active. Grow and shrink
paths otherwise diverge (grow left new children selected alongside
the parent; shrink left only the parent).

Relates to #8088.

Generated with the assistance of an AI coding tool.
2026-07-08 13:19:42 +02:00
Gorgious56 c299f0b191 Bonsai: iterate every duplicated entity in relationship recreation
Sweep [0]-indexing in recreate_aggregate, recreate_connections,
and recreate_port_connections so batched N-child duplicates
recreate relationships on every new child, not just the first.
Single-source callers unaffected (loop collapses to one iteration
on 1-element lists).

Relates to #8088.

Generated with the assistance of an AI coding tool.
2026-07-08 13:19:26 +02:00
Gorgious56 8f3a1d7412 Bonsai: batch array-duplicate + defensive guards
Replace N sequential duplicate_ifc_objects([parent]) calls in
_regenerate_array_body with one duplicate_ifc_object_n_times call
per layer, batching the fixed per-call overhead (snapshot gather,
UI refresh, decorator reload).

Guard batch_host_recut drain against dead StructRNA refs and prune
orphan array-child GUIDs at regen so outliner-delete of a
Bonsai-managed child cannot crash subsequent regenerate_array.

Recalculate walls after recreate_connections so Shift+D of
connected walls produces correct junction geometry without a
manual regen step.

Relates to #8088.

Generated with the assistance of an AI coding tool.
2026-07-08 13:13:14 +02:00
Petru Conduraru e0a1988044 Follow IfcRelAdheresToElement so IfcSurfaceFeature road markings import #8375
IfcSurfaceFeature (e.g. road markings) adheres to a host element through
IfcRelAdheresToElement, a [1:1] cardinality hierarchical relationship in the
same family as aggregation, containment and nesting since IFC4.3. The spatial
traversal never followed it, so surface features had no resolvable parent or
container: on import they landed in the Unsorted collection instead of the
host's spatial collection, and were dropped entirely in DECOMPOSITION filter
mode.

Add get_adhered_element (feature to host) to the get_parent resolver chain and
walk HasSurfaceFeatures in get_decomposition, plus a get_surface_features helper
mirroring get_parts/get_contained. With get_parent resolving adherence,
get_container now returns the host's spatial container, so tool.Collector places
surface features under the host. Also follow HasSurfaceFeatures in the Bonsai
DECOMPOSITION filter path so they load in that mode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bonsai-0.8.6-alpha2607080916
2026-07-08 11:16:08 +02:00
Richard Brice 644b92263d Merge branch 'v0.8.0' of https://github.com/IfcOpenShell/IfcOpenShell into v0.8.0 bonsai-0.8.6-alpha2607071900 2026-07-07 12:00:27 -07:00
Richard Brice 61642d2ba3 Fixes computation of fallback position for linear placement. PlacementRelTo was improperly ignored 2026-07-07 11:59:47 -07:00
Petru Conduraru 4776bd7639 Atomic IFC file writes to prevent corruption on interrupted save (#4797)
file.write() streamed directly onto the target path, so a crash mid-write
left a truncated file with dangling STEP references. Serialize to a temp
file in the same directory, then atomically rename it onto the target.

- New IfcUtil::path::atomic_rename_file: std::rename on POSIX, MoveFileExW
  with MOVEFILE_REPLACE_EXISTING on Windows. Unlike rename_file it never
  unlinks the destination first, so there is no window where it goes missing.
- Fully in C++/swig (per aothms), so the FILE_NAME header is untouched: it
  comes from the model header, not the output path (verified empirically).
- Temp lives next to the target so the rename stays on one filesystem.
- Stream is closed before the rename (Windows cannot move an open file).
- On any write error the temp is removed and the original target is intact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 14:22:44 +02:00
Petru Conduraru b2d58d0b81 cmake: read the VERSION file unconditionally so builds report the real version #8164
IfcConvert --version reported 0.8.0 on a plain source build even though the
VERSION file says 0.8.6 (#8164). buildinfo.cpp already falls back to the
IFCOPENSHELL_VERSION_STRING macro and CMake already passes it as
${RELEASE_VERSION}, but RELEASE_VERSION was only read from the VERSION file
when VERSION_OVERRIDE was on. A default build (VERSION_OVERRIDE off,
ADD_COMMIT_SHA off, as the nixpkgs package builds it) fell through to the
hardcoded "0.8.0", so the fallback macro carried the stale value.

Read the VERSION file unconditionally so RELEASE_VERSION is always the real
version. VERSION_OVERRIDE still governs the branch name embedded when
ADD_COMMIT_SHA is on, and project()/CPack now also reflect the true version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 10:05:03 +02:00
Petru Conduraru 7322263a5e GltfSerializer: clamp roughnessFactor into the valid glTF range #8073
roughnessFactor was computed as 1/specularity. An IfcSpecularExponent of
0 produced infinity, which nlohmann::json serialises as null and makes
the glTF invalid; exponents below 1 produced values above 1, which glTF
also forbids. Map exponents <= 1 to full roughness and keep 1/exponent
above that, so the factor always lands in [0, 1].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:33:47 +02:00
Petru Conduraru 49de7dbcb1 ExtractElements: handle IfcProject without RepresentationContexts #8199
The georeferencing fix (e6dc582) iterates IfcProject.RepresentationContexts
unconditionally, but the attribute is OPTIONAL and None on projects without
contexts, crashing every extraction on such files with
TypeError: 'NoneType' object is not iterable.

Also extend the #8199 regression test to assert element placements are
copied verbatim, so extraction can never bake map coordinates into local
placements.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bonsai-0.8.6-alpha2607061125 bonsai-0.8.6-alpha2607061121
2026-07-06 13:24:34 +02:00
Petru Conduraru bade0647e8 util.unit: scale RepresentationContext Precision on unit conversion #6127
IfcGeometricRepresentationContext.Precision is typed as a plain IfcReal
but is interpreted in the project length unit, so the IfcLengthMeasure
traversal in convert_file_length_units never touched it. A model
converted from mm to m kept a Precision of e.g. 0.01 (fine in mm, huge
in m), which breaks downstream geometry interpretation such as
IfcConvert boolean cleanup.

Subcontexts derive Precision from their parent, so only root contexts
are scaled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:25 +02:00
Petru Conduraru 58cfab48e6 entity_instance: get_info_2 falls back to get_info for unsupported args #4270
get_info_2 advertises the same signature as get_info but raised a bare
AssertionError for anything the C++ fast path does not implement --
including its own default arguments (recursive=False).

Use the fast path when recursive=True, return_type=dict and ignore=()
hold, and delegate to the pure Python get_info otherwise. As noted in
the issue, without recursion there is no meaningful performance gain to
lose by delegating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bonsai-0.8.6-alpha2607061115
2026-07-06 13:15:32 +02:00
Petru Conduraru fa597536e1 IfcParse: drop ostringstream from format_double per review #7696
std::to_chars is locale-independent, so the ostringstream and imbue(locale)
are no longer needed. Build the REAL string with plain std::string operations.
Output is unchanged (verified in standalone compile: same shortest values, all
round-trip). Addresses review feedback on #8309.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:14:24 +02:00
Petru Conduraru ee2b357d74 IfcParse: serialize REALs with shortest round-trip form #7696
format_double formatted doubles with setprecision(max_digits10) (17 digits),
which padded clean values with noise: 0.0174532925199433 was rewritten as
0.017453292519943299 and 1.E-05 as 1.0000000000000001E-05. Every REAL in a file
changed on save, producing enormous diffs for anyone version-controlling IFC.
Use std::to_chars, which emits the shortest string that round-trips exactly
(like Python's repr), then keep the existing mantissa/exponent formatting.

Verified in a standalone compile of the exact function logic: the reporter's
values become 0.0174532925199433 and 1.E-05, 0.1 stays 0.1, and every tested
value (including a denormal) round-trips back to the identical double.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:14:24 +02:00
Petru Conduraru b1be7d92e6 ifcwrap: accept numpy scalars in aggregate type check #5873
check_aggregate_of_type used an exact type comparison (element->ob_type ==
type_obj), so a numpy array was rejected because its elements are numpy scalars
(numpy.float64) rather than direct float instances. For the numeric types,
accept subclasses: PyFloat_Check for double (numpy.float64 subclasses float) and
PyLong_Check (excluding bool) for int. The SPF REAL vs INTEGER distinction is
kept, so a float is not accepted where an int is expected and vice versa.

This replaces the earlier Python-side walk() approach, which the maintainer
preferred not to take since walk() is removed in v0.9. Verified with a runtime
red-green (built as a shared lib, called via ctypes): the old check rejects
np.array([3.0, 4.0]) and the new one accepts it, plain lists still work, an int
list is still rejected where a REAL is expected, and bool is rejected for INTEGER.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:12:41 +02:00
Petru Conduraru d2381ad6c6 IfcParse: don't strip delimiters from a single-character token #5683
asStringRef removes the first and last characters of a string, enumeration
or binary token to drop the delimiters, guarded only by !str.empty(). A
malformed single-character token (e.g. a bare '.' left when a fuzzer turns
'.PHYSICAL.' into '.)HYSICAL.') has length 1, so the first erase empties the
string and the second erase(str.begin()) runs on an empty string. That is
undefined behaviour: benign on a normal build, but it aborts (or throws
std::length_error from a later append) under a hardened libstdc++ with
_GLIBCXX_ASSERTIONS, which is why this file only segfaulted on the Fedora
build. Require at least two characters before stripping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:28:17 +02:00
Petru Conduraru 5e539890f1 buildinfo: report the release version instead of a hardcoded fallback #8164
When ADD_COMMIT_SHA is off (the default for release tarballs), buildinfo.cpp
fell back to a hardcoded "0.8.0", so a 0.8.5/0.8.6 build reported 0.8.0 from
IfcConvert --version and in written file headers. Pass CMake's RELEASE_VERSION
(read from the VERSION file) to IfcParse as IFCOPENSHELL_VERSION_STRING and use
it as the fallback, mirroring how the branch/commit defines are handled. The
commit-sha build and the last-resort literal are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:30:26 +02:00
falken10vdl 6b4c0194ff Merge pull request #7093 from falken10vdl/group_drawings_in_groups_and_dcos
Organize drawings under a parent called DRAWINGS in ifc groups and ifc documents
bonsai-0.8.6-alpha2607060640
2026-07-06 08:40:49 +02:00
Bruno Postle 1614791775 Fix SHAPELY fill mode dropping surface fills for all but the last linked file
generate_linework() loops over the main file plus any linked models
(added in 5db955d4), reassigning drawing_elements each iteration. The
SHAPELY fill pass builds elements_with_faces/raycast_objs from
drawing_elements, but did so once *after* that loop finished, so it
only ever saw whichever file was processed last -- silently dropping
surface fills for every other file, including the main model whenever
any link was loaded.

Accumulate elements_with_faces/raycast_objs across every file inside
the loop instead of capturing drawing_elements once after it ends.

Generated with the assistance of an AI coding tool.
bonsai-0.8.6-alpha2607052247
2026-07-05 23:45:43 +01:00
Bruno Postle b549e65ad9 bonsai: restore descriptive name for test_copy_with_new_geometry_copied_from_the_old
The underlying bug (has_material_styles bypassing the tool layer) was
already fixed by e76455913, which added the required mock expectation
here, but left the test under its quarantine placeholder name
test_AAAAAAAAAAAA. Restore the real name now that it genuinely passes.
bonsai-0.8.6-alpha2607042226
2026-07-04 17:38:13 +01:00
Bruno Postle ee5d672493 tests: fix test_memusage_partial_open and add psutil to CI
test_memusage_partial_open was silently skipped in CI (psutil was
never installed there). Add psutil so it actually runs, and run the
RSS measurement in a subprocess so the fixture file isn't already in
the page cache from earlier tests, which was making both deltas read
as zero.

Generated with the assistance of an AI coding tool.
2026-07-04 17:32:44 +01:00
Bruno Postle 135f4cf023 tests: skip mathutils tests on Python < 3.13
mathutils only ships pre-built wheels for Python 3.13+ (verified
against PyPI's file list); on CI's Python 3.11, `pip install
mathutils` falls back to a slow/unreliable source build. Skip the
mathutils-dependent tests when the interpreter is too old instead.
2026-07-04 17:29:10 +01:00
Bruno Postle 608d9ead0e ci: add test coverage for ifc5d, ifcquery, ifcedit, ifcmcp
These packages already have their own pytest suites (ifc5d, ifcedit,
ifcmcp, ifcquery) but were never run in CI, so regressions in them
went unnoticed. Add path triggers and test steps for all four, plus
odfpy and xlsxwriter which ifc5d's spreadsheet export tests need and
mcp which ifcmcp's server tests need.

Generated with the assistance of an AI coding tool.
2026-07-04 17:22:42 +01:00
Bruno Postle a0ce930994 ifc5d: fix two csv2ifc bugs found by round-trip test
ItemIsASum and Quantities are exporter columns that were missing from
MAIN_CSV_HEADER_COLUMNS, causing them to be misidentified as numeric cost
value categories on re-import. Also initialise rate_cost_schedule to None
before the search loop to avoid UnboundLocalError when no match is found.

Generated with the assistance of an AI coding tool.
2026-07-04 16:08:43 +01:00
Bruno Postle eafa158ca0 Allow drawing generation in background mode
is_drawing_active() required an open VIEW_3D area purely as a poll()
gate for bim.create_drawing, even though SVG generation is
ifcopenshell.geom-based with no viewport dependency; skip that check
when bpy.app.background is true, since a viewport is neither
obtainable nor meaningful there. Interactive behaviour is unchanged.

Generated with the assistance of an AI coding tool.
bonsai-0.8.6-alpha2607040835
2026-07-04 09:34:05 +01:00
falken10vdl 20b68ce0a9 Organize drawings under a parent called DRAWINGS in ifc groups and ifc documents 2026-07-03 14:52:29 +02:00
Bruno Postle 5db955d40c Apply link matrix when serialising linked drawings
Linked IFC files were included in SVG output but without their
world transform, causing geometry to appear at wrong coordinates.
Falls back to no transform if the link cache is unavailable.

Generated with the assistance of an AI coding tool.
bonsai-0.8.6-alpha2607031034
2026-07-03 11:30:31 +01:00
Bruno Postle df27f86237 Fix linked drawings hidden on drawing activation
Link empty handles were missing from visible_objects, so linked
models were always hidden when activating a drawing.

Generated with the assistance of an AI coding tool.
2026-07-03 11:25:19 +01:00
falken10vdl 0aaafaedc9 Merge pull request #8014 from falken10vdl/surface-style-small-fixes
Surface styles fixes and message warnings
bonsai-0.8.6-alpha2607030727
2026-07-03 09:27:12 +02:00
falken10vdl 7881f5992f Add warning when PHYSICAL/NOTDEFINED uses IfcColourRgb for Metallic, because this value is IFC-only and does not affect Blender appearance. 2026-07-03 09:02:57 +02:00