#include "STLTextWriter.h" #include "time.h" // I did not write this Image-reading library. You can find the original author at the following link. // https://github.com/nothings/stb/blob/master/stb_image.h #define STB_IMAGE_IMPLEMENTATION //#define STBI_MALLOC //#define STBI_REALLOC //#define STBI_FREE #include "stb_image.h" // minimum value function for integers int imin(int num1, int num2){ if(num1 < num2){ return num1; } else{ return num2; } } // minimum value function for doubles double dmin(double num1, double num2){ if(num1 <= num2){ return num1; } else{ return num2; } } // minimum value function for doubles double dmax(double num1, double num2){ if(num1 >= num2){ return num1; } else{ return num2; } } // makes an array index wrap to the other end if it does out of bounds int indmod(int index, int size){ // index modulus index %= size; if(index < 0){ index += size; } return index; } // does literally everything else int main(int argc, char *argv[]){ double point1[3] = {0,0,0}; double point2[3] = {0,0,0}; double point3[3] = {0,0,0}; double point4[3] = {0,0,0}; int hmheight = 0; int hmwidth = 0; int n = 0; double const dpi = 1.0/8; char filepath[300]; char modelpath[300]; int extlen = 0; char newext[] = "stl"; srand(time(NULL)); printf("\n\n"); //check for filename if(argc < 2){ printf("Enter file path/name: "); scanf("%300s",&filepath); } else{ strcpy(filepath, argv[1]); } // populate heightmap unsigned char *data = stbi_load(filepath, &hmwidth, &hmheight, &n, 0); if(data == NULL){ printf("data = NULL\n\n"); exit(1); } double* heightmap; heightmap = (double*)malloc(hmheight * hmwidth * sizeof(double)); if(heightmap == NULL){ printf("Memory for heightmap could not be allocated.\n\n"); exit(1); } for(int i = 0; i < hmwidth; i++){ for(int j = 0; j < hmheight; j++){ heightmap[i*hmheight+j] = 0.5f; } } for(int i = 0; i < hmwidth; i++){ for(int j = 0; j < hmheight; j++){ for(int k = 0; k < n; k++){ heightmap[i*hmheight+j] += *(data+i*hmheight*n+j*n) / (127.0f*n); } heightmap[i*hmheight+j] = dmax(heightmap[i*hmheight+j], 0.1f); } } stbi_image_free(data); printf("STATUS___Read data into heightmap\n"); // bustin' out the spreadsheet again // Uncomment the code below to get a .csv spreadsheet of the heightmap /* FILE *dumpfile; dumpfile = fopen("heightmap.csv", "w"); for(int i = 0; i < hmheight*hmwidth; i++){ fprintf(dumpfile, "%f,", heightmap[i]); if(i % hmwidth == 0){ fprintf(dumpfile, "\n"); } } fclose(dumpfile); */ // get model file name for(int i = strlen(filepath)-1; i >= 0; i--){ if(filepath[i] == '.'){ extlen = i; filepath[i+1] = '\0'; break; } if(i == 0){ printf("Could not recognize file path/name\n\n"); exit(1); } } strcpy(modelpath, filepath); strcat(modelpath, newext); // writing to file FILE *modelfile; modelfile = fopen(modelpath, "w"); startSTL(modelfile); // drawing the top of the mesh for(int i = 0; i < hmwidth-1; i++){ // i is the distance from the left edge for(int j = 0; j < hmheight-1; j++){ // j is the distance from the bottom edge point1[0] = i*dpi; point1[1] = j*dpi; point1[2] = heightmap[i+((hmheight-1-j)*hmwidth)]; point2[0] = (i+1)*dpi; point2[1] = j*dpi; point2[2] = heightmap[(i+1)+((hmheight-1-j)*hmwidth)]; point3[0] = i*dpi; point3[1] = (j+1)*dpi; point3[2] = heightmap[i+((hmheight-2-j)*hmwidth)]; point4[0] = (i+1)*dpi; point4[1] = (j+1)*dpi; point4[2] = heightmap[(i+1)+((hmheight-2-j)*hmwidth)]; drawTriangle(modelfile, point1, point2, point4); drawTriangle(modelfile, point1, point4, point3); } } printf("STATUS___Drew top of mesh\n"); //drawing the sides of the mesh for(int i = 0; i < hmwidth-1; i++){ // Front edge point1[0] = i*dpi; point1[1] = 0; point1[2] = 0; point2[0] = i*dpi; point2[1] = 0; point2[2] = heightmap[i+(hmwidth*(hmheight-1))]; point3[0] = (i+1)*dpi; point3[1] = 0; point3[2] = 0; point4[0] = (i+1)*dpi; point4[1] = 0; point4[2] = heightmap[i+1+(hmwidth*(hmheight-1))]; drawTriangle(modelfile, point1, point4, point2); drawTriangle(modelfile, point1, point3, point4); // Back edge point1[0] = i*dpi; point1[1] = (hmheight-1)*dpi; point1[2] = 0; point2[0] = i*dpi; point2[1] = (hmheight-1)*dpi; point2[2] = heightmap[i]; point3[0] = (i+1)*dpi; point3[1] = (hmheight-1)*dpi; point3[2] = 0; point4[0] = (i+1)*dpi; point4[1] = (hmheight-1)*dpi; point4[2] = heightmap[i+1]; drawTriangle(modelfile, point1, point2, point4); drawTriangle(modelfile, point1, point4, point3); } printf("STATUS___Drew front and back of mesh\n"); for(int j = 0; j < hmheight-1; j++){ // Left edge point1[0] = 0; point1[1] = (hmheight-j-1)*dpi; point1[2] = 0; point2[0] = 0; point2[1] = (hmheight-j-1)*dpi; point2[2] = heightmap[j*hmwidth]; point3[0] = 0; point3[1] = (hmheight-j-2)*dpi; point3[2] = 0; point4[0] = 0; point4[1] = (hmheight-j-2)*dpi; point4[2] = heightmap[(j+1)*hmwidth]; drawTriangle(modelfile, point1, point4, point2); drawTriangle(modelfile, point1, point3, point4); // Right edge point1[0] = (hmwidth-1)*dpi; point1[1] = (hmheight-j-1)*dpi; point1[2] = 0; point2[0] = (hmwidth-1)*dpi; point2[1] = (hmheight-j-1)*dpi; point2[2] = heightmap[(j*hmwidth)+hmwidth-1]; point3[0] = (hmwidth-1)*dpi; point3[1] = (hmheight-j-2)*dpi; point3[2] = 0; point4[0] = (hmwidth-1)*dpi; point4[1] = (hmheight-j-2)*dpi; point4[2] = heightmap[((j+1)*hmwidth)+hmwidth-1]; drawTriangle(modelfile, point1, point2, point4); drawTriangle(modelfile, point1, point4, point3); } printf("STATUS___Drew left and right sides of mesh\n"); //drawing the bottom of the mesh point1[0] = 0; point1[1] = 0; point1[2] = 0; point2[0] = 0; point2[1] = dpi; point2[2] = 0; point3[0] = dpi; point3[1] = 0; point3[2] = 0; drawTriangle(modelfile, point1, point2, point3); point4[2] = 0; for(int i = 1; i < imin(hmheight, hmwidth)-1; i++){ point1[0] = 0; point1[1] = i * dpi; point2[0] = 0; point2[1] = (i+1) * dpi; point3[0] = i * dpi; point3[1] = 0; point4[0] = (i+1) * dpi; point4[1] = 0; drawTriangle(modelfile, point1, point2, point4); drawTriangle(modelfile, point1, point4, point3); point1[0] = (hmwidth - i - 2) * dpi; point1[1] = (hmheight - 1) * dpi; point2[0] = (hmwidth - i - 1) * dpi; point2[1] = (hmheight - 1) * dpi; point3[0] = (hmwidth - 1) * dpi; point3[1] = (hmheight - i - 2) * dpi; point4[0] = (hmwidth - 1) * dpi; point4[1] = (hmheight - i - 1) * dpi; drawTriangle(modelfile, point1, point2, point4); drawTriangle(modelfile, point1, point4, point3); } point1[0] = (hmwidth - 2) * dpi; point1[1] = (hmheight - 1) * dpi; point2[0] = (hmwidth - 1) * dpi; point2[1] = (hmheight - 1) * dpi; point3[0] = (hmwidth - 1) * dpi; point3[1] = (hmheight - 2) * dpi; drawTriangle(modelfile, point1, point2, point3); if(hmheight > hmwidth){ for(int i = 0; i < abs(hmheight-hmwidth); i++){ point1[0] = (hmwidth-1) * dpi; point1[1] = i * dpi; point2[0] = (hmwidth-1) * dpi; point2[1] = (i+1) * dpi; point3[0] = 0; point3[1] = (hmwidth+i-1) * dpi; point4[0] = 0; point4[1] = (hmwidth+i) * dpi; drawTriangle(modelfile, point1, point3, point2); drawTriangle(modelfile, point2, point3, point4); } } else if(hmheight < hmwidth){ for(int i = 0; i < abs(hmheight-hmwidth); i++){ point1[1] = (0) * dpi; point1[0] = (hmheight+i-1) * dpi; point2[1] = (0) * dpi; point2[0] = (hmheight+i) * dpi; point3[1] = (hmheight-1) * dpi; point3[0] = (i) * dpi; point4[1] = (hmheight-1) * dpi; point4[0] = (i+1) * dpi; drawTriangle(modelfile, point1, point3, point2); drawTriangle(modelfile, point2, point3, point4); } } /* // reference triangle that points at the origin point1[0] = 0; point1[1] = 0; point2[0] = -0.1; point2[1] = 0.1; point2[2] = -0.1; point3[0] = 0.1; point3[1] = -0.1; point3[2] = -0.1; drawTriangle(modelfile, point1, point2, point3); */ printf("STATUS___Drew bottom of mesh\n\n\n"); endSTL(modelfile); fclose(modelfile); free(heightmap); return 0; }