kopia lustrzana https://github.com/fellesverkstedet/fabmodules
466 wiersze
14 KiB
Python
Executable File
466 wiersze
14 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# math_stl
|
|
# compile and evaluate .math to STL
|
|
#
|
|
# todo
|
|
# run-length code
|
|
# prune triangulation
|
|
#
|
|
# Neil Gershenfeld
|
|
# CBA MIT 10/29/11
|
|
#
|
|
# (c) Massachusetts Institute of Technology 2011
|
|
# Permission granted for experimental and personal use;
|
|
# license for commercial sale available from MIT.
|
|
#
|
|
#
|
|
|
|
import sys
|
|
import string
|
|
import Image
|
|
import os
|
|
from numpy import *
|
|
|
|
#
|
|
# command line args
|
|
#
|
|
|
|
if (not((len(sys.argv) == 3) | (len(sys.argv) == 4))):
|
|
print "command line: math_stl in.math out.stl [resolution]"
|
|
print " in.math = input math string file"
|
|
print " out.stl = output STL image"
|
|
print " resolution = pixels per mm (optional, default 1)"
|
|
sys.exit()
|
|
|
|
resolution = "1"
|
|
if (len(sys.argv) == 4):
|
|
resolution = sys.argv[3]
|
|
|
|
#
|
|
# read .math file
|
|
#
|
|
|
|
input_file_name = sys.argv[1]
|
|
output_file_name = sys.argv[2]
|
|
input_file = open(input_file_name,'r')
|
|
(file_type,) = string.split(input_file.readline())
|
|
(units,) = string.split(input_file.readline())
|
|
units = float(units)
|
|
(dx,dy,dz) = string.split(input_file.readline())
|
|
(xmin,ymin,zmin) = string.split(input_file.readline())
|
|
math_string = input_file.readline()
|
|
input_file.close()
|
|
print "read "+input_file_name
|
|
print " math string type: "+file_type
|
|
print " ",units,"mm per unit"
|
|
print " dx: "+dx+", dy: "+dy+", dz: "+dz
|
|
print " xmin: "+xmin+", ymin: "+ymin+", zmin: "+zmin
|
|
|
|
#
|
|
# write evaluation program
|
|
#
|
|
|
|
program = """//
|
|
// math_stl_eval.c
|
|
// math string to STL evaluation generated by math_stl
|
|
//
|
|
// Neil Gershenfeld
|
|
// CBA MIT 10/29/11
|
|
//
|
|
// (c) Massachusetts Institute of Technology 2011
|
|
// Permission granted for experimental and personal use;
|
|
// license for commercial sale available from MIT.
|
|
//
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <png.h>
|
|
|
|
//
|
|
// data structures
|
|
//
|
|
|
|
struct fab_vars {
|
|
unsigned char empty;
|
|
unsigned char interior;
|
|
unsigned char edge;
|
|
unsigned char north;
|
|
unsigned char south;
|
|
unsigned char east;
|
|
unsigned char west;
|
|
unsigned char stop;
|
|
unsigned char corner;
|
|
unsigned char corner2;
|
|
unsigned char direction;
|
|
unsigned int nx,ny,nz;
|
|
unsigned int bit_depth;
|
|
unsigned int word_size;
|
|
double dx,dy,dz;
|
|
double xmin,ymin,zmin;
|
|
unsigned char **array;
|
|
uint32_t **rgb0,**rgb1;
|
|
short int **xptr, **yptr;
|
|
struct fab_path_type *path;
|
|
struct fab_mesh_type *mesh;
|
|
png_bytep *row_pointers;
|
|
png_structp png_ptr;
|
|
png_infop info_ptr;
|
|
};
|
|
|
|
struct fab_vars init_vars() {
|
|
//
|
|
// fab_vars constructor
|
|
//
|
|
struct fab_vars v;
|
|
//
|
|
v.empty = 0;
|
|
v.interior = 1;
|
|
v.edge = (1 << 1);
|
|
v.north = (1 << 2);
|
|
v.west = (2 << 2);
|
|
v.east = (3 << 2);
|
|
v.south = (4 << 2);
|
|
v.stop = (5 << 2);
|
|
v.corner = (6 << 2);
|
|
v.corner2 = (7 << 2);
|
|
v.direction = (7 << 2);
|
|
//
|
|
return v;
|
|
}
|
|
|
|
main(int argc, char **argv) {
|
|
//
|
|
// local vars
|
|
//
|
|
struct fab_vars v = init_vars(&v);
|
|
double units = 25.4;
|
|
double X,Y,Z;
|
|
double dx,dy,dz;
|
|
v.dx = units*"""+dx+""";
|
|
v.dy = units*"""+dy+""";
|
|
v.dz = units*"""+dz+""";
|
|
v.xmin = units*"""+xmin+""";
|
|
v.ymin = units*"""+ymin+""";
|
|
v.zmin = units*"""+zmin+""";
|
|
double resolution="""+resolution+""";
|
|
v.nx = resolution*v.dx;
|
|
v.ny = resolution*v.dy;
|
|
v.nz = resolution*v.dz;
|
|
int x,y,z;
|
|
uint32_t val;
|
|
//
|
|
// create RGB arrays
|
|
//
|
|
v.rgb0 = malloc(v.ny*sizeof(uint32_t *));
|
|
for (y = 0; y < v.ny; ++y)
|
|
v.rgb0[y] = (uint32_t*) malloc(v.nx*sizeof(uint32_t));
|
|
v.rgb1 = malloc(v.ny*sizeof(uint32_t *));
|
|
for (y = 0; y < v.ny; ++y)
|
|
v.rgb1[y] = (uint32_t*) malloc(v.nx*sizeof(uint32_t));
|
|
//
|
|
// create triangle array
|
|
//
|
|
uint32_t triangle_count=0;
|
|
struct triangle_type {
|
|
int v0x,v0y,v0z;
|
|
int v1x,v1y,v1z;
|
|
int v2x,v2y,v2z;
|
|
struct triangle_type *next;
|
|
};
|
|
struct triangle_type *t,*tstart,*tnew;
|
|
t = malloc(sizeof(struct triangle_type));
|
|
tstart = t;
|
|
//
|
|
// loop over layers
|
|
//
|
|
for (z = 0; z < v.nz; ++z) {
|
|
Z = (v.zmin + v.dz*z/(v.nz-1.0))/units;
|
|
printf(" Z = %f\\n",Z);
|
|
//
|
|
// evaluate new layer
|
|
//
|
|
for (y = 0; y < v.ny; ++y) {
|
|
Y = (v.ymin + v.dy*(v.ny-y-1)/(v.ny-1.0))/units;
|
|
for (x = 0; x < v.nx; ++x) {
|
|
X = (v.xmin + v.dx*x/(v.nx-1.0))/units;
|
|
v.rgb0[y][x] = v.rgb1[y][x];
|
|
v.rgb1[y][x] = """+math_string+""";
|
|
}
|
|
}
|
|
//
|
|
// check voxel faces
|
|
//
|
|
for (y = 0; y < (v.ny-1); ++y) {
|
|
for (x = 0; x < (v.nx-1); ++x) {
|
|
//
|
|
// left
|
|
//
|
|
if ((v.rgb0[y][x] != 0) && (v.rgb0[y+1][x] != 0) && (v.rgb1[y][x] != 0) && (v.rgb1[y+1][x] != 0)) {
|
|
if ((v.rgb0[y][x+1] == 0) || (v.rgb0[y+1][x+1] == 0) || (v.rgb1[y][x+1] == 0) || (v.rgb1[y+1][x+1] == 0)) {
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x;
|
|
(*t).v1y = y;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
}
|
|
}
|
|
//
|
|
// right
|
|
//
|
|
if ((v.rgb0[y][x+1] != 0) && (v.rgb0[y+1][x+1] != 0) && (v.rgb1[y][x+1] != 0) && (v.rgb1[y+1][x+1] != 0)) {
|
|
if ((v.rgb0[y][x] == 0) || (v.rgb0[y+1][x] == 0) || (v.rgb1[y][x] == 0) || (v.rgb1[y+1][x] == 0)) {
|
|
triangle_count += 1;
|
|
(*t).v0x = x+1;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
triangle_count += 1;
|
|
(*t).v0x = x+1;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
}
|
|
}
|
|
//
|
|
// front
|
|
//
|
|
if ((v.rgb0[y][x] != 0) && (v.rgb0[y][x+1] != 0) && (v.rgb1[y][x] != 0) && (v.rgb1[y][x+1] != 0)) {
|
|
if ((v.rgb0[y+1][x] == 0) || (v.rgb0[y+1][x+1] == 0) || (v.rgb1[y+1][x] == 0) || (v.rgb1[y+1][x+1] == 0)) {
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y;
|
|
(*t).v1z = z;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x;
|
|
(*t).v2y = y;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
}
|
|
}
|
|
//
|
|
// back
|
|
//
|
|
if ((v.rgb0[y+1][x] != 0) && (v.rgb0[y+1][x+1] != 0) && (v.rgb1[y+1][x] != 0) && (v.rgb1[y+1][x+1] != 0)) {
|
|
if ((v.rgb0[y][x] == 0) || (v.rgb0[y][x+1] == 0) || (v.rgb1[y][x] == 0) || (v.rgb1[y][x+1] == 0)) {
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y+1;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y+1;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
}
|
|
}
|
|
//
|
|
// top
|
|
//
|
|
if ((v.rgb0[y][x] != 0) && (v.rgb0[y][x+1] != 0) && (v.rgb0[y+1][x] != 0) && (v.rgb0[y+1][x+1] != 0)) {
|
|
if ((v.rgb1[y][x] == 0) || (v.rgb1[y][x+1] == 0) || (v.rgb1[y+1][x] == 0) || (v.rgb1[y+1][x+1] == 0)) {
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z;
|
|
(*t).v2x = x;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y;
|
|
(*t).v1z = z;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
}
|
|
}
|
|
//
|
|
// bottom
|
|
//
|
|
if ((v.rgb1[y][x] != 0) && (v.rgb1[y][x+1] != 0) && (v.rgb1[y+1][x] != 0) && (v.rgb1[y+1][x+1] != 0)) {
|
|
if ((v.rgb0[y][x] == 0) || (v.rgb0[y][x+1] == 0) || (v.rgb0[y+1][x] == 0) || (v.rgb0[y+1][x+1] == 0)) {
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z+1;
|
|
(*t).v1x = x+1;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
triangle_count += 1;
|
|
(*t).v0x = x;
|
|
(*t).v0y = y;
|
|
(*t).v0z = z+1;
|
|
(*t).v1x = x;
|
|
(*t).v1y = y+1;
|
|
(*t).v1z = z+1;
|
|
(*t).v2x = x+1;
|
|
(*t).v2y = y+1;
|
|
(*t).v2z = z+1;
|
|
tnew = malloc(sizeof(struct triangle_type));
|
|
(*t).next = tnew;
|
|
t = tnew;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// write STL
|
|
//
|
|
char header[80];
|
|
uint16_t attribute;
|
|
int i;
|
|
t = tstart;
|
|
float v0x,v0y,v0z;
|
|
float v1x,v1y,v1z;
|
|
float v2x,v2y,v2z;
|
|
FILE *output_file;
|
|
output_file = fopen(\""""+output_file_name+"""\","wb");
|
|
fwrite(header,1,80,output_file);
|
|
fwrite(&triangle_count,4,1,output_file);
|
|
float zero = 0;
|
|
for (i = 0; i < triangle_count; ++i) {
|
|
fwrite(&zero,4,1,output_file);
|
|
fwrite(&zero,4,1,output_file);
|
|
fwrite(&zero,4,1,output_file);
|
|
v0x = (v.xmin + v.dx*((*t).v0x)/(v.nx-1.0))/units;
|
|
fwrite(&v0x,4,1,output_file);
|
|
v0y = (v.ymin + v.dy*((*t).v0y)/(v.ny-1.0))/units;
|
|
fwrite(&v0y,4,1,output_file);
|
|
v0z = (v.zmin + v.dz*((*t).v0z)/(v.nz-1.0))/units;
|
|
fwrite(&v0z,4,1,output_file);
|
|
v1x = (v.xmin + v.dx*((*t).v1x)/(v.nx-1.0))/units;
|
|
fwrite(&v1x,4,1,output_file);
|
|
v1y = (v.ymin + v.dy*((*t).v1y)/(v.ny-1.0))/units;
|
|
fwrite(&v1y,4,1,output_file);
|
|
v1z = (v.zmin + v.dz*((*t).v1z)/(v.nz-1.0))/units;
|
|
fwrite(&v1z,4,1,output_file);
|
|
v2x = (v.xmin + v.dx*((*t).v2x)/(v.nx-1.0))/units;
|
|
fwrite(&v2x,4,1,output_file);
|
|
v2y = (v.ymin + v.dy*((*t).v2y)/(v.ny-1.0))/units;
|
|
fwrite(&v2y,4,1,output_file);
|
|
v2z = (v.zmin + v.dz*((*t).v2z)/(v.nz-1.0))/units;
|
|
fwrite(&v2z,4,1,output_file);
|
|
fwrite(&attribute,2,1,output_file);
|
|
t = (*t).next;
|
|
}
|
|
fclose(output_file);
|
|
}
|
|
"""
|
|
|
|
eval_file = open("math_stl_eval.c",'w')
|
|
eval_file.write(program)
|
|
eval_file.close()
|
|
|
|
#
|
|
# compile
|
|
#
|
|
|
|
print "compile"
|
|
if os.uname()[0] == 'Darwin':
|
|
os.system("gcc -O math_stl_eval.c -o math_stl_eval -lm -I/usr/X11/include -L/usr/X11/lib -lpng")
|
|
else:
|
|
os.system("gcc -O math_stl_eval.c -o math_stl_eval -lm -lpng")
|
|
|
|
|
|
#
|
|
# execute
|
|
#
|
|
|
|
print "execute"
|
|
os.system("./math_stl_eval")
|
|
os.system("rm ./math_stl_eval.c")
|
|
os.system("rm ./math_stl_eval")
|