gcode-slice/main.cpp
2021-12-21 20:11:40 +02:00

257 lines
4.5 KiB
C++

#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
#define DIR_TOP "./slic3r-config"
#define DIR_PRINT "print"
#define DIR_PRINTER "printer"
#define DIR_FILAMENT "filament"
int check_folder_structure(void);
vector<string> get_folder_entries(const char *folder);
vector<string> get_file_choices(void);
string pick_option(const string& name, const vector<string>& options);
string choose_support();
string choose_pattern(const string& place);
void flush_input(void);
void usage(char *name);
int main(int argc, char **argv)
{
vector<string> configurations;
vector<string>::iterator it;
string command;
// Check for stl file
if (argc < 2)
{
usage(argv[0]);
return -1;
}
if (0 != check_folder_structure())
{
return -1;
}
// Iterate configurations and build command
configurations = get_file_choices();
command = "slic3r --no-gui";
for (it = configurations.begin(); it != configurations.end(); ++it)
{
command += " --load \"";
command += *it;
command += "\"";
}
// Support choices
command += choose_support();
// Bottom pattern choices
command += " --bottom-infill-pattern \"";
command += choose_pattern("bottom infill");
command += "\"";
// Top pattern choices
command += " --top-infill-pattern \"";
command += choose_pattern("top infill");
command += "\"";
// Add filename
command += " \"";
command += argv[1];
command += "\"";
return system(command.c_str());
}
int check_folder_structure(void)
{
string path;
path = DIR_TOP;
if (0 != access(path.c_str(), F_OK))
{
printf("'%s' does not exist\n", path.c_str());
return -1;
}
path = DIR_TOP;
path += "/";
path += DIR_PRINT;
if (0 != access(path.c_str(), F_OK))
{
printf("'%s' does not exist\n", path.c_str());
return -1;
}
path = DIR_TOP;
path += "/";
path += DIR_PRINTER;
if (0 != access(path.c_str(), F_OK))
{
printf("'%s' does not exist\n", path.c_str());
return -1;
}
path = DIR_TOP;
path += "/";
path += DIR_FILAMENT;
if (0 != access(path.c_str(), F_OK))
{
printf("'%s' does not exist\n", path.c_str());
return -1;
}
return 0;
}
vector<string> get_folder_entries(const char *folder)
{
vector<string> result;
DIR *dir;
struct dirent *entry;
string name;
dir = opendir(folder);
if (NULL != dir)
{
entry = readdir(dir);
while (NULL != entry)
{
if ((DT_REG == entry->d_type) || (DT_LNK == entry->d_type))
{
name = entry->d_name;
result.push_back(name);
}
entry = readdir(dir);
}
closedir(dir);
}
sort(result.begin(), result.end());
return result;
}
vector<string> get_file_choices(void)
{
vector<string> result;
vector<string> options;
string folder;
string dirs[3];
string pick;
int i;
dirs[0] = DIR_PRINT;
dirs[1] = DIR_PRINTER;
dirs[2] = DIR_FILAMENT;
for (i = 0; i < 3; ++i)
{
folder = DIR_TOP;
folder += "/";
folder += dirs[i];
options = get_folder_entries(folder.c_str());
pick = pick_option(dirs[i], options);
if (pick.empty())
{
continue;
}
folder += "/";
folder += pick;
result.push_back(folder);
}
return result;
}
string pick_option(const string& name, const vector<string>& options)
{
vector<string>::const_iterator it;
int i;
int error;
if (1 == options.size())
{
return options[0];
}
printf("Choose %s:\n", name.c_str());
i = 1;
for (it = options.begin(); it != options.end(); ++it)
{
printf("%2d - %s\n", i, it->c_str());
++i;
}
redo_choice:
printf("Choice: ");
error = scanf("%d", &i);
flush_input();
if (1 != error)
{
printf("Could not understand choice. Try again.\n");
goto redo_choice;
}
if ((i <= 0) || (i > options.size()))
{
printf("Number out of bounds. Try again.\n");
goto redo_choice;
}
return options[i - 1];
}
string choose_support()
{
vector<string> options;
options.push_back("Do not generate support");
options.push_back("Generate support");
if (pick_option("support", options) == options[1])
{
return " --support-material";
}
else
{
return "";
}
}
string choose_pattern(const string& place)
{
vector<string> options;
options.push_back("rectilinear");
options.push_back("concentric");
options.push_back("hilbertcurve");
options.push_back("archimedeanchords");
options.push_back("octagramspiral");
return pick_option(place, options);
}
void flush_input()
{
char c;
while((c = getchar()) != '\n' && c != EOF);
}
void usage(char *name)
{
printf("Usage:\n");
printf("\t%s [stl file]\n", name);
}