灵符lingfu

lingmodeler

↓ 0 downloads

LingModeler: box modeling with quads and tris, rigging + weight painting, 2D vector illustration and animation, procedural textures and game assets; .lmesh / .ling native formats, OBJ, glTF and SVG import / export

Windows · x86-64Linux · x86-64LingOS · x86-64LingOS · Pi 5 ARM64Web · WASM
Keywords 3d, modeling, vector, svg, gltf, obj, rigging, animation, textures, ling
lingfu install lingmodeler
LicenseApache-2.0 OR MIT
Authorsling-lin
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (67)

tools/make_screenshots.py
"""Regenerate the README screenshots in docs/screenshots/ with scripted LingModeler sessions.
   python tools/make_screenshots.py            (uses ../ling/target/release/ling.exe, or LING_BIN)"""
import glob, os, shutil, subprocess

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LING = os.environ.get('LING_BIN', os.path.join(ROOT, '..', 'ling', 'target', 'release', 'ling.exe'))
OUT = os.path.join(ROOT, 'docs', 'screenshots')

SHOTS = [
    # name, extra args, scripted actions ("frame,action;..."), frame to capture
    ('model', [], '2,test.new;3,gen:character;4,test.cursor:2.6/0/0.4;5,gen:tree;6,test.cursor:-2.6/0/0.2;7,gen:rock;'
                  '8,test.cursor:0.6/0/-3;9,gen:crystal;10,test.cursor:-2.4/0/-2.8;11,gen:barrel;12,test.cursor:3/0/-2.8;'
                  '13,gen:crate;14,test.cursor:0/0/0;15,mode:0;16,view.frame_all', 26),
    ('edit', [], '2,mode:1;3,set:sel_mode=2;4,test.selface:4;5,mesh.extrude;6,test.confirm;7,mesh.inset;8,mesh.extrude;'
                 '9,test.confirm;10,test.selface:0;11,mesh.inset', 20),
    ('rig', ['--open', 'examples/character.lmesh'], '3,mode:2;4,test.selbone:13;5,view.frame_all', 14),
    ('weights', ['--open', 'examples/character.lmesh'], '3,mode:3;4,test.selbone:2;5,view.frame_all', 14),
    ('pose', ['--open', 'examples/character.lmesh'], '3,mode:4;4,test.selbone:6;5,test.frame:6;6,view.frame_all', 16),
    ('vector', ['--open', 'examples/shapes.ling'], '3,mode:5;4,vtest.print', 12),
    ('anim', ['--open', 'examples/shapes.ling'], '3,mode:6;4,set:vc_onion=1;5,test.frame:10', 14),
    ('texture', [], '2,mode:7;3,set:tx_cur=2;4,set:tx_time=0.8', 12),
]


def run(name, extra, actions, frame):
    tag = 'readme_' + name
    for f in glob.glob(os.path.join(ROOT, 'screenshots', '*_%s_*.png' % tag)):
        os.remove(f)
    cmd = [LING, 'run', '--interp', 'ling/main.ling'] + extra + ['--shot', str(frame), '--name', tag, '--do', actions]
    r = subprocess.run(cmd, cwd=ROOT, capture_output=True, text=True, timeout=600)
    shots = sorted(glob.glob(os.path.join(ROOT, 'screenshots', '*_%s_*.png' % tag)))
    if not shots:
        print(name, 'FAILED', (r.stdout + r.stderr)[-400:])
        return
    shutil.move(shots[-1], os.path.join(OUT, name + '.png'))
    print(name, 'ok')


os.makedirs(OUT, exist_ok=True)
for s in SHOTS:
    run(*s)
# the LingOS captures come from tools/lingos_qemu_test.sh and tools/lingos_qemu_test_rpi.sh
for src, dst in (('screenshots/lingos/app.png', 'lingos-x86_64.png'), ('screenshots/lingos-rpi/app.png', 'lingos-rpi.png')):
    p = os.path.join(ROOT, src)
    if os.path.exists(p):
        shutil.copy(p, os.path.join(OUT, dst))
        print(dst, 'copied')

← Back to index