v0.4.0 — sulcus drawing
Draw sulci as well as ROIs, stored the way pycortex already stores sulci.
Sulci
- A sulcus is an open editable bezier curve. Pick
Sulcusin the panel's newROI | Sulcusselector and drag along the sulcus. - Export sulci (SVG) writes an
overlays.svg-compatible fragment: open, unfilled<path>elements in asulcilayer.quickflat.add_sulci, the WebGL viewer, and Inkscape read it natively. - Trace each hemisphere separately and give both strokes the same name — they merge into one
<g inkscape:label="…">with a<path>per hemisphere, exactly as pycortex's ownCaSis stored. - Sulci carry no vertex membership, because pycortex stores none (there is no
get_sulci_verts; sulci are display geometry).
ROIs are unchanged
Closed bezier, enclosed-vertex membership, and the pycortex-roidraw/vertexset-v2 JSON are byte-for-byte as before. v1/v2 files still import. No format bump.
Fixes
- Stale drag target. Pressing
Deletewhile dragging an anchor or handle left the drag pointing into the pre-splice array: past the end it corrupted the tangent-handle arrays; still in range it silently moved the wrong anchor. Pre-existing — it affected closed ROIs identically. - An open curve's endpoints are always corners and show a single tangent handle.
- Panel CSS: the segmented control's width/margin resets were inert due to selector specificity.
Internals
core/bezier.js gained open-curve support behind a closed flag rather than a fork. core/roi-model.js → core/shape-model.js (ROISet → ShapeSet, every shape carries a kind). New pure core/svg-export.js. No ViewerAdapter contract change.
Verified against a live pycortex viewer over the Chrome DevTools Protocol: sulcal paths bake with no trailing Z, ROI paths keep theirs, same-named sulci merge, names are XML-escaped, and no sulcus leaks into the ROI JSON. Not yet verified: feeding the exported fragment back through pycortex's svgoverlay.py parser. See TESTING.md.
Suite: 152 JS tests + Python tooling, green.