lingmodeler
↓ 0 downloadsLingModeler: 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
Keywords 3d, modeling, vector, svg, gltf, obj, rigging, animation, textures, ling
lingfu install lingmodelerCode / Files (67)
ling/settings.ling
# ━━━ settings.ling — settings.txt (next to the program) and the recent-files list ━━━
fn settings_path() { return fs_join(st_get("default_root", "."), "settings.txt") }
fn settings_load() {
bind p = settings_path()
st_lclear("recent")
if !file_exists(p) { settings_defaults() return 0.0 }
settings_defaults()
bind lines = str_split(read_file(p), "\n")
bind i = 0.0
while i < len(lines) {
bind ln = str_trim(list_get(lines, i))
bind eq = str_find(ln, "=")
if eq > 0.0 {
bind k = str_slice(ln, 0.0, eq)
bind v = str_slice(ln, eq + 1.0, str_len(ln) - eq - 1.0)
if k == "recent" { if v != "" && st_llen("recent") < 10.0 { st_lpush("recent", v) } }
else if k == "last_dir" { st_set("last_dir", v) }
else { st_set(k, to_number(v)) }
}
bind i = i + 1.0
}
settings_recent_menu()
}
fn settings_defaults() {
st_set("theme_black", 1.0)
st_set("load_last", 0.0)
st_set("reduce_motion", 0.0)
st_set("wp_autonorm", 1.0)
st_set("autosave", 5.0)
st_set("orbit_sens", 1.0)
st_set("cam_fov", 50.0)
st_set("show_sidebar", 1.0)
st_set("show_props", 1.0)
st_set("show_timeline", 1.0)
}
fn settings_save() {
bind out = list_new()
bind i = 0.0
while i < st_llen("recent") {
bind out = list_push(out, "recent=" + st_lget("recent", i))
bind i = i + 1.0
}
bind keys = ["theme_black", "load_last", "reduce_motion", "wp_autonorm", "autosave", "orbit_sens", "cam_fov", "show_sidebar", "show_props", "show_timeline", "v3_shade", "v3_grid", "v3_cull"]
bind i = 0.0
while i < len(keys) {
bind k = list_get(keys, i)
bind out = list_push(out, k + "=" + num_str(st_get(k, 0.0)))
bind i = i + 1.0
}
bind out = list_push(out, "last_dir=" + st_get("last_dir", ""))
write_file(settings_path(), p_join(out, "\n") + "\n")
}
fn settings_recent_add(path) {
if path == "" { return 0.0 }
bind keep = list_new()
bind keep = list_push(keep, path)
bind i = 0.0
while i < st_llen("recent") {
bind r = st_lget("recent", i)
if r != path && len(keep) < 10.0 { bind keep = list_push(keep, r) }
bind i = i + 1.0
}
st_lclear("recent")
bind i = 0.0
while i < len(keep) { st_lpush("recent", list_get(keep, i)) bind i = i + 1.0 }
st_set("last_dir", fs_parent(path))
settings_recent_menu()
settings_save()
}
fn settings_recent_menu() {
bind items = list_new()
bind i = 0.0
while i < st_llen("recent") {
bind p = st_lget("recent", i)
bind items = list_push(items, path_base(p) + "|recent:" + num_str(i) + "||file")
bind i = i + 1.0
}
if len(items) < 0.5 { bind items = ["(empty)|none||"] }
st_set("recent_menu", items)
}
fn path_base(p) {
bind q = str_replace(p, "\\", "/")
bind parts = str_split(q, "/")
return list_get(parts, len(parts) - 1.0)
}
fn path_ext(p) {
bind b = str_lower(path_base(p))
bind d = str_find(b, ".")
if d < 0.0 { return "" }
# last dot
bind e = ""
bind parts = str_split(b, ".")
if len(parts) > 1.0 { bind e = list_get(parts, len(parts) - 1.0) }
return e
}
fn path_stem(p) {
bind b = path_base(p)
bind parts = str_split(b, ".")
if len(parts) < 2.0 { return b }
bind out = list_get(parts, 0)
bind i = 1.0
while i < len(parts) - 1.0 { bind out = out + "." + list_get(parts, i) bind i = i + 1.0 }
return out
}
fn path_swap_ext(p, ext) {
bind dir = fs_parent(p)
bind s = path_stem(p) + "." + ext
if dir == "" { return s }
return fs_join(dir, s)
}