Releases: emircbngl/blender-optics-simulator
Release list
v0.24.3 — Store-review hardening
v0.24.3 — Store-review hardening: thread-free MCP bridge, input guards, graceful plots
The extensions.blender.org review pass — and several reviewer points turned out to be genuine engine
improvements that land here for all builds. No physics changes. Regression 409/409, validation
303/303.
Changed — the MCP bridge is now thread-free
The bridge is rewritten as a single bpy.app.timers pump over non-blocking sockets — accept, read,
dispatch, write each tick, entirely on Blender's main thread. threading/queue no longer appear
anywhere in the add-on (crash-prone in Blender; timers are the sanctioned pattern). The wire protocol
is unchanged — existing MCP clients connect exactly as before.
Fixed — real crashes an agent could trigger
speckle_pattern/caustic_pattern/produce_phenomenonwithpng=Trueraised NameError
(missingos/tempfileimports — thanks to the platform reviewer for catching it).- Garbage inputs on 15 MCP-reachable producers now return
{error}instead of crashing:
wavelength_nm=0used to ZeroDivisionError, and an unboundedn_gridcould OOM-kill Blender
(verified withn_grid=1e6).n_gridis now capped. - The bridge replies with an error instead of dropping the connection on a non-serializable result.
Changed — plots degrade gracefully everywhere
All matplotlib use goes through one access point: in a matplotlib-less environment PNG producers
return an honest png_error instead of crashing — numeric results are never affected.
Added
tools/build_platform_zip.py— builds the extensions.blender.org-compliant zip from an untouched
source tree (no updater, nosys.modulesalias, no self-test tails, no external-software access),
with a strict compliance self-check. The GitHub build keeps its full feature set.- +32 independent-oracle validation checks (coverage-gap audit; 271 → 303).
Install / update: drag the one-click link from https://emircbngl.github.io/blender-optics-simulator/
into Blender 4.2+, or download the attached zip. Existing installs update from inside Blender.
v0.24.2 — Optics Simulator (naming compliance)
v0.24.2 — Extension display name → "Optics Simulator"
No physics or behaviour changes. The Blender Extensions platform's naming policy (rule 2.1) disallows
"Blender" in an extension's name, so the manifest display name is now "Optics Simulator" (was
"Blender Optics Simulator"). The extension id (optical_alignment_sim) is unchanged, so your
installs and the update channel are unaffected — this is a display-name-only change. The GitHub project /
repository is still called Blender Optics Simulator; only the in-Blender / platform display name drops
the word "Blender".
Install / update: drag the one-click link from https://emircbngl.github.io/blender-optics-simulator/
into Blender 4.2+, or download the attached zip. Existing installs update from inside Blender.
v0.24.1 — Distribution & repo hygiene
v0.24.1 — Distribution & repo hygiene
No physics changes — a distribution + repo-hygiene pass so the add-on is discoverable and
installable through every channel, and every install path can update. The manifest display name is now
Blender Optics Simulator (the extension id is unchanged, so your installs and the update channel
are unaffected).
Changed — platform-ready updater
- The self-hosted updater now defers to the Blender Extensions platform when the add-on is installed
from it (_platform_managed()→ packagebl_ext.blender_org.<id>): no daily-check timer, no external
repo registration, no Check/Install button — Blender delivers updates, and the panel just reads
"updates via Blender Extensions". GitHub / one-click / disk installs are unchanged — the
self-hosted channel + in-add-on updater still run. The same zip works both ways (no second build),
which is what makes the add-on submittable to extensions.blender.org.
Added — packaged MCP server
- The MCP server is now a
pip/uvx-installable console app,blender-optics-mcp(see
mcp/pyproject.toml+ themcp/server.jsonMCP-Registry manifest). Your MCP client config becomes one
command —uvx blender-optics-mcp— instead of an absolute path to a script.
Added — repo hygiene
CONTRIBUTING.md,CODE_OF_CONDUCT.md,SECURITY.md, issue + PR templates,FUNDING.yml.- README: fixed the citation block (it advertised a frozen v0.9.1 version DOI mislabeled as the concept
DOI), added OptiCore to "How this compares", a 60-second TL;DR + a release badge, and a clear
per-install-path update table. docs/EXTENSIONS_SUBMISSION.md— the compliance checklist + listing prep for extensions.blender.org.
Install / update: drag the one-click link from
https://emircbngl.github.io/blender-optics-simulator/ into Blender 4.2+, or download the attached
optical_alignment_sim-0.24.1.zip and Install from Disk. Existing installs update from inside Blender —
see the README's Install & stay updated section.
v0.24.0 — Laser speckle + the coffee-cup caustic
v0.24.0 — Phenomena closed out: laser speckle + the coffee-cup caustic, and a bypassed-optic warning
Two new off-trace phenomenon producers close the emergence catalog — laser speckle and the coffee-cup
caustic — each derived from first principles and checked against its exact textbook statistics/geometry.
Plus a diagnostic the owner's own eye surfaced: the engine now warns when an optic is knocked off the
beam. All off-trace; the live trace stays byte-identical — validation 271/271, regression 397/397, CI-green.
Added — laser speckle (speckle_pattern)
- A random-phase circular diffuser propagated to a screen gives fully-developed laser speckle. Reports
the verified Goodman statistics: contrast σ_I/⟨I⟩ → 1, the negative-exponential intensity PDF
P(I) = e^{-I/⟨I⟩}/⟨I⟩(sovar/⟨I⟩² → 1andP(I>⟨I⟩) → e⁻¹ = 0.368), mean speckle size~ λz/D, and —
averagingn_avgindependent frames — the speckle-suppression lawC_N = 1/√N. Contrast + 1/√N are
physics_verify ok=true; the exponential PDF / survival / size-scaling are confirmed in the module self-test.
Added — caustics (caustic_pattern)
- Parallel rays reflecting off the concave inner wall of a circular mirror (radius
R) pile up on a
nephroid — the coffee-cup caustic. Traced from first principles (reflect a ray fan, accumulate the
ray-density) and reported against the exact analytic envelope(R/4)(3cosθ−cos3θ, 3sinθ−sin3θ). The
reflected direction(−cos2θ,−sin2θ), the caustic point lying on each ray att = −(R/2)cosθ, and the
cusp at R/2 (the mirror paraxial focus) arephysics_verify ok=true; the ray-density piles onto the
nephroid ~20×, brightest at the cusp. This closes the phenomenon-emergence catalog (hologram · interferogram
· Fabry–Pérot · Talbot · Newton's-rings · speckle · caustic).
Added — optic_bypassed diagnostic
diagnose()/propose_corrections()now warn when a mid-path optic receives no beam at all — it was
moved or mis-placed off the path so the trace bypasses it ("<optic> is in the scene but NO beam reaches it … (moved off the beam / mis-placed?)"), with a re-centre fix + amaybe_intentional_ifjudge hint.
Previously silent:beam_clippedonly fires on a near-miss over the aperture anddark_detectoronly
covers terminals. Found via the v0.23.0 rigid-mount render, where a lens stepped aside left the beam and
nothing flagged it. No false positives across the 18 example benches.
Install / update: drag the one-click link from
https://emircbngl.github.io/blender-optics-simulator/ into Blender, or download the attached
optical_alignment_sim-0.24.0.zip and Install from Disk. Existing installs auto-update via the
self-hosted extension channel.
v0.23.0 — The mount rides the optic
v0.23.0 — The mount rides the optic: rigid assemblies, inspection dashboards & post-audit hardening
A post-release review pass. The headline is a real bug hit on the bench: dressed opto-mechanical
hardware (post, holder, mount) did not move with its optic — grab the lens in a Newton's-rings setup
and it slid free of its mount. Alongside that fix, this release adds the "show me everything"
inspection + report tooling, surfaces the in-add-on update button for up-to-date users, expands the
glass / crystal / IR catalog, and tidies vendor-IP provenance + naming. All trace-affecting work
stays byte-identical — regression 392/392, validation 262/262, CI-green.
Fixed — opto-mechanical hardware now rides its optic
dress_bench()built each optic's post / holder / mount as standalone objects pinned to absolute
world coordinates, so moving the optic left the mount behind._own_newnow rigid-parents each
cluster's hardware to a representative optic viamatrix_parent_inverse = optic.matrix_world.inverted():
no visible jump, the optic'smatrix_worldis untouched (so the live trace stays byte-identical),
and Blender's depsgraph moves the whole assembly rigidly — an optic nudged 10 mm carries all of
its dressed hardware by exactly 10 mm.- Added a distinct translation-stage mount geometry (it previously fell through to the kinematic mount).
Added — "show me everything" inspection & reporting
inspect_all()— a per-element dashboard (power, beam count, w, R, polarization, vignetting,
diagnostics) for the whole bench.export_report(filepath, title, with_render)— a self-contained HTML spec-sheet bundling
get_state+diagnose+ per-element inspection + plots (+ an optional render), images embedded.- Both exposed over MCP for the AI agent.
Added — material / crystal / IR catalog (sourced)
- Four more glasses — N-PK51, N-LASF9, N-SF66, S-FPL51.
- Two more nonlinear crystals — CLBO and AgGaS2 (self-validated against published cuts).
- Three infrared materials — As2S3, AgCl, ZnS — via a new refractiveindex.info
formula 4
evaluator. - A new
docs/DATASOURCES.mddocumenting the provenance of every material constant + component spec.
Added — physics-validation coverage
- New checks for AOM deflection and Gaussian-to-fiber coupling efficiency.
Changed — update-button discoverability, naming & IP provenance
- The in-add-on Updates panel rendered only when an update was available or staged, so up-to-date
users never saw it. It is now always visible with an "Up to date · Check" affordance + a state icon. - Naming tidy toward "simulator": "Alignment Report" → "Optical Report"; "Update Report" → "Refresh Report".
library.pygained an IP / trademark clarifying note (public part-number references for spec
reproduction; no vendor CAD bundled; not affiliated with or endorsed by any vendor).
Install / update: drag the one-click link from
https://emircbngl.github.io/blender-optics-simulator/ into Blender, or download the attached
optical_alignment_sim-0.23.0.zip and Install from Disk. Existing installs auto-update via the
self-hosted extension channel.
v0.22.0 — Biaxial crystals, nonlinear-optics depth, interference & GPU/quantum scaffolds
v0.22.0 — Biaxial crystals, nonlinear-optics depth, interference & GPU / quantum scaffolds
Seven additions across the off-trace physics layer — completing the nonlinear-crystal catalog, deepening the
χ² solver, and laying down the first GPU and quantum scaffolds. Everything is opt-in and on-demand; the live
single-ray + Gaussian trace stays byte-identical (regression 390/390), and validation grows 215 to 249.
Biaxial nonlinear crystals — KTP + LBO
The Sellmeier-derived phase matching covered only uniaxial crystals; this adds the two workhorse biaxial
doublers. With all three principal-axis indices sourced from refractiveindex.info, the XY-plane phase matching
reduces to an effective-uniaxial problem and reproduces the textbook Nd:YAG green-doubler cuts from the
coefficients alone — KTP Type-II at 23.58 deg, LBO Type-I at 11.76 deg — plus their walk-off (KTP ~4 mrad, LBO
~7 mrad). (The in-plane index order was caught and corrected via physics_verify before coding: the
polarization is perpendicular to the wavevector.)
LBO non-critical phase matching — with an honest limitation
LBO's temperature-tuned NCPM route, using the real datasheet dn/dT constants. Honest caveat (no fabrication):
the constant dn/dT under-predict the tuning slope, so the model lands near 256 C, not the real 148 C; the
wavelength-resolved coefficients that reproduce 148 C are paywalled and were not transcribed. The calculator
ships the datasheet constants, the cited literature value, and the documented gap.
Type-II SHG coupled-wave efficiency
The χ² depletion solver's Type-II case: the three-wave coupled equations where the harmonic consumes one
ordinary plus one extraordinary photon. A balanced pump reduces exactly to Type-I at half the drive; an
unbalanced pump saturates at the weaker polarization — the Manley-Rowe cap, never exceeded.
Newton's-rings 2D pattern
The full 2-D reflected pattern of a plano-convex surface on a flat — a central dark spot and dark rings landing
exactly on the closed-form radii.
AR coating ghost curve
The wavelength-dependent V-shaped reflectance of a single-layer quarter-wave coating, reducing exactly to the
oracle quarter-wave value at the design wavelength. physics_verify'd.
Opt-in GPU backend (scaffold)
A NumPy-compatible array namespace that switches to CuPy or MLX when present and enabled. The NumPy path
reproduces the field propagator exactly, so the GPU-ready code is proven correct; the owner installs cupy/mlx
and flips a flag. (A real numerical fix surfaced during the scaffold: the transfer-function phase reaches about
a million radians, so it must be built in float64 even on the GPU — with that the complex64 fast path deviates
only about one part in ten million.)
Quantum photon statistics (analytic core + QuTiP scaffold)
The first quantum observables in the engine, the ones the χ²/SPDC layer implies: the second-order coherence
g-squared-of-zero (coherent 1, thermal 2, single-photon 0, Fock 1 minus 1 over n), the Hong-Ou-Mandel
two-photon dip, squeezing (sub-shot-noise quadrature variance), and the SPDC source statistics. The closed-form
core is physics_verify ok; the full many-mode state is a QuTiP scaffold (closed-form fallback when QuTiP is
absent).
Verification: textbook validation 249 / 249, byte-identical regression 390 / 390, the
bare-interpreter physics.py self-test, the MCP-to-API parity meta-test, plus physics_verify Docker-oracle
passes on the new nonlinear-optics and quantum relations. New demos: biaxial-crystals-demo.png,
newton-rings-demo.png.
Install / update: the add-on self-updates through Blender's native extension channel, or drag the attached
optical_alignment_sim-0.22.0.zip into Blender (Edit, Preferences, Get Extensions, Install from Disk).
v0.21.0 — Birefringence: o/e spatial ray-splitting + a χ² coupled-wave solver
v0.21.0 — Birefringence: o/e spatial ray-splitting + a χ² coupled-wave solver
The two biggest-ticket architectural items on the backlog, both landing in the live ray tracer (not the
off-trace analysis layer) yet byte-identical — each gated behind a per-element opt-in flag (default OFF), so
all 18 baseline examples trace unchanged. The tracer already branches rays (beamsplitter, Wollaston) and already
emits walk-off SHG children, so each feature is the same split-two pattern, not a new engine.
True ordinary/extraordinary spatial double refraction (oe_split)
A uniaxial crystal or waveplate with oe_split ON forks one incident ray into an ordinary beam (polarized
perpendicular to the principal plane, index n_o) and an extraordinary beam (polarized in-plane, index n_e),
modeled as a slab: both exit parallel to the input, the e-beam laterally displaced by L·tan(ρ) — the
textbook calcite double image (a fixed displacement set by the crystal thickness, not the screen distance). The
power split is Malus on the eigen-axes; the two beams are orthogonally polarized; energy is conserved. Materials:
calcite, quartz, MgF2, sapphire.
χ² tensor solver: the Manley-Rowe coupled-wave ODE (use_chi2_solver)
A nonlinear crystal with use_chi2_solver ON derives its SHG conversion efficiency from the full Manley-Rowe
coupled-wave equations (pump depletion + arbitrary phase mismatch, RK4-integrated) instead of a static
efficiency scalar. It is verified against both analytic limits to about 1e-12 (perfect phase match gives
tanh-squared of the square root of the undepleted efficiency; undepleted gives the sinc-squared tuning curve) and
conserves photon number. In-trace, a 1064-to-532 BBO crystal converts more as the pump rises (eta 0.076, then
0.93, then 0.999), pump residual plus harmonic equal the input at every level.
Nonlinear-crystal catalog (sourced + self-validated)
The phase-match angle and walk-off worked only for BBO; added three more uniaxial crystals from
refractiveindex.info, each self-validated by reproducing its textbook Type-I 1064-to-532 phase-match angle (a
wrong coefficient would miss it): KDP (41.2 deg), ADP (41.7 deg), LiIO3 (30.0 deg, exact). KTP and
LBO are biaxial, and congruent LiNbO3 has no room-temperature critical angle for this conversion, so all three
honestly stay outside the uniaxial angle path rather than be modeled wrong.
Type-I and Type-II phase matching
Added the real Type-II condition (one ordinary plus one extraordinary fundamental photon make an
extraordinary harmonic) solved by bisection — BBO 32.84 deg, KDP 59.1 deg, both larger than their Type-I cuts as
a negative uniaxial requires. The Sellmeier-derived walk-off is now per-type.
Verification: textbook validation 219 / 219, byte-identical regression 389 / 389, the bare-interpreter
physics.py self-test, and the MCP-to-API parity meta-test all green; plus two standalone harnesses
(_verify_birefringence.py 6/6, _verify_chi2_tensor.py 14/14) and a physics_verify Docker-oracle pass on the
SHG depletion result. New demos: birefringence-demo.png, chi2-solver-demo.png.
Install / update: the add-on self-updates through Blender's native extension channel, or drag the attached
optical_alignment_sim-0.21.0.zip into Blender (Edit → Preferences → Get Extensions → Install from Disk).
v0.20.0 — Wave optics: aberrated PSF, phase retrieval & cavity modes
v0.20.0 — Wave optics: aberrated PSF, phase retrieval & cavity modes
Three additions on the verified off-trace wave/FFT layer, plus a real bug fix. Everything here is opt-in and
on-demand: the live single-ray + Gaussian-q trace stays byte-identical.
aberrated_psf — any-mode Zernike aberration of the diffraction PSF (the forward problem)
The general form of wave_psf's defocus knob: aberrate the PSF with any Zernike mode (defocus, astigmatism,
coma, trefoil, spherical) at a chosen RMS, or a full Noll-indexed wavefront vector. The Strehl ratio collapses
the same way for every mode — it depends only on the RMS wavefront error (the Maréchal approximation
exp(−(two·pi·rms)²): 0.05 waves gives 0.906, 0.10 waves gives 0.674) — while the PSF morphology is the mode's
fingerprint: defocus blurs symmetrically, astigmatism elongates, coma flares one-sided, spherical haloes.
fienup_phase_retrieval — reconstruct a hidden object from its diffraction intensity (the inverse problem)
The genuine "phase problem" of coherent diffractive imaging: a detector records only |FFT(object)|² — the
phase is lost. Given that magnitude plus a real-space support mask, Fienup's Hybrid-Input-Output algorithm
reconstructs the unknown object (correlation 0.996, up to the inherent translation + twin ambiguity). Where
v0.19.0's Gerchberg-Saxton knows the amplitude in both planes (CGH design), here the object is unknown — only
its support is; the HIO feedback escapes the stagnation pure error-reduction falls into.
tem_mode — laser cavity transverse eigenmodes
The transverse mode patterns a real resonator emits. family="HG" builds the Hermite-Gaussian TEM_mn
(rectangular, (m+1)(n+1) bright lobes, an orthonormal set); family="LG" builds the Laguerre-Gaussian donut
LG_p,l with an on-axis null and an exp(i·l·phi) phase vortex carrying orbital angular momentum l·hbar.
Validated: HG orthonormality, second moment scaling as (2m+1), lobe count (m+1)(n+1), the LG on-axis null and
its two·pi·l azimuthal phase winding, and the Gouy order.
Fixed — off-trace optics_api wrappers crashed with NameError
gerchberg_saxton, spatial_filter (both v0.19.0) and propagate_chain (v0.18.0) referenced a bare,
un-imported field module. They ran fine when field.* was called directly (as the validation suite does) but
raised NameError when invoked through optics_api / the MCP tool — the path an AI agent actually takes.
The field submodule is imported lazily to keep numpy out of the add-on's startup path; these wrappers omitted
that import. Fixed in all of them, and a regression block now actually invokes every off-trace wrapper
end-to-end so a never-run wrapper can't ship broken again.
Verification: textbook validation 179 → 202 checks, byte-identical regression 375 → 383 checks, the
MCP-to-API parity meta-test green. New demos: aberrated-psf-demo.png, fienup-phase-retrieval-demo.png,
tem-modes-demo.png.
Install / update: the add-on self-updates through Blender's native extension channel. Or drag the attached
optical_alignment_sim-0.20.0.zip into Blender (Edit → Preferences → Get Extensions → Install from Disk).
v0.19.0 — Fourier optics: phase retrieval + spatial filtering
v0.19.0 — Fourier optics: phase retrieval + spatial filtering
A Fourier-optics pair built on the verified Fraunhofer FFT — one designs a Fourier-plane phase mask, the other applies one. The geometric trace is byte-identical to v0.18.0 (regression 375/375).
gerchberg_saxton — phase retrieval / CGH design
The iterative Fourier-transform algorithm: find a source-plane phase whose far-field |FFT| matches a target pattern, alternating amplitude constraints in the source and far-field planes. The far-field error is monotone non-increasing (the GS convergence guarantee), and the recovered phase mask is a computer-generated hologram for beam shaping. Canonical targets {ring, double, tophat, spot}. Validated: monotone error; a feasible target recovered to correlation 0.99; a double-spot CGH target at correlation 0.94.
spatial_filter — 4f Fourier-plane filtering (the Abbe-Porter experiment)
Coherent optical image processing: FFT an object, mask the Fourier plane, IFFT back. kind ∈ {lowpass (smooths — a square grating becomes sinusoidal), highpass (edge enhancement — removes the DC background), phase_contrast (Zernike — a quarter-turn dot on the zero order makes a pure-phase object visible in intensity)}. Validated: highpass removes the DC (mean → 0); a lowpass passing only the zero order erases the grating (uniform output); a pure-phase object (intensity std = 0) becomes visible under phase contrast (std 0.078).
Validation now 179 oracle checks. Both off-trace; the live ray-trace is byte-identical.
Install / update
Existing users on the native update channel get this as a one-click update. New install: download the zip below → Blender Preferences ▸ Add-ons ▸ Install from Disk…
Full notes: CHANGELOG.md.
v0.18.0 — Multi-plane field-propagation chain (propagate_chain)
v0.18.0 — Multi-plane field-propagation chain (propagate_chain)
propagate_field runs the angular-spectrum propagator once; the new propagate_chain marches a complex field through a sequence of planes — the POPPY-style multi-plane OpticalSystem the single-step layer could not chain. The geometric trace is byte-identical to v0.17.0 (regression 375/375).
Each step is ["prop", dz_mm] (free-space propagation), ["aperture", D_mm] (hard circular aperture), or ["lens", f_mm] (thin lens); the source is a Gaussian w0_mm or a clear aperture_mm. (optics_api + MCP.) Validated:
- propagator additivity — the pure angular spectrum composes exactly,
prop(z1)·prop(z2) = prop(z1+z2)to 3.7×10⁻¹¹; - a chained
aperture→lens(f)→propfocuses at z=f (200 mm); - a free Gaussian marched through the chain reproduces
w(z)=w0√(1+(z/zR)²).
This closes the optics-textbook catalog's principal remaining gap: single plane→plane is now a chainable auto-pipeline (Voelz propTF, POPPY-style multi-plane). Validation now 171 oracle checks. (Near-field / moderate-propagation layer — a tight focus or a Fraunhofer far field is better via direct FFT: wave_psf / slit_diffraction.)
Install / update
Existing users on the native update channel get this as a one-click update. New install: download the zip below → Blender Preferences ▸ Add-ons ▸ Install from Disk…
Full notes: CHANGELOG.md.