Where to Start? Generating Meshes from an Image

Hi everyone,
I took a look at the OF tutorials, and I’m trying to understand how to do this https://openframeworks.cc/ofBook/chapters/generativemesh.html
in Processing.
It’s not essential for this first step to make a 3D mesh, I just like the way that the image look like,
with this kind of “image processing”
here what I mean: https://openframeworks.cc/ofBook/images/generativemesh/images/StarLinesFirstMeshSmall.png

I suppose that I need to use the HE_Mesh library, or maybe, openGL/GLSL directly or maybe I just need to work with vertex/beginShape(LINES) etc…?

Where can I find the right mesh choice in HE_Mesh?
Where can I choose the primitive tipe ?

If you could guide me would be awesome.

I looked at the he_mesh examples, but there are too many irons in the fire.

thanks
R_Colors

2 Likes

Hi, that’s very interesting project!
Thank you for sharing!

This code work with lines, not the mesh
after following the tutorial, i got this

tried to convert it into processing.
except for the color

PImage image;
ArrayList<PVector> vertices = new ArrayList<PVector>();
void setup() {
  size(800, 800);
  background(0);
  noFill();
  stroke(255, 100, 0);
  
  image = loadImage("stars.png");
  //beginShape();
  float intensityThreshold = 255.0;
  int w = image.width;
  int h = image.height;
  for (int x=0; x<w; ++x) {
    for (int y=0; y<h; ++y) {
      color c = image.get(x, y);
      float intensity = brightness(c);
      if (intensity >= intensityThreshold) {
        vertices.add(new PVector(x, y));
      }
    }
  }
  //endShape();
  float num = 0;
  float connectionDistance = 15;
  int numVerts = vertices.size();
  stroke(255 ,100, 0, 50);
  println(numVerts * numVerts);
  for (int a=0; a<numVerts; ++a) {
    PVector verta = vertices.get(a);
    for (int b=a+1; b<numVerts; ++b) {
      PVector vertb = vertices.get(b);
      float distance = dist(verta.x, verta.y, vertb.x, vertb.y);//abs(verta.sub(vertb).mag());
      if (distance <= connectionDistance) {
        // In OF_PRIMITIVE_LINES, every pair of vertices or indices will be
        // connected to form a line
        line(verta.x, verta.y, vertb.x, vertb.y);
      }
    }
    num += numVerts - 1;
    //println((num / sq(numVerts) * 100) + "%");
  }
}

for the color, you need to research on how to draw gradient colored line

4 Likes

Really thank you!
looks super nice!

I added a simple function to make the background interpolated in radial way.and I’m working on
the code finded here to make gradient colored lines.
// grad lines https://forum.processing.org/two/discussion/5620/how-to-draw-a-gradient-colored-line

// computationally killer like...

void backgroundGradient(){
 
for(int y = 0; y < height; y++){
  for( int x = 0; x < width; x++){
    float distFromCent = dist(x,y, width/2, height/2);
  stroke(450-distFromCent,0,100);
 

  point(x,y);
  }
}  
}

I’m tring to adapt this code… extracting the colors from the pixel.arrays

float x1, y1, x2, y2;
color a, b;
 
void setup() {
  size(600, 600);
  noStroke();
  a = color(255, 0, 0);
  b = color(0, 255, 0);
  reset();
}
 
void draw() {
  background(0);
  gradientLine(x1, x2, y1, y2, a, b);
}
 
void mousePressed() {
  reset();
}
 
void gradientLine(float x1, float y1, float x2, float y2, color a, color b) {
  float deltaX = x2-x1;
  float deltaY = y2-y1;
  float tStep = 1.0/dist(x1, y1, x2, y2);
  for (float t = 0.0; t < 1.0; t += tStep) {
    fill(lerpColor(a, b, t));
    ellipse(x1+t*deltaX,  y1+t*deltaY, 3, 3);
  }
}
 
void reset() {
  x1 = random(width);
  y1 = random(height);
  x2 = random(width);
  y2 = random(height);
}

