Files
armorpaint/paint/assets/plugins/import_stl.c
T
2026-03-23 23:20:02 +01:00

86 lines
3.0 KiB
C

#include "global.h"
void *plugin;
void *import_stl(char *path) {
buffer_t *b = data_get_blob(path);
int pos = 80; // skip header
int faces = buffer_get_i32(b, pos);
pos += 4;
f32_array_t *pos_temp = f32_array_create(faces * 9);
f32_array_t *nor_temp = f32_array_create(faces * 3);
for (int i = 0; i < faces; ++i) {
int i3 = i * 3;
nor_temp->buffer[i3 ] = buffer_get_f32(b, pos); pos += 4;
nor_temp->buffer[i3 + 1] = buffer_get_f32(b, pos); pos += 4;
nor_temp->buffer[i3 + 2] = buffer_get_f32(b, pos); pos += 4;
int i9 = i * 9;
pos_temp->buffer[i9 ] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 1] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 2] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 3] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 4] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 5] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 6] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 7] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 8] = buffer_get_f32(b, pos); pos += 4;
pos += 2; // skip attribute
}
float scale_pos = 0.0;
for (int i = 0; i < pos_temp->length; ++i) {
float f = pos_temp->buffer[i];
if (f < 0.0) f = -f;
if (scale_pos < f) scale_pos = f;
}
float inv = 32767.0 * (1.0 / scale_pos);
int verts = faces * 3;
i16_array_t *posa = i16_array_create(verts * 4);
i16_array_t *nora = i16_array_create(verts * 2);
u32_array_t *inda = u32_array_create(verts);
for (int i = 0; i < verts; ++i) {
int f = (i / 3) * 3; // face normal base index
// posa->buffer[i * 4 ] = (int)( pos_temp->buffer[i * 3 ] * inv);
// posa->buffer[i * 4 + 1] = (int)(-pos_temp->buffer[i * 3 + 2] * inv);
// posa->buffer[i * 4 + 2] = (int)( pos_temp->buffer[i * 3 + 1] * inv);
// nora->buffer[i * 2 ] = (int)( nor_temp->buffer[f ] * 32767.0);
// nora->buffer[i * 2 + 1] = (int)(-nor_temp->buffer[f + 2] * 32767.0);
// posa->buffer[i * 4 + 3] = (int)( nor_temp->buffer[f + 1] * 32767.0);
buffer_set_i16(posa, (i * 4) * 2, pos_temp->buffer[i * 3 ] * inv);
buffer_set_i16(posa, (i * 4 + 1) * 2, -pos_temp->buffer[i * 3 + 2] * inv);
buffer_set_i16(posa, (i * 4 + 2) * 2, pos_temp->buffer[i * 3 + 1] * inv);
buffer_set_i16(nora, (i * 2) * 2, nor_temp->buffer[f ] * 32767.0);
buffer_set_i16(nora, (i * 2 + 1) * 2, -nor_temp->buffer[f + 2] * 32767.0);
buffer_set_i16(posa, (i * 4 + 3) * 2, nor_temp->buffer[f + 1] * 32767.0);
inda->buffer[i] = i;
}
data_delete_blob(path);
string_array_t *a = string_split(path, "\\\\");
char *s = array_pop(a);
a = string_split(s, "/");
s = array_pop(a);
a = string_split(s, ".");
char *name = a->buffer[0];
return plugin_make_raw_mesh(name, posa, nora, inda, scale_pos);
}
void on_delete() {
plugin_unregister_mesh("stl");
}
void main() {
plugin = plugin_create();
gc_root(plugin);
plugin_notify_on_delete(plugin, on_delete);
plugin_register_mesh("stl", import_stl);
}