nx_t2mesh.nx source
↩ module page · 123 lines · 5852 B
1// nx_t2mesh.nx -- sovereign TEXT-to-MESH generator v0 (generator-path R2). NOT a neural DreamFusion/Shap-E
2// model -- a DATA-DRIVEN PARAMETRIC generator: a prompt selects an object TEMPLATE (a recipe of SDF primitives),
3// which fills the field; nx_meshgen (surface nets) then EMITS the mesh. The point vs hand-crafting: ONE call
4// emits N different objects from N prompts, and the vocabulary GROWS AS DATA (add a template = add an object).
5// The critic scores each emitted object. Honest ceiling: parametric (not free-form), a spine to grow toward
6// neural later. license_tier: ORIGINAL
7import "nx_syscalls.nx"
8import "nx_sdfrender.nx"
9const K_MAGIC_1050: i64 = 1050
10
11func t2m_set(base: i64, idx: i64, cx: i64, cy: i64, cz: i64, rx: i64, ry: i64, rz: i64) -> i64 {
12 let p: *i64 = (base + O_PARTS) as *i64
13 p[idx * 6] = cx; p[idx * 6 + 1] = cy; p[idx * 6 + 2] = cz
14 p[idx * 6 + 3] = rx; p[idx * 6 + 4] = ry; p[idx * 6 + 5] = rz
15 return 0
16}
17func t2m_conf(base: i64, count: i64, blend: i64) -> i64 {
18 let np: *i64 = (base + O_NPART) as *i64; np[0] = count
19 let kb: *i64 = (base + O_KBLEND) as *i64; kb[0] = blend
20 sdf_clear_ops(base, PARTS_CAP) // reused arenas must not inherit a previous object's carve ops
21 return 0
22}
23
24// substring keyword match (no OOB): stop=1 matched-all, stop=2 mismatch.
25func t2m_has(s: *u8, kw: *u8) -> i64 {
26 var i: i64 = 0
27 while s[i] != (0 as u8) {
28 var k: i64 = 0
29 var stop: i64 = 0
30 while stop == 0 {
31 if kw[k] == (0 as u8) { stop = 1 } else {
32 let sc: *u8 = (s as i64 + i + k) as *u8
33 if sc[0] != kw[k] { stop = 2 } else { k = k + 1 }
34 }
35 }
36 if stop == 1 { return 1 }
37 i = i + 1
38 }
39 return 0
40}
41// prompt -> object id (data-driven vocabulary; grows by adding a keyword+template)
42func t2m_id_of(prompt: *u8) -> i64 {
43 if t2m_has(prompt, "snow" as *u8) == 1 { return 1 }
44 if t2m_has(prompt, "dumbbell" as *u8) == 1 { return 2 }
45 if t2m_has(prompt, "barbell" as *u8) == 1 { return 2 }
46 if t2m_has(prompt, "weight" as *u8) == 1 { return 2 }
47 if t2m_has(prompt, "tree" as *u8) == 1 { return 3 }
48 if t2m_has(prompt, "mushroom" as *u8) == 1 { return 4 }
49 if t2m_has(prompt, "bottle" as *u8) == 1 { return 5 }
50 if t2m_has(prompt, "person" as *u8) == 1 { return 6 }
51 if t2m_has(prompt, "human" as *u8) == 1 { return 6 }
52 if t2m_has(prompt, "body" as *u8) == 1 { return 6 }
53 if t2m_has(prompt, "elara" as *u8) == 1 { return 6 }
54 if t2m_has(prompt, "figure" as *u8) == 1 { return 6 }
55 if t2m_has(prompt, "cactus" as *u8) == 1 { return 7 }
56 if t2m_has(prompt, "capsule" as *u8) == 1 { return 8 }
57 if t2m_has(prompt, "pill" as *u8) == 1 { return 8 }
58 return 0 // default: sphere/ball
59}
60func t2m_name(id: i64) -> *u8 {
61 if id == 1 { return "snowman" as *u8 }
62 if id == 2 { return "dumbbell" as *u8 }
63 if id == 3 { return "tree" as *u8 }
64 if id == 4 { return "mushroom" as *u8 }
65 if id == 5 { return "bottle" as *u8 }
66 if id == 6 { return "person" as *u8 }
67 if id == 7 { return "cactus" as *u8 }
68 if id == 8 { return "capsule" as *u8 }
69 return "sphere" as *u8
70}
71
72// build the SDF field for object `id` into base (fills O_PARTS + O_NPART + O_KBLEND).
73func t2m_gen(base: i64, id: i64) -> i64 {
74 if id == 1 { // snowman: 3 stacked spheres + carrot nose
75 t2m_set(base, 0, 0, 0 - 700, 0, 700, 700, 700)
76 t2m_set(base, 1, 0, 300, 0, 500, 500, 500)
77 t2m_set(base, 2, 0, K_MAGIC_1050, 0, 360, 360, 360)
78 t2m_set(base, 3, 0, K_MAGIC_1050, 360, 90, 80, 260)
79 t2m_conf(base, 4, 90); return 0
80 }
81 if id == 2 { // dumbbell: 2 weights + bar
82 t2m_set(base, 0, 0 - 800, 0, 0, 400, 400, 400)
83 t2m_set(base, 1, 800, 0, 0, 400, 400, 400)
84 t2m_set(base, 2, 0, 0, 0, 850, 140, 140)
85 t2m_conf(base, 3, 50); return 0
86 }
87 if id == 3 { // tree: trunk + 3 canopy blobs
88 t2m_set(base, 0, 0, 0 - 500, 0, 180, 700, 180)
89 t2m_set(base, 1, 0, 500, 0, 600, 520, 600)
90 t2m_set(base, 2, 0 - 320, 300, 180, 400, 400, 400)
91 t2m_set(base, 3, 320, 360, 0 - 160, 400, 400, 400)
92 t2m_conf(base, 4, 140); return 0
93 }
94 if id == 4 { // mushroom: stem + cap
95 t2m_set(base, 0, 0, 0 - 400, 0, 250, 520, 250)
96 t2m_set(base, 1, 0, 320, 0, 680, 250, 680)
97 t2m_conf(base, 2, 90); return 0
98 }
99 if id == 5 { // bottle: body + shoulder + neck
100 t2m_set(base, 0, 0, 0 - 350, 0, 430, 600, 430)
101 t2m_set(base, 1, 0, 350, 0, 300, 260, 300)
102 t2m_set(base, 2, 0, 780, 0, 150, 320, 150)
103 t2m_conf(base, 3, 70); return 0
104 }
105 if id == 6 { sdf_body(base); return 0 } // person -> the pioneer benchmark body
106 if id == 7 { // cactus: column + 2 arms
107 t2m_set(base, 0, 0, 0, 0, 300, 950, 300)
108 t2m_set(base, 1, 0 - 460, 250, 0, 190, 420, 190)
109 t2m_set(base, 2, 0 - 460, 650, 0, 190, 300, 190)
110 t2m_set(base, 3, 460, 120, 0, 190, 420, 190)
111 t2m_set(base, 4, 460, 520, 0, 190, 300, 190)
112 t2m_conf(base, 5, 55); return 0
113 }
114 if id == 8 { // capsule/pill: 3 fat spheres, wide blend
115 t2m_set(base, 0, 0, 0 - 450, 0, 380, 400, 380)
116 t2m_set(base, 1, 0, 0, 0, 380, 400, 380)
117 t2m_set(base, 2, 0, 450, 0, 380, 400, 380)
118 t2m_conf(base, 3, 220); return 0
119 }
120 t2m_set(base, 0, 0, 0, 0, 900, 900, 900); t2m_conf(base, 1, 120); return 0 // sphere
121}
122// convenience: prompt -> field
123func t2m_prompt(base: i64, prompt: *u8) -> i64 { return t2m_gen(base, t2m_id_of(prompt)) }