Skip to content

Bind math_Vector-family templates + dependent OCCT surface; fix embind cross-inheritance overload aliasing#2

Open
marwndev wants to merge 3 commits into
taucad:occt-v8-emscripten-5from
marwndev:occt-v8-emscripten-5
Open

Bind math_Vector-family templates + dependent OCCT surface; fix embind cross-inheritance overload aliasing#2
marwndev wants to merge 3 commits into
taucad:occt-v8-emscripten-5from
marwndev:occt-v8-emscripten-5

Conversation

@marwndev

@marwndev marwndev commented Jun 7, 2026

Copy link
Copy Markdown

Summary

Three related changes that make the math_Vector / TKMath template surface bindable, surface the OCCT classes that depend on it, and fix an embind overload-resolution bug exposed along the way.

1. bindgen: discover + emit non-NCollection template instantiations

Lets template typedefs outside the NCollection family — e.g. math_VectorBase<double> (= math_Vector) and math_MatrixBase<double> (= math_Matrix) — be discovered and compiled.

  • discover.py: add EXTRA_TEMPLATE_CONTAINERS (math_VectorBase, math_MatrixBase) and ADMIT_TEMPLATE_CONTAINERS = NCOLLECTION_CONTAINERS | EXTRA (existing behaviour stays a strict subset, so it cannot regress), plus pass‑1 canonical resolution so a method param spelled via a typedef (const math_Vector&) resolves to its canonical container before bailing. Implements the long‑standing generic‑template‑discovery follow‑up.
  • ast/template_args.py: substitute the canonical forward‑declaration template parameter name. OCCT forward‑declares template<typename T> class math_VectorBase; then defines it with TheItemType; libclang renders a method's self‑type param (const math_VectorBase&) using the forward‑decl name T, while processTemplate keys templateArgs from the definition, so T was never substituted and an uncompilable math_VectorBase<T> leaked into select_overload<> signatures and val‑dispatch arg.as<> lambdas. Mapping the canonical param name onto the same ordinal fixes every self‑type‑param site at once.

2. libembind: fork inherited overload tables (cross‑inheritance aliasing fix)

embind keys method overloads by arg‑count → arg‑signature only; the this type is not in the key. When a derived class registers an override of a method whose overload dispatcher / per‑signature map is inherited from a base, ensureOverloadTable / ensureOverloadSignatureTable did not fork an own copy, so the write landed in the base's shared structures. With a base method overridden by multiple subclasses, they shared one per‑signature slot and the last registrant won — so the base and non‑overriding siblings dispatched to the wrong invoker and threw Expected null or instance of <sibling>, got an instance of <base>.

Concrete case: BOPAlgo_Builder::Perform is overridden by sibling BOPAlgo_Splitter and inherited by BOPAlgo_CellsBuilder; before this fix, both new BOPAlgo_CellsBuilder().Perform(...) and new BOPAlgo_Builder().Perform(...) threw Expected ... BOPAlgo_Splitter, got ... BOPAlgo_Options.

Fix: both helpers now fork inherited overload structures so each registering class owns its own dispatcher / per‑signature maps (tagged ocjsSignatureOwner); writes never escape to a base. Non‑inherited paths are byte‑for‑byte unchanged, so single‑class methods cannot regress. This is distinct from the sub‑2b constructor sibling‑aliasing handled by predicates/sibling_aliasing.py (that is within one class; this is across inheritance). The change is folded into src/patches/libembind-overloading.patch (regenerated against the vendored stock‑emscripten pristine snapshot — round‑trips exactly) with an updated libembind-overloading.expected.sha256.

3. full builds: bind the math_Vector‑dependent OCCT surface

Now that math_VectorBase<double> is discoverable + compilable, the classes excluded only because that base was unbound can be re‑included:

  • bindgen-filters.yaml: un‑exclude the walking‑line approximators (BRepApprox/GeomInt TheComputeLine{,Bezier}), the 2D tangent‑constraint solvers (GccAna_* / Geom2dGcc_* / GccEnt), and the ProjLib projection package. (Geom2dGcc_FunctionTanCuCuCu stays excluded — an internal undefined‑symbol functor, not public API.)
  • build-configs/full*.yml: add the now‑bindable symbols (math_VectorBase_double + the re‑included approximators / Gcc solvers / ProjLib classes), regenerated via scripts/enumerate-symbols.py.

