Thursday, March 27, 2025

310 Experimental FDM: This shouldn't be possible

And yet...
So -
Single curve vertical toolpath extrusion is already impossible.
But then they successfully connected.
Without any infill or supports.







Transductive Loop Success! Maybe!

 
Success! Maybe!
 
Through a truly atrocious amount of alpha's and betas and tests and testing and troubleshooting and ripping out the entire codebase and starting over innumerable times - and the version before this was, annoyingly enough, TOO perfect.
 
So this version I'm doing something a little different - at each iterative step I'm keeping everythinglessless - except for *one* thing. No idea how well this'll work, but I think not just adding but putting some restraints on the data moshing aspect of this makes it more intersting than a perfectly stale loop. Let's make this mean something.



 

Tuesday, March 25, 2025

I, Object! OBDF show March 25 2025

 Great OBDF department show at AUArts last night!


Lots I could write about but I especially loved this celestial clock a student made, a steel ball bearing endlessly rotating about its equater, powered by what I presume to be a magnet on the inside of the device, invisible rolling it around and around as if it were a second-hand on a clock. Very creative, and a cool hidden-mechanism idea I'd love to incorporate into future projects.

 

 
 

 
And there was plenty more to see, so here's a few photos I took along the way:












    
And of course, I was there too:



 


Thursday, March 20, 2025

.png -> .bin -> wav -> obj

 


Transductive loop alpha

 Lotta problems, still working through it, gotta separate these and more fully implement and test each stage:




/*

 * Stage 1: Image (.png) → Raw Binary Data (.bin)

 *

 * Converts the image pixel data into raw binary and saves as a .bin file.

 */


PImage img;

String binaryFile = "output-1.bin";


void setup() {

  size(512, 512);

  img = loadImage("input.png");

  img.resize(width, height);

 

  byte[] bytes = new byte[img.pixels.length * 4];

  img.loadPixels();


  for (int i = 0; i < img.pixels.length; i++) {

color c = img.pixels[i];

bytes[i * 4] = (byte) red(c);

bytes[i * 4 + 1] = (byte) green(c);

bytes[i * 4 + 2] = (byte) blue(c);

bytes[i * 4 + 3] = (byte) alpha(c);

  }

 

  saveBytes(binaryFile, bytes);

  println("Stage 1 complete: "+binaryFile);

  exit();

}


/*

 * Stage 2: Binary Data (.bin) → Soundwave (.wav)

 *

 * Interprets binary data as waveform amplitude values and generates a .wav file.

 */


import processing.sound.*;


String binaryInput = "output-1.bin";

String wavFile = "output-2.wav";


void setup() {

  byte[] data = loadBytes(binaryInput);

  AudioSample sample = new AudioSample(this, data.length, 44100);

 

  for (int i = 0; i < data.length; i++) {

sample.write(i, (data[i] / 128.0) - 1.0);

  }

 

  sample.save(wavFile);

  println("Stage 2 complete: "+wavFile);

  exit();

}


/*

 * Stage 3: Soundwave (.wav) → 3D Mesh (.obj)

 *

 * Uses waveform amplitude data to generate a 3D mesh and saves it as .obj.

 */


import peasy.*;

import wblut.hemesh.*;


String wavInput = "output-2.wav";

String objFile = "output-3.obj";


void setup() {

  float[] waveform = loadSoundWave(wavInput);

  HE_Mesh mesh = new HE_Mesh(new HEC_Grid().setU(100).setV(100).setUSize(200).setVSize(200));

 

  for (int i = 0; i < waveform.length; i++) {

mesh.getVertex(i).setZ(waveform[i] * 50);

  }

 

  HET_Export.saveToOBJ(mesh, objFile);

  println("Stage 3 complete: "+objFile);

  exit();

}


/*

 * Stage 4: 3D Mesh (.obj) → Vector Drawing (.svg)

 *

 * Flattens the 3D mesh into 2D and saves it as an .svg file.

 */


import processing.svg.*;


String objInput = "output-3.obj";

String svgFile = "output-4.svg";


void setup() {

  PShape mesh2D = loadShape(objInput);

  size(800, 800);

  beginRecord(SVG, svgFile);

  shape(mesh2D, 0, 0, width, height);

  endRecord();

 

  println("Stage 4 complete: "+svgFile);

  exit();

}


