Skip to content

ENH: Smart import naming rules — auto-assign filament & part type from body name tags#10451

Open
jomixlaf wants to merge 18 commits intobambulab:masterfrom
jomixlaf:feature/smart-import-naming
Open

ENH: Smart import naming rules — auto-assign filament & part type from body name tags#10451
jomixlaf wants to merge 18 commits intobambulab:masterfrom
jomixlaf:feature/smart-import-naming

Conversation

@jomixlaf
Copy link
Copy Markdown
Contributor

Summary

Adds a small naming-rules system that parses tags inside body/object names at import time (and on reload) to auto-assign filament and part type. Tagging a body in your CAD as wheel[f3][mod] is enough to land it in BambuStudio with filament 3 and type Modifier — no clicking through the type submenu, no remembering which body needs which filament after every reload.

Works for STEP, 3MF, OBJ, and STL — every multi-body format BambuStudio supports.

This builds on top of PR #10380 (reload-from-disk fixes). The reload path here calls into the naming-rules helpers added by this PR, so #10380 should land first.

Tag syntax

body_name[tag1][tag2]… — tags are case-insensitive, order-independent, combinable.

Tag Meaning
[f1][f16] Filament 1–16
[part] Type: Part (default)
[neg] Type: Negative Part
[mod] Type: Modifier
[blk] Type: Support Blocker
[enf] Type: Support Enforcer

Examples:

  • gear[f2] → Part on filament 2
  • cavity[neg] → Negative Part
  • support_zone[enf][f5] → Support Enforcer on filament 5

Why brackets? They survive every CAD export I tested, are ASCII-safe, path-safe, readable, and don't collide with normal naming.

Behavior

  • On import (STEP / 3MF / OBJ / STL): every volume's name is parsed; matched tags set filament and/or type.
  • On reload from disk: rules re-applied to matched and new bodies, so renaming or retagging in CAD is reflected immediately.
  • Tag removal reverts to default: removing a tag in CAD on the next export resets that property (filament → 1, type → Part). If the name has no brackets at all, the volume is left alone — manual filament/type tweaks survive reload.
  • Always overridable by the user from the sidebar after import.

Files added

  • src/libslic3r/ImportNamingRules.hpp / .cpp — rule definitions, tag parser, and apply_naming_rules_to_volume / apply_naming_rules_to_objects helpers.

Files touched

  • src/slic3r/GUI/Plater.cpp — calls apply_naming_rules_to_objects after import; calls apply_naming_rules_to_volume on matched + new volumes during reload.
  • STL import path — naming rules now applied.

