0.4.0 — the imaging exits stop shipping a look, and rulers become data
This release breaks every existing call to the four imaging tools.
They each take a new requiredstyleargument. Nothing else changes —
if you do not useimaging.*, upgrading is a no-op.本版对四个 imaging 工具是破坏性变更:每个都多了必填的
style参数。
其余部分不受影响,不用imaging.*的话升级无感。
Why / 为什么
klink is the mechanism layer. It knew how to build a Principled BSDF, stage a camera, dilate an SEM rim and lay out a page — and it also held the numbers: sun energy, camera lens, film transform, beam blur, grain, page colour, the colour of every atom in a lattice figure. Those are not mechanism. They are taste, tuned by one person against one device, and a library that ships them is deciding what your process looks like.
So klink now ships none of them, and refuses to guess. A render with no style declared is an error naming the file to copy, rather than a picture drawn with somebody else's judgement.
klink 是机制层。它知道怎么搭 BSDF、怎么架相机、怎么画 SEM 边缘增亮、怎么排版一张图——但它同时还攥着一堆数字:太阳能量、镜头焦距、胶片色彩管理、束流模糊、颗粒、页面配色、晶格图里每个原子的颜色。那些不是机制,是某个人对着某台设备调出来的审美;一个库把它们随包发出去,就是在替你的工艺决定长什么样。
所以 klink 现在一个都不带,也不猜。没有声明 style 的渲染会直接报错并指出该抄哪个文件,而不是用别人的判断画一张图给你。
Upgrading in three steps / 三步升级
1. Get the style files. They ship with the package:
klink update # refreshes example_template/, touches nothing of yoursYou now have four files under example_template/imaging/:
| file | exit |
|---|---|
section_style.py |
imaging.xsection_run (only when render=true) |
sem_style.py |
imaging.sem_top |
viewer_style.py |
imaging.render3d |
blender_style.py |
imaging.blender |
Each is a documented walkthrough: every number says what it controls, what happens if you raise or lower it, and where it came from. Copy the ones you need out of example_template/ before editing — klink update refreshes that directory.
2. Turn one into JSON. The MCP tools take a path, not a Python object, and each style file writes its own:
python sem_style.py # -> sem_style.jsonFrom Python you can skip this and pass the object directly.
3. Pass it.
imaging.sem_top {
stack: "stack.json",
+ style: "sem_style.json",
output_dir: "figs"
}- render_sem_png(gds, STACK, "sem.png", out_color="sem_c.png")
+ render_sem_png(gds, STACK, "sem.png", STYLE, out_color="sem_c.png")A section GDS has no look, so imaging.xsection_run without render still needs no style at all.
三步:
klink update刷出四个 style 文件 →python sem_style.py生成 JSON → 调用时加style=。
截面只要 GDS(不加render)时完全不需要 style。
Two more things that will bite / 另外两个会绊人的地方
Stack layers need a colour. A VisualStack layer must declare color, unless it is kind="lattice" and drawn as atoms. There is no default colour any more.
Lattice figures need their species declared. blender_style.lattice.species must contain an entry for each atom the motif produces (C, or Mo and S). A missing one is an error naming the species and listing the ones you did declare.
层必须声明
color(画成原子的kind="lattice"层除外);晶格图必须声明每个原子物种的颜色和半径。
Also new / 顺带新增
- SEM views get a scale bar. There was previously no way to ask for one, in a picture calling itself an SEM view. It rounds to a 1/2/5 length and sits on a contrast plate so it stays readable over bright metal.
window_ummagnifies.width_pxonly ever added pixels to the same field of view — which is why the scale bar never changed with it. A window changes the field, and the bar follows.z_window_umandaxisreach the cross-section tool. Without a window the engine's multi-micron substrate fills the frame and your device is a hairline across the top. This is the single most common reason a section looks wrong.- Rulers are data.
annotation.list / get / insert / update / delete / clear / measure. A ruler lives in the view, not the layout — invisible toselection.getand to any saved GDS — so these are the only way to read one.imaging.xsection_run cut_from_ruler=truesections along the ruler you drew. A multi-segment ruler is refused with its segments listed rather than quietly flattened to a line you never drew.
Fixed / 修复
- The die render decided for itself what was metal. A luminance guess metallised 11 of 15 materials in a plain CMOS stack — the pale things there are substrate, wells, implants and oxides, while tungsten and silicide are dark — and since a metallic surface does not read as see-through it also defeated declared transparency, hiding every plug inside an opaque dielectric.
- A Chinese step name rendered as tofu boxes, silently, into the PNG, the film strip, the GIF and the sidecar hash. Labels now resolve a CJK-capable face by asking the font whether it actually has the glyphs, and report any character no installed font can draw.
- Step names that sanitise to nothing no longer leave dangling underscores in filenames.
If something used to work and now does not / 报错对照
| error | what it means |
|---|---|
style=... is required |
this change — follow the three steps; the message names the exact file |
'noise' is missing grain |
a hand-written style JSON; every field is required, start from the example |
color is required (#RRGGBB) |
a stack layer without a colour |
this motif contains a 'S' atom and the style declares no lattice.species['S'] |
add the species to your blender style |
Two blind tests ran against this release before it was tagged — one on a fresh klink init project, one through the MCP tools against a live KLayout session — and the defects they surfaced are fixed in it.