%D \module %D [ file=mp-thrd.mpxl, %D version=2026.05.01, %D title=\CONTEXT\ \METAPOST\ graphics, %D subtitle=Scene based 3D plotting, %D author=Mikael Sundqvist & Hans Hagen & Chat 5.5] %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. if known metafun_loaded_thrd : endinput ; fi ; newinternal boolean metafun_loaded_thrd ; metafun_loaded_thrd := true ; immutable metafun_loaded_thrd ; runscript("lua.registercode('mlib-thr.lmt')"); presetparameters "lmtthreedscene" [ bytemap = 1, % crop = true, maxfragment = 0, % width = 600, % height = 600, % bytewidth = "", % byteheight = "", supersample = 1, resolution = 300, projection = "perspective", eye = (3,-4,2), target = (0,0,0), up = (0,0,1), forward = (0,0,0), fov = 45, light = (-1,-1,-1), intensity = 1, % stipple = [ % edgeboost = .20, % gamma = 1.25, % errorthreshold = .5, % dotradius = 0, % levels = 2, % tonedots = true, % outline = false, % outlinethreshold = .85, % outlineradius = 0, % color = black, % backgroundcolor = white % ] ] ; presetparameters "lmtthreedmaterial" [ name = "default", diffuse = (.7,.7,.7), specular = (0,0,0), shininess = 10, ambient = .18, twosided = false, opacity = 1, ontop = false, dx = 0, dy = 0, ] ; presetparameters "lmtthreedsurface" [ kind = "graph", id = "surface", code = "0", dfdx = "", dfdy = "", normal = "smooth", xstep = "", ystep = "", xmin = -1, xmax = 1, ymin = -1, ymax = 1, nx = 32, ny = 32, material = "default" ] ; presetparameters "lmtthreedparametricsurface" [ kind = "parametric", id = "surface", x = "u", y = "v", z = "0", xu = "", yu = "", zu = "", xv = "", yv = "", zv = "", normal = "smooth", umin = 0, umax = 2pi, vmin = 0, vmax = 2pi, nu = 64, nv = 32, ustep = "", vstep = "", width = .35, boundary = false, boundarycolor = black, boundarywidth = .5, % -1, material = "default" ] ; presetparameters "lmtthreedimplicitsurface" [ kind = "implicit", id = "surface", code = "x*x + y*y + z*z - 1", dfdx = "", dfdy = "", dfdz = "", normal = "smooth", xmin = -1, xmax = 1, ymin = -1, ymax = 1, zmin = -1, zmax = 1, nx = "", ny = "", nz = "", iso = 0, material = "default" ] ; presetparameters "lmtthreedexternalsurface" [ kind = "external", id = "surface", % filename = "", scale = 1, % normal = "smooth", material = "default" ] ; presetparameters "lmtthreedinternalsurface" [ kind = "internal", id = "surface", % name = "", scale = 1, % normal = "smooth", material = "default" ] ; presetparameters "lmtthreedplane" [ kind = "plane", id = "plane", normal = (0,0,1), center = (0,0,0), usize = 2, vsize = 2, material = "default" ] ; presetparameters "lmtthreedcurve" [ kind = "curve", id = "curve", x = "t", y = "0", z = "0", tmin = 0, tmax = 1, nt = 64, % tstep = 0, material = "default" ] ; presetparameters "lmtthreedintersection" [ kind = "intersection", id = "intersection", first = "surface", second = "plane", nx = 0, ny = 0, material = "default" ] ; presetparameters "lmtthreedvisiblegrid" [ id = "", origin = (0,0,0), uaxis = (1,0,0), vaxis = (0,1,0), umin = -1, umax = 1, ustep = .25, vmin = -1, vmax = 1, vstep = .25, color = black, width = -1 ] ; presetparameters "lmtthreedvisibleaxis" [ id = "", origin = (0,0,0), xaxis = (1,0,0), yaxis = (0,1,0), zaxis = (0,0,1), xmin = -1, xmax = 1, ymin = -1, ymax = 1, zmin = 0, zmax = 1, color = black, width = -1 ] ; presetparameters "lmtthreedvisibleticks" [ id = "", origin = (0,0,0), axis = (1,0,0), tickaxis = (0,1,0), first = -1, last = 1, step = 1, size = .1, color = black, width = -1 ] ; presetparameters "lmtthreedvisiblespecial" [ id = "", % from = (0,0,0), % to = (0,0,0), % at = (0,0,0), color = black, width = -1 ] ; presetparameters "lmtthreedvisiblesegment" [ id = "", first = (0,0,0), second = (1,0,0), color = black, width = -1 ] ; newscriptindex mfid_scene_width ; mfid_scene_width := scriptindex "lmt_scene_width" ; newscriptindex mfid_scene_height ; mfid_scene_height := scriptindex "lmt_scene_height" ; newscriptindex mfid_scene_bytemap ; mfid_scene_bytemap := scriptindex "lmt_scene_bytemap" ; def lmt_scene_width = runscript mfid_scene_width enddef ; def lmt_scene_height = runscript mfid_scene_height enddef ; def lmt_scene_bytemap = runscript mfid_scene_bytemap enddef ; % newscriptindex mfid_scene_overlay_path_count ; mfid_scene_overlay_path_count := scriptindex "lmt_scene_overlay_path_count" ; % newscriptindex mfid_scene_overlay_path_data ; mfid_scene_overlay_path_data := scriptindex "lmt_scene_overlay_path_data" ; % newscriptindex mfid_scene_overlay_path_width ; mfid_scene_overlay_path_width := scriptindex "lmt_scene_overlay_path_width" ; % newscriptindex mfid_scene_overlay_path_color ; mfid_scene_overlay_path_color := scriptindex "lmt_scene_overlay_path_color" ; % def lmt_scene_overlay_path_count = runscript mfid_scene_overlay_path_count enddef ; % def lmt_scene_overlay_path_data (expr j) = runscript mfid_scene_overlay_path_data j enddef ; % def lmt_scene_overlay_path_width (expr j) = runscript mfid_scene_overlay_path_width j enddef ; % def lmt_scene_overlay_path_color (expr j) = runscript mfid_scene_overlay_path_color j enddef ; newscriptindex mfid_scene_project_point ; mfid_scene_project_point := scriptindex "lmt_scene_project_point" ; newscriptindex mfid_scene_calculate_normal ; mfid_scene_calculate_normal := scriptindex "lmt_scene_calculate_normal" ; newscriptindex mfid_scene_project_visible ; mfid_scene_project_visible := scriptindex "lmt_scene_project_visible" ; def lmt_scene_project_point expr j = runscript mfid_scene_project_point j enddef ; def lmt_scene_calculate_normal (expr n, j) = runscript mfid_scene_calculate_normal n j enddef ; def lmt_scene_project_visible expr j = runscript mfid_scene_project_visible j enddef ; let lmt_scene_point = lmt_scene_project_point ; let lmt_scene_normal = lmt_scene_calculate_normal ; let lmt_scene_visible = lmt_scene_project_visible ; def lmt_scene_material = applyparameters "lmtthreedmaterial" "lmt_scene_do_material" enddef ; def lmt_scene_parametric = applyparameters "lmtthreedparametricsurface" "lmt_scene_do_parametric" enddef ; def lmt_scene_implicit = applyparameters "lmtthreedimplicitsurface" "lmt_scene_do_implicit" enddef ; def lmt_scene_internal = applyparameters "lmtthreedinternalsurface" "lmt_scene_do_internal" enddef ; def lmt_scene_external = applyparameters "lmtthreedexternalsurface" "lmt_scene_do_external" enddef ; def lmt_scene_surface = applyparameters "lmtthreedsurface" "lmt_scene_do_surface" enddef ; def lmt_scene_plane = applyparameters "lmtthreedplane" "lmt_scene_do_plane" enddef ; def lmt_scene_curve = applyparameters "lmtthreedcurve" "lmt_scene_do_curve" enddef ; def lmt_scene_intersection = applyparameters "lmtthreedintersection" "lmt_scene_do_intersection" enddef ; vardef lmt_scene_do_material = lua.mp.lmt_scene_set_material () ; enddef ; vardef lmt_scene_do_parametric = lua.mp.lmt_scene_set_parametric () ; enddef ; vardef lmt_scene_do_implicit = lua.mp.lmt_scene_set_implicit () ; enddef ; vardef lmt_scene_do_internal = lua.mp.lmt_scene_set_internal () ; enddef ; vardef lmt_scene_do_external = lua.mp.lmt_scene_set_external () ; enddef ; vardef lmt_scene_do_surface = lua.mp.lmt_scene_set_surface () ; enddef ; vardef lmt_scene_do_plane = lua.mp.lmt_scene_set_plane () ; enddef ; vardef lmt_scene_do_curve = lua.mp.lmt_scene_set_curve () ; enddef ; vardef lmt_scene_do_intersection = lua.mp.lmt_scene_set_intersection() ; enddef ; def lmt_scene_segment = applyparameters "lmtthreedvisiblesegment" "lmt_scene_do_segment" enddef ; def lmt_scene_grid = applyparameters "lmtthreedvisiblegrid" "lmt_scene_do_grid" enddef ; def lmt_scene_axis = applyparameters "lmtthreedvisibleaxis" "lmt_scene_do_axis" enddef ; def lmt_scene_ticks = applyparameters "lmtthreedvisibleticks" "lmt_scene_do_ticks" enddef ; def lmt_scene_special = applyparameters "lmtthreedvisiblespecial" "lmt_scene_do_special" enddef ; vardef lmt_scene_do_segment = lua.mp.lmt_scene_overlay_segment() ; enddef ; vardef lmt_scene_do_grid = lua.mp.lmt_scene_overlay_grid () ; enddef ; vardef lmt_scene_do_axis = lua.mp.lmt_scene_overlay_axis () ; enddef ; vardef lmt_scene_do_ticks = lua.mp.lmt_scene_overlay_ticks () ; enddef ; vardef lmt_scene_do_special = lua.mp.lmt_scene_overlay_special() ; enddef ; % this will change: % % proper begin /end % no lmt variables % todo : tick labels % todo : axis labels % todo : get position % todo : push/pop parameters % todo : cleanup results boolean lmt_scene_rendered ; lmt_scene_rendered := false ; numeric lmt_scene_nesting ; lmt_scene_nesting := 0 ; def lmt_load_mlib_thr = runscript("lua.registercode('mlib-thr.lmt')"); let lmt_load_mlib_thr = relax ; enddef ; def lmt_scene_start = lmt_load_mlib_lsy ; applyparameters "lmtthreedscene" "lmt_scene_do_start" enddef ; def lmt_scene_do_start = if lmt_scene_nesting = 0 : lua.mp.lmt_scene_manage_prepare() ; lmt_scene_rendered := false ; fi ; lmt_scene_nesting := lmt_scene_nesting + 1 ; enddef ; def lmt_scene_render = if not lmt_scene_rendered and (lmt_scene_nesting = 1) : lua.mp.lmt_scene_manage_render() ; lmt_scene_flush_bytemap ; % lmt_scene_flush_paths ; % lmt_scene_flush_labels ; lmt_scene_rendered := true ; fi ; enddef ; def lmt_scene_stop = lmt_scene_render ; lmt_scene_nesting := lmt_scene_nesting - 1 ; if lmt_scene_nesting = 0 : lua.mp.lmt_scene_manage_reset() ; fi enddef ; numeric lmt_scene_final_width ; numeric lmt_scene_final_height ; def lmt_scene_flush_bytemap = begingroup ; save p; path p ; p := unitsquare xyscaled (lmt_scene_width,lmt_scene_height) if (hasparameter "lmtthreedscene" "width") : if (hasparameter "lmtthreedscene" "height") : xsized (getparameter "lmtthreedscene" "width"),getparameter "lmtthreedscene" "height")) else : xsized (getparameter "lmtthreedscene" "width") fi elseif (hasparameter "lmtthreedscene" "height") : ysized (getparameter "lmtthreedscene" "height") fi ; lmt_final_width := bbwidth (p) ; lmt_final_height := bbheight(p) ; endgroup ; draw unitsquare xyscaled(lmt_final_width,lmt_final_height) withbytemap (lmt_scene_bytemap) withbytemasked 255 withpen pencircle scaled 0 ; enddef ; def lmt_scene_project_point expr j = ( (runscript mfid_scene_project_point j) xscaled (lmt_final_width /lmt_scene_width ) yscaled (lmt_final_height/lmt_scene_height) ) enddef ; vardef lmt_scene_bounds = unitsquare xyscaled(lmt_final_width,lmt_final_height) enddef ; let lmt_scene_point = lmt_scene_project_point ;