Test plan

  • STEP import with [f1][f16] tags → filament column populated correctly
  • STEP import with [neg] / [mod] / [blk] / [enf] → volume type set
  • Combined tags like [f3][mod] → both applied
  • Reload from disk picks up tag changes (add, remove, change tag)
  • Removing a tag in CAD between exports reverts the property (e.g. [mod] → no tag → back to Part)
  • Names without any [...] left alone — manual filament adjustments survive reload
  • Tags work on STL imports
  • 3MF and OBJ imports apply rules (verified in code path; pair with sample multi-body files)
  • Bodies with non-ASCII chars in name (when paired with Fix reload-from-disk: matching, positions, deleted bodies, STEP names #10380) keep their tags intact

jomixlaf added 18 commits April 24, 2026 21:57
Parse [tag] tokens from body/volume names on import and automatically
assign filament and part type. Supports STEP and 3MF.

Default tags: [f1]-[f16] for filament, [part], [neg], [mod], [blk], [enf]
for part type. Tags are case-insensitive and combinable.

Example: body named "logo[f2][mod]" imports as filament 2, Modifier type.
…ansfer map

OCCT's XCAF layer only preserves names from PRODUCT entities, so bodies that
live directly inside a root Fusion 360 component (stored as MANIFOLD_SOLID_BREP
in STEP) were always imported as "SOLID" regardless of their actual name.

After the XCAF transfer, iterate all STEP entities via the transfer process to
build a TShape-pointer → MANIFOLD_SOLID_BREP-name map. getNamedSolids now
consults this map when naming solid shapes, so tags like [f3] embedded in a
body name are correctly preserved and subsequently applied by the smart-import
naming rules.
…nents

When a Fusion 360 file has a body directly inside the root component, OCCT's
XCAF layer creates a virtual label for that geometry with a shape-type default
name ("SOLID") rather than the component/product name.  The previous approach
tried to recover the MANIFOLD_SOLID_BREP entity name (the body name), but that
gives the wrong result — users should tag the *component* name, not the body
name, consistent with how sub-components already work.

Fix: treat OCCT shape-type default strings (SOLID, COMPOUND, SHELL, etc.) as
missing names and fall back to the parent component name (prefix).  Bodies that
live directly in an assembly component now inherit the component name so tags
like [f3] or [neg] placed on the component are correctly applied on import.
When reloading a STEP file from disk, the old volume's config and type were
restored after loading, but naming rules were never re-applied.  This meant
that body name tag changes (e.g. renaming a component from [f1] to [f3]) or
newly added bodies had no effect until the file was re-imported via drag-and-drop.

Apply naming rules to the new volume after the old config is restored, so tags
always reflect the current state of the file on disk.  Both reload code paths
(ENABLE_RELOAD_FROM_DISK_REWORK and legacy) are covered.
Two issues with reload from disk for STEP files:

1. New bodies added to the STEP file were never imported — the reload loop
   only iterated over existing volumes looking for matches, so anything new
   in the file was silently dropped.

2. Component name changes didn't trigger naming rule re-evaluation because
   the old config/type were restored after loading without re-running rules.

Fix: track which new_model volumes were matched during the update loop, then
add all unmatched volumes as new volumes to the target object. Naming rules
are applied to both updated and newly added volumes so filament/type tags
are always current with what's in the file on disk.
…odies

When a STEP file is updated with new bodies, existing volumes can shift
to different indices in the newly-loaded model. The previous source-index
match only checked input_file, so adding a body could silently match the
wrong volume and copy its type/config onto a different volume (e.g. giving
the wrong part a NEGATIVE_VOLUME type). Now the candidate must also have
the same name as the old volume before the source-index match is accepted.
After reloading volumes from disk, the sidebar object list was not
updated, leaving stale volume names, types, and filament columns from
before the reload. Now add_volumes_to_object_in_list() is called for
every modified object after the reload loop completes, so the sidebar
immediately reflects new component names, updated tags, and newly-added
volumes.
Previously, renaming a component (e.g. polo[f2] → polo[f5]) caused
reload to fail with an error because source-index+name and name-search
both required the old name. Now matching uses three passes:

  Pass 1: source index + exact name match (unchanged bodies)
  Pass 2: name search (body moved to different index, name kept)
  Pass 3: source index only (body renamed in place)

Already-claimed new_model slots are skipped at every pass to prevent
two old volumes from mapping to the same new geometry. Source indices
on the resulting volume are updated to the new model positions so the
next reload also finds the correct slot.
Three related fixes:

1. Deleted bodies: when a body no longer exists in the reloaded STEP
   file (deleted from Fusion), it now gets silently removed from the
   model instead of showing an error and leaving a stale volume behind.

2. sort_volumes moved out of per-volume loop: calling sort_volumes
   after each swap/delete was reordering the volumes array and making
   later vol_idx values point to the wrong volumes, causing duplicates
   and missed updates. sort_volumes is now called once after the loop
   for all modified objects.

3. Deleted-volume cleanup: volumes marked as deleted are removed in
   reverse index order after the loop so earlier indices stay valid.
When a body is added to a Fusion 360 STEP file and the model is
reloaded, the new body appeared at the center of the plate instead
of its correct position.

Root cause: center_around_origin() shifts all volumes by -bb_center.
On initial import the bb_center is computed from the original set of
bodies; on reload new_model has an extra body that shifts the
bounding-box center. Matched volumes are repositioned via
old_volume->get_transformation(), so they land correctly. New
(unmatched) volumes were copied directly from new_model, which uses
the new shifted center — wrong coordinate frame.

Fix: capture coord_shift = old_offset - new_model_offset from the
first matched volume. This equals new_bb_center - initial_bb_center.
Apply the shift to every newly added volume so it lands in the same
coordinate frame as the existing volumes.
Logs new_model structure (objects, volumes, offsets) before and after
center_around_origin, coord_shift capture, per-matched-volume final
offsets, and per-new-body pre/post shift values. Useful for
diagnosing position issues across reload sequences.
Pass 2 (name-based fallback) was gated by has_name, which only fires
when old_volume->name equals the reloaded file's filename — false for
multi-body STEP files where each body has its own name. The result:
Pass 2 never ran, and when Fusion reordered bodies in the new STEP,
Pass 1 missed and Pass 3 fell through, matching by source.volume_idx
alone and routing the wrong body's transform.

Run Pass 2 whenever the volume has a name; the outer has_source ||
has_name gate already restricts processing to volumes from the file
being reloaded.
Previously, set_transformation(old_volume->get_transformation()) preserved
the matched volume's old position regardless of whether the body moved
in CAD. This broke when users repositioned bodies between exports —
matched bodies stayed at stale offsets while only their meshes updated.

Use the new STEP position translated by coord_shift instead. For the
first matched volume (which defines coord_shift), this yields its old
offset exactly, keeping the object's plate anchor stable. For all other
volumes, it tracks their new STEP positions in the existing scene's
coordinate frame.
OCCT's TCollection_AsciiString(extString) without a replacement
character preserves raw bytes >= 0x80, which then fail BambuStudio's
isUtf8 check (a lone continuation byte like 0xA0 is invalid UTF-8).
The body falls back to the parent component name, losing both the
user's body name and any [tag] inside it.

This bites users who paste a non-breaking space in Fusion (the typical
source of STEP \X\A0 escapes) — for example renaming a body to
'cylinder [f4]' with a stray NBSP would import as 'test_step' with
no filament tag.

Pass ' ' as the replacement so non-ASCII becomes a regular space,
keeping the name readable, the [tag] discoverable, and the isUtf8
check happy.
The previous attempt of passing a replacement char to TCollection_AsciiString
did not engage as expected (OCCT's behavior with that constructor preserved
raw high bytes). A lone byte like 0xE9 (é) or 0xA0 (NBSP) then failed
StepPreProcessor::isUtf8 and the body fell back to the parent component
name, losing both the name and any [tag] inside it.

Walk the OCCT extended (UTF-16) string codepoint by codepoint and emit a
benign space for anything outside printable ASCII. Pure ASCII output
always passes isUtf8, so the user's tags are preserved no matter what
character they paste into a body name in Fusion.
apply_import_name_tags only updated filament/type when a recognized
tag was found. Removing a [mod] or [neg] tag in Fusion left the
volume stuck on its previous type after reload; same story for
removing a [fN] tag. The user's mental model is that bracket-tags
are the source of truth and absent ones mean default.

Gate naming-rule application on the volume's name containing at least
one [<anything>] sequence. If yes, apply complete tags defaulting
filament=1 and type=MODEL_PART for missing/unrecognized tags. If no
brackets at all, leave the volume's filament/type alone so manual
adjustments the user made in BambuStudio survive reload.
Strip the .stl/.STL extension from the imported object and volume name
in load_stl() so filename tags like "MyPart [f3] [neg].stl" display as
"MyPart [f3] [neg]". The existing apply_naming_rules_to_objects pipeline
in Plater::priv::load_model_objects then picks up the bracket tags and
assigns filament + part type, matching STEP body-name behavior.
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.

1 participant