Skip to content

Commit 483ef52

Browse files
Lua binding updated
1 parent fb2ef18 commit 483ef52

15 files changed

Lines changed: 2889 additions & 37 deletions

docs/LUA_TUTORIAL.md

Lines changed: 396 additions & 7 deletions
Large diffs are not rendered by default.

src/lua_bind/alea_lua.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
* Metatable names
1515
* ============================================================================ */
1616

17-
#define ALEA_SYSTEM_MT "alea.System"
18-
#define ALEA_NODE_MT "alea.Node"
19-
#define ALEA_RAYRESULT_MT "alea.RaycastResult"
20-
#define ALEA_CURVES_MT "alea.SliceCurves"
21-
#define ALEA_MESHRESULT_MT "alea.MeshResult"
22-
#define ALEA_VOIDRESULT_MT "alea.VoidResult"
17+
#define ALEA_SYSTEM_MT "alea.System"
18+
#define ALEA_NODE_MT "alea.Node"
19+
#define ALEA_RAYRESULT_MT "alea.RaycastResult"
20+
#define ALEA_CURVES_MT "alea.SliceCurves"
21+
#define ALEA_MESHRESULT_MT "alea.MeshResult"
22+
#define ALEA_VOIDRESULT_MT "alea.VoidResult"
23+
#define ALEA_FRAMEBUFFER_MT "alea.Framebuffer"
2324

2425
/* ============================================================================
2526
* Userdata types
@@ -74,6 +75,10 @@ int luaopen_alea_surfaces(lua_State* L);
7475
int luaopen_alea_io(lua_State* L);
7576
int luaopen_alea_query(lua_State* L);
7677
int luaopen_alea_util(lua_State* L);
78+
int luaopen_alea_raycast(lua_State* L);
79+
int luaopen_alea_slice(lua_State* L);
80+
int luaopen_alea_render(lua_State* L);
81+
int luaopen_alea_mesh(lua_State* L);
7782

7883
/* The main module opener (called from lua_main.c) */
7984
int luaopen_alea(lua_State* L);