Validation

  • Changes 1 & 2 were validated in a downstream multi‑threaded consumer build + its test suite: BOPAlgo_CellsBuilder.Perform, the 2D Gcc tangent‑constraint solvers, ProjLib projection, and direct math_Vector numeric use all work. A runtime audit of 157 signature dispatchers across 607 classes shows every one resolves to an ancestor‑or‑self owner (zero sibling mis‑resolution).
  • The newly‑included surface in change 3 is generation/compile‑validated; the full build links a broader set than that downstream build, so this repo's CI full.yml build is the authoritative full‑link check.

🤖 Generated with Claude Code

marwndev and others added 2 commits June 7, 2026 20:27
Let template typedefs outside the NCollection family — e.g.
math_VectorBase<double> (= math_Vector) and math_MatrixBase<double>
(= math_Matrix) — be discovered and compiled. Two coupled changes:

- discover.py: add EXTRA_TEMPLATE_CONTAINERS (math_VectorBase, math_MatrixBase)
  and ADMIT_TEMPLATE_CONTAINERS = NCOLLECTION_CONTAINERS | EXTRA (existing
  behaviour stays a strict subset, so it cannot regress), plus pass-1 canonical
  resolution so a method param spelled via a typedef (const math_Vector&)
  resolves to its canonical container before bailing. Implements the
  long-standing generic-template-discovery follow-up.
- ast/template_args.py: substitute the canonical forward-declaration template
  parameter name. OCCT forward-declares `template<typename T> class
  math_VectorBase;` then defines it with TheItemType; libclang renders a
  method's self-type param (const math_VectorBase&) using the forward-decl name
  T, while processTemplate keys templateArgs from the definition (TheItemType),
  so the T was never substituted and an uncompilable math_VectorBase<T> leaked
  into select_overload<> signatures and val-dispatch arg.as<> lambdas. Mapping
  the canonical param name onto the same ordinal fixes every self-type-param
  site at once.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fix)

embind keys method overloads by arg-count -> arg-signature only; the `this`
type is not in the key. When a derived class registers an override of a method
whose overload dispatcher / per-signature map is inherited from a base,
ensureOverloadTable / ensureOverloadSignatureTable did not fork an own copy, so
the write landed in the base's shared structures. With a base method overridden
by multiple subclasses, all of them shared one per-signature slot and the last
registrant won -- so the base and non-overriding siblings dispatched to the
wrong invoker and threw "Expected null or instance of <sibling>, got an
instance of <base>".

Both helpers now fork inherited overload structures so each registering class
owns its own dispatcher / per-signature maps (tagged ocjsSignatureOwner);
writes never escape to a base. Non-inherited paths are unchanged. This is
distinct from the sub-2b constructor sibling-aliasing handled by
predicates/sibling_aliasing.py (that is within one class; this is across
inheritance).

Regenerated src/patches/libembind-overloading.patch against the vendored
stock-emscripten pristine snapshot (round-trips exactly) and updated
libembind-overloading.expected.sha256 to the new post-patch result.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

@marwndev is attempting to deploy a commit to the TauCAD Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b0b7dd7-0365-4dab-a34c-b691fb42bea3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Regenerate build-configs/full*.yml via scripts/enumerate-symbols.py now that the
bindgen template-discovery change + the bindgen-filters.yaml un-exclusions make
the math_Vector-dependent surface bindable. The three configs share one bindings
list (only emcc flags differ); each is the verbatim enumerator output.

Adds vs the previous full.yml:
  - walking-line approximators (BRepApprox/GeomInt TheComputeLine{,Bezier}),
    2D tangent-constraint solvers (GccAna_*/Geom2dGcc_*/GccEnt), and the ProjLib
    projection package — previously excluded only because math_VectorBase<double>
    was unbound;
  - 6 IMeshData_*Handle the previous (stale) full.yml had missed; the enumerator
    emits these independently of this change.

math_VectorBase<double> is not emitted as a standalone symbol by the enumerator,
so it is not listed here; the classes that consume it are.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@marwndev marwndev force-pushed the occt-v8-emscripten-5 branch from 70d1fd7 to c068b04 Compare June 8, 2026 09:52
@rifont

rifont commented Jun 14, 2026

Copy link
Copy Markdown

Thanks for the contribution @marwndev , I'll review and seek to incorporate these changes over the next few days! The math APIs are something I hadn't got a chance to properly exercise, so it's great you have on your downstream. I'll look to add additional smoke tests for these APIs too.

Cheers Richard

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.

2 participants