/*

 * Stage 5: Vector Drawing (.svg) → Plaintext Coordinates (.txt)

 *

 * Extracts x, y coordinates from the .svg and saves them as a .txt file.

 */


String svgInput = "output-4.svg";

String txtFile = "output-5.txt";


void setup() {

  PShape svg = loadShape(svgInput);

  String coords = "";


  for (int i = 0; i < svg.getChildCount(); i++) {

PShape child = svg.getChild(i);

for (int j = 0; j < child.getVertexCount(); j++) {

   float x = child.getVertexX(j);

   float y = child.getVertexY(j);

   coords += x + "," + y + "\n";

}

  }

 

  saveStrings(txtFile, split(coords, "\n"));

  println("Stage 5 complete: "+txtFile);

  exit();

}


/*

 * Stage 6: Plaintext Coordinates (.txt) → Color Palette (.aco)

 *

 * Converts x, y coordinates into RGB color values and saves as an .aco color palette file.

 */


String txtInput = "output-5.txt";

String acoFile = "output-6.aco";


void setup() {

  String[] coords = loadStrings(txtInput);

  color[] palette = new color[coords.length];


  for (int i = 0; i < coords.length; i++) {

String[] parts = split(coords[i], ",");

float x = float(parts[0]) % 255;

float y = float(parts[1]) % 255;

palette[i] = color(x, y, (x + y) % 255);

  }


  saveACO(acoFile, palette);

  println("Stage 6 complete: "+acoFile);

  exit();

}


/*

 * Stage 7: Color Palette (.aco) → Encoded Image (.tiff)

 *

 * Uses the color palette to create a new image and saves it as a .tiff file.

 */


String acoInput = "output-6.aco";

String tiffFile = "output-7.tiff";


void setup() {

  color[] palette = loadACO(acoInput);

  PImage img = createImage(512, 512, RGB);


  img.loadPixels();

  for (int i = 0; i < img.pixels.length; i++) {

img.pixels[i] = palette[i % palette.length];

  }

  img.updatePixels();


  img.save(tiffFile);

  println("Stage 7 complete: "+tiffFile);

  exit();

}


/*

 * Stage 8: Encoded Image (.tiff) → Raw Hex Data (.hex)

 *

 * Converts image pixel data into raw hexadecimal values.

 */


String tiffInput = "output-7.tiff";

String hexFile = "output-8.hex";


void setup() {

  PImage img = loadImage(tiffInput);

  img.loadPixels();


  String hexData = "";

  for (int i = 0; i < img.pixels.length; i++) {

hexData += hex(img.pixels[i], 6) + "\n";

  }


  saveStrings(hexFile, split(hexData, "\n"));

  println("Stage 8 complete: "+hexFile);

  exit();

}


/*

 * Stage 9: Raw Hex Data (.hex) → Glitched Audio (.wav)

 *

 * Uses the hex data as raw audio waveform values.

 */


String hexInput = "output-8.hex";

String glitchWav = "output-9.wav";


void setup() {

  String[] hexData = loadStrings(hexInput);

  AudioSample sample = new AudioSample(this, hexData.length, 44100);


  for (int i = 0; i < hexData.length; i++) {

float val = unhex(hexData[i]) / 255.0 * 2.0 - 1.0;

sample.write(i, val);

  }


  sample.save(glitchWav);

  println("Stage 9 complete: "+glitchWav);

  exit();

}


/*

 * Stage 10: Glitched Audio (.wav) → Reconstructed Image (.png)

 *

 * Interprets audio data as pixel values and reconstructs a new image.

 */


String wavInput = "output-9.wav";

String finalPng = "output-10.png";


void setup() {

  float[] audioData = loadSoundWave(wavInput);

  PImage img = createImage(512, 512, RGB);


  img.loadPixels();

  for (int i = 0; i < img.pixels.length; i++) {

float val = audioData[i % audioData.length] * 255.0;

img.pixels[i] = color(val);

  }

  img.updatePixels();


  img.save(finalPng);

  println("Stage 10 complete: "+finalPng);

  exit();

}





Current obsession

 Singularly combining photography, traditional cyanotype printing processes, 3d printing, and digital maniuplation - to create singlular obj...