// grad lines https://forum.processing.org/two/discussion/5620/how-to-draw-a-gradient-colored-line
PImage image;
ArrayList<PVector> vertices = new ArrayList<PVector>();
void setup() {
  size(800, 800);
//background(0);
   backgroundGradient();

 // noFill();
  //stroke(255, 100, 0);
  int loc = 0;
  
  image = loadImage("stars.png");
  //beginShape();
  float intensityThreshold = 255.0;
  int w = image.width;
  int h = image.height;
  color c = color(0);
  color c1 = color(0);
 color c2 = color(0);
  for (int x=0; x<w; ++x) {
    for (int y=0; y<h; ++y) {
       c = image.get(x, y);
      float intensity = brightness(c);
      if (intensity >= intensityThreshold) {
        vertices.add(new PVector(x, y));
        
      }
    }
  }

  //endShape();
  
  //Color from image 
  // you can use  c = image.get(x, y); as well
  //  for (int x=0; x<w; ++x) {
  //  for (int y=0; y<h-1; ++y) {
  
  //     loc = x + y*image.width;
  //    // Color according to the image
  //    c1 = image.pixels[loc];
  //    c2 = image.pixels[loc+1];
      
  //  }
  //}
  //
  
  
  float num = 0;
  float connectionDistance = 15;
  int numVerts = vertices.size();
 // stroke(c);
 //  stroke(255 ,100, 0, 50);
  println(numVerts * numVerts);
  for (int a=0; a<numVerts; ++a) {
    PVector verta = vertices.get(a);
    for (int b=a+1; b<numVerts; ++b) {
      PVector vertb = vertices.get(b);
      float distance = dist(verta.x, verta.y, vertb.x, vertb.y);//abs(verta.sub(vertb).mag());
      if (distance <= connectionDistance) {
        // In OF_PRIMITIVE_LINES, every pair of vertices or indices will be
        // connected to form a line
        // fixed colors to debug it
         
        gradientLine(verta.x, verta.y, vertb.x, vertb.y,color(255, 0, 0,50),color(0, 255, 0,50));
      }
     
    }
    num += numVerts - 1;
    //println((num / sq(numVerts) * 100) + "%");
  }
  


}

void draw(){if(key == 's')saveFrame("a"+".png");}

void gradientLine(float x1, float y1, float x2, float y2, color a, color b) {
  float deltaX = x2-x1;
  float deltaY = y2-y1;
  float tStep = 1.0/dist(x1, y1, x2, y2);
  for (float t = 0.0; t < 1.0; t += tStep) {
    fill(lerpColor(a, b, t));
    ellipse(x1+t*deltaX,  y1+t*deltaY, 0.1, 0.1);
  }
}

void backgroundGradient(){
 
for(int y = 0; y < height; y++){
  for( int x = 0; x < width; x++){
    float distFromCent = dist(x,y, width/2, height/2);
  stroke(450-distFromCent,0,100);
 

  point(x,y);
  }
}  

}

with fixed gradientLine setted to get the color from the vertices.

PImage image;
ArrayList<PVector> vertices = new ArrayList<PVector>();
void setup() {
  size(800, 800);
 // background(126);
   backgroundGradient();
 
  int loc = 0;
 
  image = loadImage("stars.png");
  //beginShape();
  float intensityThreshold = 255.0;
  int w = image.width;
  int h = image.height;
  color c = color(0);
  for (int x=0; x<w; ++x) {
    for (int y=0; y<h; ++y) {
       c = image.get(x, y);
      float intensity = brightness(c);
      if (intensity >= intensityThreshold) {
        vertices.add(new PVector(x, y));
        
      }
    }
  }

  //endShape();
 
  float num = 0;
  float connectionDistance = 15;
  int numVerts = vertices.size();

  println(numVerts * numVerts);
  for (int a=0; a<numVerts; ++a) {
    PVector verta = vertices.get(a);
    for (int b=a+1; b<numVerts; ++b) {
      PVector vertb = vertices.get(b);
      float distance = dist(verta.x, verta.y, vertb.x, vertb.y);//abs(verta.sub(vertb).mag());
      if (distance <= connectionDistance) {
      // gradient line    
        gradientLine(verta.x, verta.y, vertb.x, vertb.y,image.get((int)verta.x, (int)verta.y),image.get((int)vertb.x, (int)vertb.y));
      }
     
    }
    num += numVerts - 1;
    //println((num / sq(numVerts) * 100) + "%");
  }
  


}

void draw(){}



void gradientLine(float x1, float y1, float x2, float y2, color a, color b) {
  float deltaX = x2-x1;
  float deltaY = y2-y1;
  float tStep = 1.0/dist(x1, y1, x2, y2);
   noStroke();
  for (float t = 0.0; t < 1.0; t += tStep) {
    fill(lerpColor(a, b, t));
    ellipse(x1+t*deltaX,  y1+t*deltaY, 1, 1);
  }
}

void backgroundGradient(){
for(int y = 0; y < height; y++){
  for( int x = 0; x < width; x++){
    float distFromCent = dist(x,y, width/2, height/2);
  stroke(300-distFromCent,300-distFromCent,300-distFromCent,200);
  point(x,y);
  }
}  
}

void keyPressed(){
 if(key == 's')saveFrame("a"+".png");
}
2 Likes

It would run faster if you use Quadtree for distance threshold checking. And then remove vertices that are not connected atleast to one other vertex.

1 Like

I’m looking at those links to try to understand what is this “mystic” quadtree :
Quadtree - Wikipedia // point QuadTree

// Recursion
Recursion is simply achieved by writing a function that calls itself one or more times.

// quad tree in processing
https://thecodingtrain.com/CodingChallenges/098.1-quadtree.html

thanks

2 Likes