src/lua_bind/lua_mesh.c

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// SPDX-FileCopyrightText: 2026 Giovanni MARIANO
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
#include "alea_lua.h"
6+
#include "alea_mesh.h"
7+
#include <stdlib.h>
8+
9+
/* ============================================================================
10+
* Userdata
11+
* ============================================================================ */
12+
13+
typedef struct {
14+
alea_mesh_result_t* ptr;
15+
} alea_lua_mesh_result_t;
16+
17+
static alea_lua_mesh_result_t* check_meshresult(lua_State* L, int idx) {
18+
return (alea_lua_mesh_result_t*)luaL_checkudata(L, idx, ALEA_MESHRESULT_MT);
19+
}
20+
21+
/* ============================================================================
22+
* Config helper: Lua table -> alea_mesh_config_t
23+
* ============================================================================ */
24+
25+
static void lua_to_mesh_config(lua_State* L, int idx, alea_mesh_config_t* cfg) {
26+
luaL_checktype(L, idx, LUA_TTABLE);
27+
28+
lua_getfield(L, idx, "x_min");
29+
if (!lua_isnil(L, -1)) cfg->x_min = lua_tonumber(L, -1);
30+
lua_pop(L, 1);
31+
lua_getfield(L, idx, "x_max");
32+
if (!lua_isnil(L, -1)) cfg->x_max = lua_tonumber(L, -1);
33+
lua_pop(L, 1);
34+
lua_getfield(L, idx, "y_min");
35+
if (!lua_isnil(L, -1)) cfg->y_min = lua_tonumber(L, -1);
36+
lua_pop(L, 1);
37+
lua_getfield(L, idx, "y_max");
38+
if (!lua_isnil(L, -1)) cfg->y_max = lua_tonumber(L, -1);
39+
lua_pop(L, 1);
40+
lua_getfield(L, idx, "z_min");
41+
if (!lua_isnil(L, -1)) cfg->z_min = lua_tonumber(L, -1);
42+
lua_pop(L, 1);
43+
lua_getfield(L, idx, "z_max");
44+
if (!lua_isnil(L, -1)) cfg->z_max = lua_tonumber(L, -1);
45+
lua_pop(L, 1);
46+
47+
lua_getfield(L, idx, "nx");
48+
if (!lua_isnil(L, -1)) cfg->nx = (int)lua_tointeger(L, -1);
49+
lua_pop(L, 1);
50+
lua_getfield(L, idx, "ny");
51+
if (!lua_isnil(L, -1)) cfg->ny = (int)lua_tointeger(L, -1);
52+
lua_pop(L, 1);
53+
lua_getfield(L, idx, "nz");
54+
if (!lua_isnil(L, -1)) cfg->nz = (int)lua_tointeger(L, -1);
55+
lua_pop(L, 1);
56+
57+
lua_getfield(L, idx, "format");
58+
if (!lua_isnil(L, -1)) cfg->format = (alea_mesh_format_t)(int)lua_tointeger(L, -1);
59+
lua_pop(L, 1);
60+
61+
lua_getfield(L, idx, "void_material_id");
62+
if (!lua_isnil(L, -1)) cfg->void_material_id = (int)lua_tointeger(L, -1);
63+
lua_pop(L, 1);
64+
65+
lua_getfield(L, idx, "auto_pad");
66+
if (!lua_isnil(L, -1)) cfg->auto_pad = lua_tonumber(L, -1);
67+
lua_pop(L, 1);
68+
}
69+
70+
/* ============================================================================
71+
* System methods
72+
* ============================================================================ */
73+
74+
/* sys:mesh_sample(config) -> MeshResult */
75+
static int l_mesh_sample(lua_State* L) {
76+
alea_system_t* sys = alea_get_sys(L, 1);
77+
alea_mesh_config_t cfg;
78+
alea_mesh_config_init(&cfg);
79+
if (lua_istable(L, 2))
80+
lua_to_mesh_config(L, 2, &cfg);
81+
82+
alea_lua_mesh_result_t* ud = (alea_lua_mesh_result_t*)lua_newuserdata(
83+
L, sizeof(alea_lua_mesh_result_t));
84+
ud->ptr = NULL;
85+
luaL_setmetatable(L, ALEA_MESHRESULT_MT);
86+
87+
ud->ptr = alea_mesh_sample(sys, &cfg);
88+
if (!ud->ptr)
89+
return luaL_error(L, "mesh_sample failed: %s", alea_error());
90+
return 1;
91+
}
92+
93+
/* sys:mesh_export(config, filename) */
94+
static int l_mesh_export_system(lua_State* L) {
95+
alea_system_t* sys = alea_get_sys(L, 1);
96+
alea_mesh_config_t cfg;
97+
alea_mesh_config_init(&cfg);
98+
if (lua_istable(L, 2))
99+
lua_to_mesh_config(L, 2, &cfg);
100+
const char* filename = luaL_checkstring(L, 3);
101+
102+
if (alea_mesh_export_system(sys, &cfg, filename) != 0)
103+
return luaL_error(L, "mesh_export failed: %s", alea_error());
104+
return 0;
105+
}
106+
107+
/* ============================================================================
108+
* MeshResult methods
109+
* ============================================================================ */
110+
111+
/* mesh:export(format, filename) */
112+
static int l_meshresult_export(lua_State* L) {
113+
alea_lua_mesh_result_t* ud = check_meshresult(L, 1);
114+
if (!ud->ptr) return luaL_error(L, "mesh result freed");
115+
int fmt = (int)luaL_checkinteger(L, 2);
116+
const char* filename = luaL_checkstring(L, 3);
117+
if (alea_mesh_export(ud->ptr, (alea_mesh_format_t)fmt, filename) != 0)
118+
return luaL_error(L, "mesh:export failed: %s", alea_error());
119+
return 0;
120+
}
121+
122+
/* mesh:info() -> table */
123+
static int l_meshresult_info(lua_State* L) {
124+
alea_lua_mesh_result_t* ud = check_meshresult(L, 1);
125+
if (!ud->ptr) return luaL_error(L, "mesh result freed");
126+
alea_mesh_result_t* m = ud->ptr;
127+
128+
lua_createtable(L, 0, 5);
129+
lua_pushinteger(L, m->nx); lua_setfield(L, -2, "nx");
130+
lua_pushinteger(L, m->ny); lua_setfield(L, -2, "ny");
131+
lua_pushinteger(L, m->nz); lua_setfield(L, -2, "nz");
132+
lua_pushinteger(L, m->num_materials); lua_setfield(L, -2, "num_materials");
133+
134+
/* unique_materials */
135+
lua_createtable(L, m->num_materials, 0);
136+
for (int i = 0; i < m->num_materials; i++) {
137+
lua_pushinteger(L, m->unique_materials[i]);
138+
lua_rawseti(L, -2, i + 1);
139+
}
140+
lua_setfield(L, -2, "unique_materials");
141+
return 1;
142+
}
143+
144+
/* mesh:material_ids() -> flat table */
145+
static int l_meshresult_material_ids(lua_State* L) {
146+
alea_lua_mesh_result_t* ud = check_meshresult(L, 1);
147+
if (!ud->ptr) return luaL_error(L, "mesh result freed");
148+
alea_mesh_result_t* m = ud->ptr;
149+
size_t total = (size_t)m->nx * (size_t)m->ny * (size_t)m->nz;
150+
lua_createtable(L, (int)total, 0);
151+
for (size_t i = 0; i < total; i++) {
152+
lua_pushinteger(L, m->material_ids[i]);
153+
lua_rawseti(L, -2, (lua_Integer)(i + 1));
154+
}
155+
return 1;
156+
}
157+
158+
/* mesh:cell_ids() -> flat table */
159+
static int l_meshresult_cell_ids(lua_State* L) {
160+
alea_lua_mesh_result_t* ud = check_meshresult(L, 1);
161+
if (!ud->ptr) return luaL_error(L, "mesh result freed");
162+
alea_mesh_result_t* m = ud->ptr;
163+
size_t total = (size_t)m->nx * (size_t)m->ny * (size_t)m->nz;
164+
lua_createtable(L, (int)total, 0);
165+
for (size_t i = 0; i < total; i++) {
166+
lua_pushinteger(L, m->cell_ids[i]);
167+
lua_rawseti(L, -2, (lua_Integer)(i + 1));
168+
}
169+
return 1;
170+
}
171+
172+
/* __gc */
173+
static int l_meshresult_gc(lua_State* L) {
174+
alea_lua_mesh_result_t* ud = check_meshresult(L, 1);
175+
if (ud->ptr) {
176+
alea_mesh_result_free(ud->ptr);
177+
ud->ptr = NULL;
178+
}
179+
return 0;
180+
}
181+
182+
/* ============================================================================
183+
* Registration
184+
* ============================================================================ */
185+
186+
static const luaL_Reg mesh_system_methods[] = {
187+
{"mesh_sample", l_mesh_sample},
188+
{"mesh_export", l_mesh_export_system},
189+
{NULL, NULL}
190+
};
191+
192+
static const luaL_Reg meshresult_meta[] = {
193+
{"__gc", l_meshresult_gc},
194+
{NULL, NULL}
195+
};
196+
197+
static const luaL_Reg meshresult_methods[] = {
198+
{"export", l_meshresult_export},
199+
{"info", l_meshresult_info},
200+
{"material_ids", l_meshresult_material_ids},
201+
{"cell_ids", l_meshresult_cell_ids},
202+
{NULL, NULL}
203+
};
204+
205+
int luaopen_alea_mesh(lua_State* L) {
206+
/* Add system methods */
207+
luaL_getmetatable(L, ALEA_SYSTEM_MT);
208+
lua_getfield(L, -1, "__index");
209+
luaL_setfuncs(L, mesh_system_methods, 0);
210+
lua_pop(L, 2);
211+
212+
/* Create MeshResult metatable */
213+
luaL_newmetatable(L, ALEA_MESHRESULT_MT);
214+
luaL_setfuncs(L, meshresult_meta, 0);
215+
lua_newtable(L);
216+
luaL_setfuncs(L, meshresult_methods, 0);
217+
lua_setfield(L, -2, "__index");
218+
lua_pop(L, 1);
219+
220+
return 0;
221+
}

0 commit comments

Comments
 (0)