メニュー 閉じる

036. Processingで空間にドローイングしたイメージを3Dデータに書き出す

以前メイカーズバザール大阪で出展した際のコンテンツです。上の画像はマウスの軌跡上にチューブが描画されていく様子です。
このイメージをProcessing上からOBJ形式のファイルに書き出します。

import nervoussystem.obj.*;

PVector pos;

int cell_num;

int rot_mode;

float radius;

float rotx;
float roty;
float rotz;

float axisx;
float axisy;
float axisz;

boolean hand_r;
boolean hand_l;

boolean record;

boolean debug;

ArrayList<LineSystem> line_system;

void setup () {

	size (1920, 1080, P3D);
	colorMode (HSB, 100);
	background (0);

	line_system = new ArrayList<LineSystem> ();

	pos = new PVector ();

	cell_num = 100;

	radius = 10;

	rotx = 0.0;
	roty = 0.0;
	rotx = 0.0;

	rot_mode = 0;

	axisx = width / 2;
	axisy = height / 2;
	axisz = 0.0;

	record = false;

	debug = true;

	line_system.add (new LineSystem (pos));

}

void draw () {

	background (0);
	lights ();

	if (record == true) {
		OBJExport obj = (OBJExport) createGraphics (width, height, "nervoussystem.obj.OBJExport", "sample.obj");
		obj.setColor (true);
		obj.beginDraw ();
		line_system.get (0).update (pos);
		line_system.get (0).render (obj);
		line_system.get (0).numchk ();
		obj.endDraw ();
		obj.dispose ();
		record =  false;
	}

	translate (axisx, axisy, axisz);
	rotateX (rotx);
	rotateY (roty);
	rotateZ (rotz);

	pos.x = mouseX;
	pos.y = mouseY;

	line_system.get (0).create = true;
	line_system.get (0).update (pos);


	if (rot_mode == 0) {
		rotx += 0.06;
	}
	if (rot_mode == 1) {
		roty += 0.06;
	}
	rotz += 0.00;

	for (int i = 0; i < line_system.size (); i ++) {
		line_system.get (i).render (this.g);
		line_system.get (i).numchk ();
	}

	if (debug == true) {
		strokeWeight (2);
		stroke (0, 100, 100);
		line (-960, 0, 0, 960, 0, 0);
		stroke (50, 100, 100);
		line (0, -540, 0, 0, 540, 0);
	}

}

void keyPressed () {

	if (key == 'r') {
		record = true;
	}

	if (key == 'h') {
		roty = 0;
		rot_mode = 0;
	}

	if (key == 'v') {
		rotx = 0;
		rot_mode = 1;
	}

	if (key == 'c') {
		for (int i = 0; i < line_system.size (); i ++) {
			line_system.remove (0);
		}
		line_system.add (new LineSystem (pos));
	}

}

class LineSystem {

	ArrayList<LineCreate> line_create;

	PVector next_pts[];
	PVector prev_pts[];

	float tmpx;
	float tmpy;
	float tmpz;
	float targetx;
	float targety;
	float targetz;

	float mouse_nx;
	float mouse_ny;
	float mouse_px;
	float mouse_py;
	float mouse_ds;

	float angle;

	float easing;

	color col;

	boolean create;

	LineSystem (PVector mouse_pos) {

		line_create = new ArrayList<LineCreate> ();

		prev_pts = new PVector[cell_num + 1];

		for (int i = 0; i <= cell_num; i++) {
			prev_pts[i] = new PVector ();
		}

		angle = 0;

		for (int i = 0; i <= cell_num; i++) {
			tmpx = (mouse_pos.x - (width / 2)) + radius * cos (radians (angle));
			tmpy = (mouse_pos.y - (height / 2)) + radius * sin (radians (angle));
			prev_pts[i].x = tmpx * cos (roty);
			prev_pts[i].y = tmpy * cos (rotx);
			prev_pts[i].z = tmpx * cos ((PI / 2) - roty) - tmpy * cos ((PI / 2) - rotx);
			angle += 360.0 / cell_num;
		}

		col = color (random (100), 100, 100);

		line_create.add (new LineCreate (prev_pts, radius, col));

		easing = 0.1;

		create = true;

	}

	void update (PVector mouse_pos) {

		if (create == true) {
			mouse_nx += (mouse_pos.x - mouse_px) * easing;
			mouse_ny += (mouse_pos.y - mouse_py) * easing;
			mouse_ds = dist (mouse_nx, mouse_ny, mouse_px, mouse_py) + 4;
			angle = 0;
			next_pts = new PVector[cell_num + 1];
			for (int i = 0; i <= cell_num; i++) {
				next_pts[i] = new PVector ();
			}
			for (int i = 0; i <= cell_num; i++) {
				float x = prev_pts[i].x;
				float y = prev_pts[i].y;
				float z = prev_pts[i].z;
				tmpx = (mouse_pos.x - (width / 2)) + radius * cos (radians (angle));
				tmpy = (mouse_pos.y - (height / 2)) + radius * sin (radians (angle));
				targetx = tmpx * cos (roty);
				targety = tmpy * cos (rotx);
				targetz = tmpx * cos ((PI / 2) - roty) - tmpy * cos ((PI / 2) - rotx);
				x += (targetx - x) * easing;
				y += (targety - y) * easing;
				z += (targetz - z) * easing;
				next_pts[i].x = x;
				next_pts[i].y = y;
				next_pts[i].z = z;
				angle += 360.0 / cell_num;
			}
			radius = 200 / mouse_ds;
			col = color (random (100), 100, 100);
			line_create.add (new LineCreate (next_pts, radius, col));
			prev_pts = next_pts;
			mouse_px = mouse_nx;
			mouse_py = mouse_ny;
		}

	}

	void render (PGraphics pg) {

		for (int i = 0; i < line_create.size (); i++) {
			if (i > 0) {
				LineCreate line_prev = line_create.get (i - 1);
				LineCreate line_next = line_create.get (i);
				color c = line_next.col;
				pg.beginShape (QUAD_STRIP);
				pg.fill (c);
				pg.noStroke ();
				for (int j = 0; j <= cell_num; j++) {
					pg.vertex (line_prev.points[j].x, line_prev.points[j].y, line_prev.points[j].z);
					pg.vertex (line_next.points[j].x, line_next.points[j].y, line_next.points[j].z);
				}
				pg.endShape ();
			}
		}

	}

	void numchk () {

		if (line_create.size () > 1000) {
			line_create.remove (0);
		}

	}

}

class LineCreate {

	PVector points[];

	float radius;

	color col;

	LineCreate (PVector[] pts, float r, color c) {

		points = pts;

		radius = r;

		col = c;

	}

}

これで作られたOBJファイルを3Dプリンタで出力するためにSTLファイルに変換します。これはフリーのBlenderを使って変換します(変換だけに使っていますが、3Dソフトとしては凄まじく強力です)。

BlenderでSTL形式にエクスポートします。このSTLファイルをFlashForgeのFinderの標準スライスソフト「FlashPrint」で読み込みます。

あとはFinderでプリントするだけです。

Posted in processing