shithub: 3dee

Download patch

ref: bd079fb59cff60792842d2726737002fabcc8951
parent: 677b3dca6496046d60e46bce7db0fe4b9dfb4ca3
author: rodri <rgl@antares-labs.eu>
date: Sat May 24 21:08:18 EDT 2025

new tool: tostl

--- a/mkfile
+++ b/mkfile
@@ -9,6 +9,7 @@
 	procgen\
 	obj\
 	stl\
+	tostl\
 
 OFILES=\
 	alloc.$O\
--- a/readme
+++ b/readme
@@ -16,6 +16,7 @@
 	- solar: a solar system planetarium (WIP)
 	- obj: an OBJ to model(6) conversion tool
 	- stl: an STL to model(6) conversion tool
+	- tostl: a model(6) to STL conversion tool
 
 USAGE
 
@@ -115,6 +116,15 @@
 
 	Just like with obj, by default it will try to compress the resulting
 	model by deduplicating entries, to disable this feature use -d.
+
+
+	tostl [-t] [file]
+
+	Converts a model(6) into an STL model and writes it to stdout.
+	If there are no arguments, it will read the model(6) from stdin.
+
+	Use the t option to write an ASCII STL file, otherwise a
+	binary one will be written.
 
 CUBEMAPS
 
--- /dev/null
+++ b/tostl.c
@@ -1,0 +1,93 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <memdraw.h>
+#include <geometry.h>
+#include "libgraphics/graphics.h"
+#include "fns.h"
+#include "libstl/stl.h"
+
+static int
+loadstlmodel(Stl *stl, Model *m)
+{
+	Primitive *p;
+	Stltri **tri, *t;
+	int i;
+
+	snprint((char*)stl->hdr, sizeof(stl->hdr), "Exported with libstl from ⑨");
+
+	/* XXX we assume all prims are triangles */
+	stl->ntris = m->nprims;
+	stl->tris = emalloc(stl->ntris*sizeof(Stltri*));
+
+	/* since we don't use attributes we can allocate tris in bulk */
+	t = emalloc(stl->ntris*sizeof(Stltri));
+	memset(t, 0, stl->ntris*sizeof(Stltri));
+	for(tri = stl->tris; tri < stl->tris+stl->ntris; tri++)
+		*tri = &t[tri - stl->tris];
+
+	tri = stl->tris;
+	for(p = m->prims; p < m->prims+m->nprims; p++){
+		if(p->type != PTriangle){
+			stl->ntris--;
+			continue;
+		}
+
+		(*tri)->n[0] = p->v[0].n.x;
+		(*tri)->n[1] = p->v[0].n.y;
+		(*tri)->n[2] = p->v[0].n.z;
+
+		for(i = 0; i < 3; i++){
+			(*tri)->v[i][0] = p->v[i].p.x;
+			(*tri)->v[i][1] = p->v[i].p.y;
+			(*tri)->v[i][2] = p->v[i].p.z;
+		}
+		tri++;
+	}
+
+	return stl->ntris;
+}
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-t] [mdlfile]\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	Model *m;
+	Stl *stl;
+	char *infile;
+	int fd, ofmt;
+
+	ofmt = STLBINARY;
+	infile = "/fd/0";
+	ARGBEGIN{
+	case 't': ofmt = STLTEXT; break;
+	default: usage();
+	}ARGEND;
+	if(argc == 1)
+		infile = argv[0];
+	else if(argc > 1)
+		usage();
+
+	fd = open(infile, OREAD);
+	if(fd < 0)
+		sysfatal("open: %r");
+
+	m = readmodel(fd);
+	if(m == nil)
+		sysfatal("readmodel: %r");
+
+	stl = emalloc(sizeof(Stl));
+	loadstlmodel(stl, m);
+
+	if(writestl(1, stl, ofmt) == 0)
+		sysfatal("writestl: %r");
+
+	exits(nil);
+}
--