function refine_demo %REFINE_DEMO Interactive surfacefun mesh refinement via a uihtml figure. % % Runs in the numbl IDE and via `numbl run --plot`. Shows a cubed-sphere % surfacemesh rendered with numbl's surface renderer (duplicated into the % bundled web app). Drag the "Refinement level" slider in the figure: the % page sends the level to this script, which refines the base mesh with % surfacefun and sends the new patches back — the figure re-renders without % losing the camera orientation. % % The web app is prebuilt into app/dist/index.html (cd app && npm run build). mip load --install flatironinstitute/flatironinstitute/surfacefun here = fileparts(mfilename('fullpath')); html = fileread(fullfile(here, 'app', 'dist', 'index.html')); maxLevel = 3; % slider range 0..maxLevel n = 8; % Chebyshev order per patch dom0 = surfacemesh.sphere(n); % base cubed sphere (6 patches) data0 = meshToData(dom0, 0, maxLevel); fig = figure; gl = uigridlayout(fig, [1 1], 'Padding', [0 0 0 0], ... 'RowHeight', {'1x'}, 'ColumnWidth', {'1x'}); uihtml(gl, 'HTMLSource', html, 'Data', data0, ... 'HTMLEventReceivedFcn', @(src, ev) onRefine(src, ev, dom0, maxLevel)); end function onRefine(src, ev, dom0, maxLevel) % Refine the base mesh to the requested absolute level and send it back. if ~strcmp(ev.HTMLEventName, 'refine') return end level = max(0, min(maxLevel, round(ev.HTMLEventData))); if level == 0 dom = dom0; else dom = refine(dom0, level); end sendEventToHTMLSource(src, 'mesh', meshToData(dom, level, maxLevel)); fprintf('refined to level %d: %d patches\n', level, length(dom)); end function data = meshToData(dom, level, maxLevel) % Pack a surfacemesh into a plain struct the web app can render: one flat % (column-major) x/y/z array per patch, each an n-by-n grid. np = length(dom); px = cell(1, np); py = cell(1, np); pz = cell(1, np); for k = 1:np % real() drops any (all-zero) imaginary part the solver/JIT may carry; % the geometry is real and jsonencode (numbl and MATLAB) rejects complex. px{k} = real(dom.x{k}(:).'); py{k} = real(dom.y{k}(:).'); pz{k} = real(dom.z{k}(:).'); end data = struct(); data.n = size(dom.x{1}, 1); data.x = px; data.y = py; data.z = pz; data.npatches = np; data.level = level; data.maxLevel = maxLevel; end