|
@@ -3,13 +3,14 @@
|
|
|
#include <vector>
|
|
|
#include <cmath>
|
|
|
#include <iomanip>
|
|
|
+#include <filesystem>
|
|
|
|
|
|
class BMP2Gcode
|
|
|
{
|
|
|
public:
|
|
|
BMP2Gcode();
|
|
|
- void traitement(char* nom_fichier);
|
|
|
- void fichier_conf();
|
|
|
+ void traitement(std::string nom_fichier);
|
|
|
+ int fichier_configuration(std::string conf);
|
|
|
|
|
|
private:
|
|
|
int entete();
|
|
@@ -20,18 +21,26 @@ class BMP2Gcode
|
|
|
unsigned int consecutif(unsigned int indice, unsigned int min, unsigned int max, unsigned int puissance, int sens);
|
|
|
|
|
|
unsigned int BMP_largeur, BMP_hauteur, BMP_offset, BMP_profondeur, BMP_taille;
|
|
|
- double conf_taille_laser, conf_puissance_min, conf_puissance_max, conf_vitesse, conf_vitesse_max, conf_taille_image;
|
|
|
+ double conf_taille_laser, conf_puissance_min, conf_puissance_max, conf_vitesse, conf_vitesse_max, conf_taille_image, conf_taille_pixel;
|
|
|
std::vector<unsigned int> tab_donnees;
|
|
|
std::string nom_fichier_bmp;
|
|
|
};
|
|
|
|
|
|
BMP2Gcode::BMP2Gcode()
|
|
|
-:BMP_largeur(0), BMP_hauteur(0), BMP_offset(0), BMP_profondeur(0), BMP_taille(0)
|
|
|
+:BMP_largeur(0), BMP_hauteur(0), BMP_offset(0), BMP_profondeur(0), BMP_taille(0),
|
|
|
+conf_taille_laser(-1), conf_puissance_min(-1), conf_puissance_max(-1),
|
|
|
+conf_vitesse(-1), conf_vitesse_max(-1),
|
|
|
+conf_taille_image(-1), conf_taille_pixel(-1)
|
|
|
{}
|
|
|
|
|
|
-void BMP2Gcode::traitement(char* nom_fichier)
|
|
|
+void BMP2Gcode::traitement(std::string nom_fichier)
|
|
|
{
|
|
|
- nom_fichier_bmp = nom_fichier;
|
|
|
+ //convertion du fichier et redimensionnement du fichier
|
|
|
+ int nbr_pixel_x = conf_taille_image / conf_taille_pixel;
|
|
|
+ std::string commande("convert " + nom_fichier + " -resize " + std::to_string(nbr_pixel_x) + " " + nom_fichier + ".bmp");
|
|
|
+ system(commande.c_str());
|
|
|
+
|
|
|
+ nom_fichier_bmp = nom_fichier + ".bmp";
|
|
|
|
|
|
if(entete() == 0)
|
|
|
{
|
|
@@ -133,24 +142,20 @@ int BMP2Gcode::donnees()
|
|
|
Il est donc nécessaire pour lire correctement les données de prévoir une limite qui est un multiple de 4
|
|
|
mais également de sauter ces éventuels informations
|
|
|
*/
|
|
|
-
|
|
|
- int reste = BMP_largeur % 4, longueur_ligne = BMP_largeur;
|
|
|
+
|
|
|
+ int reste = (BMP_largeur * BMP_profondeur/8) % 4, longueur_ligne = BMP_largeur * BMP_profondeur/8;
|
|
|
+ int limite = BMP_largeur * BMP_hauteur * BMP_profondeur/8 + BMP_offset;
|
|
|
|
|
|
if(reste != 0)
|
|
|
{
|
|
|
//Si la longueur d'une ligne n'est un multiple de 4
|
|
|
//il suffit alors d'ajouter à la ligne 4 - reste
|
|
|
- longueur_ligne += 4 - reste;
|
|
|
+ longueur_ligne += (4 - reste);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- int limite = longueur_ligne*BMP_hauteur * BMP_profondeur/8 + BMP_offset;
|
|
|
|
|
|
char *donnees = new char [ limite ];
|
|
|
fichier.read(donnees, limite);
|
|
|
|
|
|
- std::cout << "données brutes : " << std::endl;
|
|
|
-
|
|
|
int depart = BMP_offset;
|
|
|
for(int i = 0 ; i < BMP_hauteur ; i++)
|
|
|
{
|
|
@@ -163,7 +168,7 @@ int BMP2Gcode::donnees()
|
|
|
{tab_donnees.push_back((int)donnees[j]);}
|
|
|
}
|
|
|
|
|
|
- depart += longueur_ligne * BMP_profondeur/8;
|
|
|
+ depart += longueur_ligne;
|
|
|
}
|
|
|
delete[] donnees;
|
|
|
fichier.close();
|
|
@@ -180,18 +185,13 @@ int BMP2Gcode::sortie()
|
|
|
fichier_sortie.open (nom_fichier_gcode);
|
|
|
|
|
|
/****************************CONDITIONS INITIALES****************************/
|
|
|
- double taille_pixel = (double)(conf_taille_image)/(double)(BMP_largeur);
|
|
|
-
|
|
|
int sens = 1, nbr_passage = 1, ligne = 0, colonne = 0;
|
|
|
|
|
|
- //on arrondi la taille du pixel pour quelle corresponde à un multiple de la taille du laser
|
|
|
- double rapport = ceil(taille_pixel/conf_taille_laser);
|
|
|
- taille_pixel = rapport * conf_taille_laser;
|
|
|
-
|
|
|
std::cout << "***SORTIE***" << std::endl;
|
|
|
- std::cout << "largeur = " << BMP_largeur * taille_pixel << " mm" << std::endl;
|
|
|
- std::cout << "hauteur = " << BMP_hauteur * taille_pixel << " mm" << std::endl;
|
|
|
- std::cout << "taille pixel = " << taille_pixel << " mm" << std::endl;
|
|
|
+ std::cout << "BMP_largeur = " << BMP_largeur << " mm" << std::endl;
|
|
|
+ std::cout << "largeur = " << BMP_largeur * conf_taille_pixel << " mm" << std::endl;
|
|
|
+ std::cout << "hauteur = " << BMP_hauteur * conf_taille_pixel << " mm" << std::endl;
|
|
|
+ std::cout << "taille pixel = " << conf_taille_pixel << " mm" << std::endl;
|
|
|
|
|
|
//On passe en mode relatif
|
|
|
fichier_sortie << "G91" << std::endl;
|
|
@@ -209,12 +209,11 @@ int BMP2Gcode::sortie()
|
|
|
do
|
|
|
{
|
|
|
int indice = ligne * BMP_largeur + colonne;
|
|
|
-
|
|
|
unsigned int puissance = 0, indice_min = 0, indice_max = 0, nbr = 1;
|
|
|
+
|
|
|
puissance = conversion(255 - tab_donnees[indice], conf_puissance_min, conf_puissance_max);
|
|
|
indice_min = ligne * BMP_largeur;
|
|
|
indice_max = indice_min + BMP_largeur - 1;
|
|
|
-
|
|
|
|
|
|
//on détermine le nombre de pixels successifs pour lesquels la puissance du laser sera la même
|
|
|
nbr = consecutif(indice, indice_min, indice_max, puissance, sens);
|
|
@@ -228,7 +227,7 @@ int BMP2Gcode::sortie()
|
|
|
fichier_sortie << "M106 P1 S" << puissance << std::endl;
|
|
|
|
|
|
//on se déplace selon le sens
|
|
|
- fichier_sortie << "G1 X" << sens * taille_pixel * nbr << std::endl;
|
|
|
+ fichier_sortie << "G1 X" << sens * conf_taille_pixel * nbr << std::endl;
|
|
|
colonne += sens * nbr;
|
|
|
|
|
|
//ne pas oublier de rétablir la vitesse après les blancs
|
|
@@ -246,7 +245,7 @@ int BMP2Gcode::sortie()
|
|
|
if(colonne >= BMP_largeur)
|
|
|
{colonne = BMP_largeur - 1;}
|
|
|
|
|
|
- if(taille_pixel > conf_taille_laser * nbr_passage)
|
|
|
+ if(conf_taille_pixel > conf_taille_laser * nbr_passage)
|
|
|
{
|
|
|
/*si on a pas fait un nombre de passage suffisent pour égaler la taille du pixel
|
|
|
alors on repart dans l'autre sens en prennant soin de décaler la colonne
|
|
@@ -312,10 +311,11 @@ unsigned int BMP2Gcode::consecutif(unsigned int indice, unsigned int min, unsign
|
|
|
return nbr;
|
|
|
}
|
|
|
|
|
|
-void BMP2Gcode::fichier_conf()
|
|
|
+int BMP2Gcode::fichier_configuration(std::string conf)
|
|
|
{
|
|
|
+ int nbr_parametres = 0;
|
|
|
//On regarde si le fichier de configuration existe déjà
|
|
|
- std::ifstream fichier_conf("laser.conf");
|
|
|
+ std::ifstream fichier_conf(conf);
|
|
|
|
|
|
//s'il n'existe pas
|
|
|
if(!fichier_conf)
|
|
@@ -327,22 +327,24 @@ void BMP2Gcode::fichier_conf()
|
|
|
fichier_conf << "puissance_min 0" << std::endl;
|
|
|
fichier_conf << "puissance_max 255" << std::endl;
|
|
|
fichier_conf << "vitesse(mm/min) 1300" << std::endl;
|
|
|
- fichier_conf << "vitesse_max(mm/min) 10000" << std::endl;
|
|
|
+ fichier_conf << "vitesse_max(mm/min) 8000" << std::endl;
|
|
|
fichier_conf << "taille_image_x(mm) 150" << std::endl;
|
|
|
+ fichier_conf << "taille_pixel(mm) 0.4" << std::endl;
|
|
|
|
|
|
std::cout << "*************************************************" <<std::endl;
|
|
|
std::cout << "ATTENTION, un fichier de configuration a été crée" <<std::endl;
|
|
|
std::cout << "Il ne contient probablement pas les bonnes valeurs" <<std::endl;
|
|
|
- std::cout << "Pour les connaitre il est nécessaire dutiliser" <<std::endl;
|
|
|
- std::cout << "les scripts d'étalonnage" <<std::endl;
|
|
|
+ std::cout << "Pour les connaitre il est nécessaire d'utiliser" <<std::endl;
|
|
|
+ std::cout << "les scripts d'étalonnages" <<std::endl;
|
|
|
std::cout << "*************************************************" <<std::endl;
|
|
|
|
|
|
conf_taille_laser = 0.2;
|
|
|
conf_puissance_min = 0;
|
|
|
conf_puissance_max = 255;
|
|
|
conf_vitesse = 1300;
|
|
|
- conf_vitesse_max = 10000;
|
|
|
+ conf_vitesse_max = 8000;
|
|
|
conf_taille_image = 150;
|
|
|
+ conf_taille_pixel = 0.4;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -368,6 +370,52 @@ void BMP2Gcode::fichier_conf()
|
|
|
|
|
|
if(clef == "taille_image_x(mm)")
|
|
|
{conf_taille_image = valeur;}
|
|
|
+
|
|
|
+ if(clef == "taille_pixel(mm)")
|
|
|
+ {conf_taille_pixel = valeur;}
|
|
|
+ }
|
|
|
+
|
|
|
+ //vérification des paramètres
|
|
|
+ if(conf_taille_laser == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La taille du laser n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(conf_puissance_min == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La puissance minimale du laser n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(conf_puissance_max == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La puissance maximale du laser n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(conf_vitesse == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La vitesse du laser n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(conf_vitesse_max == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La vitesse maximale du laser n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(conf_taille_image == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La taille de l'image n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(conf_taille_pixel == -1)
|
|
|
+ {
|
|
|
+ std::cout << "ATTENTION ! La taille du pixel n'a pas été fournie" << std::endl;
|
|
|
+ return 3;
|
|
|
}
|
|
|
|
|
|
std::cout << "***CONFIGURATION***" << std::endl;
|
|
@@ -377,22 +425,78 @@ void BMP2Gcode::fichier_conf()
|
|
|
std::cout << "vitesse = " << conf_vitesse << " mm/min" << std::endl;
|
|
|
std::cout << "vitesse_max = " << conf_vitesse_max << " mm/min" << std::endl;
|
|
|
std::cout << "taille_image = " << conf_taille_image << " mm" << std::endl;
|
|
|
+ std::cout << "taille_pixel = " << conf_taille_pixel << " mm" << std::endl;
|
|
|
}
|
|
|
|
|
|
fichier_conf.close();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void aide()
|
|
|
+{
|
|
|
+ std::cout << "Ce programme permet de générer une fichier gcode à partir d'une image." << std::endl;
|
|
|
+ std::cout << "Pour fonctionner il nécessite imagemagik afin de convertir et redimensionner les images." << std::endl;
|
|
|
+ std::cout << "Les options :" << std::endl;
|
|
|
+ std::cout << "-h\t--help\taffiche cette aide" << std::endl;
|
|
|
+ std::cout << "-c\t\tpour préciser le fichier de configuration" << std::endl;
|
|
|
+ std::cout << "-i\t\tpour préciser l'image à traiter" << std::endl;
|
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
{
|
|
|
- if(argc >= 2)
|
|
|
+ //Il est nécessaire d'avoir au moins 3 arguments
|
|
|
+ if(argc >= 3)
|
|
|
{
|
|
|
- std::string entree = argv[1];
|
|
|
+ //On cherche la position des arguments
|
|
|
+ int position_c = -1, position_i = -1;
|
|
|
+
|
|
|
+ for(int i = 0 ; i < argc ; i++)
|
|
|
+ {
|
|
|
+ if(std::string(argv[i]) == "-c")
|
|
|
+ {position_c = i;}
|
|
|
+
|
|
|
+ if(std::string(argv[i]) == "-i")
|
|
|
+ {position_i = i;}
|
|
|
+ }
|
|
|
+
|
|
|
+ //On vérifie que les positions sont cohérentes
|
|
|
+ if(position_c == argc || position_i == argc || abs(position_c - position_i) < 2)
|
|
|
+ {
|
|
|
+ std::cout << "argument manquant\n" << std::endl;
|
|
|
+ aide();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //si on arrive ici c'est que des arguments ont été fournis
|
|
|
+ //On va donc les récupérer
|
|
|
+ std::string conf, fichier;
|
|
|
+
|
|
|
+ if(position_c > 0)
|
|
|
+ {conf = argv[position_c + 1];}
|
|
|
+
|
|
|
+ if(position_i > 0)
|
|
|
+ {fichier = argv[position_i + 1];}
|
|
|
+
|
|
|
+ std::cout << "fichier image : " << fichier << std::endl;
|
|
|
+
|
|
|
+ //on vérifie qu'il y a bien un fichier image
|
|
|
+ //s'il n'existe pas
|
|
|
+ std::ifstream fichier_image(fichier);
|
|
|
+ if (!fichier_image)
|
|
|
+ {
|
|
|
+ // read away
|
|
|
+ std::cout << "Le fichier image n'existe pas" << std::endl;
|
|
|
+ return 2;
|
|
|
+ }
|
|
|
+
|
|
|
BMP2Gcode image;
|
|
|
- image.fichier_conf();
|
|
|
- image.traitement(argv[1]);
|
|
|
+
|
|
|
+ if(image.fichier_configuration(conf) != 0)
|
|
|
+ {return 3;}
|
|
|
+ image.traitement(fichier);
|
|
|
}
|
|
|
else
|
|
|
- {std::cout << "Veuillez préciser un nom de fichier BMP" << std::endl;}
|
|
|
+ {aide();}
|
|
|
|
|
|
- return 1;
|
|
|
+ return 0;
|
|
|
}
|