PlottWare/PlottWareControl/project.cpp
2019-08-08 17:02:07 +03:00

318 lines
8.3 KiB
C++

#include "project.h"
Project::Project(Settings* _settings){
settings=_settings;
filename="";
retrmode=CV_RETR_LIST;
cannythresh=100;
gcode="";
ivcombined=ImageViewer(&combined, "Images");
ivprocessed=ImageViewer(&processed, "Processing");
}
Project::Project(Settings* _settings, std::string _filename){
settings=_settings;
filename=_filename;
retrmode=CV_RETR_LIST;
cannythresh=100;
gcode="";
ivcombined=ImageViewer(&combined, "Images");
ivprocessed=ImageViewer(&processed, "Processing");
}
std::vector<Image>* Project::getImages(){
return &images;
}
int Project::getRetrMode(){
return retrmode;
}
int Project::getCannyThresh(){
return cannythresh;
}
std::map<int, int>* Project::getColoring(){
return &coloring;
}
std::string* Project::getGcode(){
return &gcode;
}
void Project::setFileName(std::string _filename){
filename=_filename;
}
void Project::setRetrMode(int _retrmode){
retrmode=_retrmode;
}
void Project::setCannyThresh(int _cannythresh){
cannythresh=_cannythresh;
}
bool Project::newProj(){
//create files, save def, etc
FILE* f=fopen(filename.c_str(), "w");
if(!f){
fprintf(stderr, "Error> Creating file for project. At: Project::newProj() (file: %s, line: %i)\n", __FILE__, __LINE__);
return false;
}
fprintf(f,"");
fclose(f);
return true;
}
void Project::loadProj(){
//load stuff, deserialize
}
void Project::save(){
//serialize, save to file
}
void Project::close(){
//close project, free up resources;
cv::destroyAllWindows();
}
bool Project::combine(){
//get col and row count
int colmax=0, rowmax=0;
for(std::vector<Image>::iterator it=images.begin(); it<images.end(); it++){
//get current mat
cv::Mat cur=*it->getMat();
//get resized mat
cv::Mat resz;
cv::resize(cur, resz, cv::Size(cur.cols*it->getScale(), cur.rows*it->getScale()));
//get cropped mat
cv::Mat crop=resz(cv::Rect(it->getCrop1().getX(), it->getCrop1().getY(), (it->getCrop2().getX()-it->getCrop1().getX())*it->getScale(), (it->getCrop2().getY()-it->getCrop1().getY())*it->getScale()));
//crop debug
if(settings->isDebug()){
ImageViewer* iv=new ImageViewer(crop, "DEBUG:combine> "+it->getFilename());
iv->show();
}
if(it->getPosition().getX()+crop.cols > colmax){
colmax=it->getPosition().getX()+crop.cols;
}
if(it->getPosition().getY()+crop.rows > rowmax){
rowmax=it->getPosition().getY()+crop.rows;
}
//cleanup
resz.release();
crop.release();
}
if(settings->isDebug()){
printf("DEBUG:combine> colmax=%i, rowmax=%i\n", colmax, rowmax);
}
//create new mat
combined=cv::Mat::zeros(rowmax, colmax, CV_8UC3);
//add layers
for(std::vector<Image>::iterator it=images.begin(); it<images.end(); it++){
//get current mat
cv::Mat cur=*it->getMat();
//get resized mat
cv::Mat resz;
cv::resize(cur, resz, cv::Size(cur.cols*it->getScale(), cur.rows*it->getScale()));
//get cropped mat
cv::Mat crop=resz(cv::Rect(it->getCrop1().getX()*it->getScale(), it->getCrop1().getY()*it->getScale(), (it->getCrop2().getX()-it->getCrop1().getX())*it->getScale(), (it->getCrop2().getY()-it->getCrop1().getY())*it->getScale()));
//add layer
crop.copyTo(combined(cv::Rect(it->getPosition().getX(), it->getPosition().getY(), crop.cols, crop.rows)));
//cleanup
resz.release();
crop.release();
}
//show results
ivcombined.refresh();
//everything alright
return true;
}
bool Project::process(){
if(combined.empty()){
return false;
}
//convert mat to gray
cv::Mat graymat;
cv::cvtColor(combined, graymat, CV_BGR2GRAY);
if(settings->isDebug()){
ImageViewer* iv=new ImageViewer(graymat, "DEBUG:process> cvtColor");
iv->show();
}
//blur edges
cv::blur(graymat, graymat, cv::Size(3, 3));
if(settings->isDebug()){
ImageViewer* iv=new ImageViewer(graymat, "DEBUG:process> blur");
iv->show();
}
//canny edge detection
cv::Mat canny;
cv::Canny(graymat, canny, cannythresh, cannythresh*2, 3);
if(settings->isDebug()){
ImageViewer* iv=new ImageViewer(canny, "DEBUG:process> Canny");
iv->show();
}
//find contours
cv::findContours(canny, contours, hierarchy, retrmode, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
//build color map if not ready
if(coloring.size()!=contours.size()){
coloring.clear();
for(int i=0; i<contours.size(); i++){
coloring[i]=-1; //set to default head to use
}
}
//draw output
processed=cv::Mat::zeros(canny.size(), CV_8UC3);
for(int i=0; i<contours.size(); i++){
cv::Scalar color=cv::Scalar(30, 200, 30);
cv::drawContours(processed, contours, i, color, 2, 8, hierarchy, 0, cv::Point());
}
//show results
ivprocessed.refresh();
//cleanup
graymat.release();
canny.release();
//it's k
return true;
}
bool Project::printEdge(int n){
//the same story
if(combined.empty()){
return false;
}
//draw contours
processed=cv::Mat::zeros(processed.size(), CV_8UC3);
for(int i=0; i<contours.size(); i++){
cv::Scalar color=cv::Scalar(30, 200, 30);
cv::drawContours(processed, contours, i, color, 2, 8, hierarchy, 0, cv::Point());
}
//highlight "The One"
cv::Scalar color=cv::Scalar(30, 30, 200);
cv::drawContours(processed, contours, n, color, 2, 8, hierarchy, 0, cv::Point());
//show results
ivprocessed.refresh();
//kkk
return true;
}
bool Project::generateGcode(){
//check if the stuff is set
if(contours.empty()){
return false;
}
//clear previous gcode
gcode="";
//statistics
unsigned int lines=0;
double maxX=0, maxY=0;
//add info
gcode+=";Generated by: PlottWareControl\n;Project: "+filename+"\n;Program created by: Fandly Gergo (fandlygergo@gmail.hu, systemtest.tk)\n\n\n\n";
//startup code
gcode+="G90 ;absolute positioning\n";
gcode+="M17 ;enable steppers\n";
gcode+="T1000 ;deselect all tools\n";
gcode+="G28 ;home axises\n";
lines+=10;
//iterate through contours
for(int i=0; i<contours.size(); i++){
//if we need to eliminate the contour...
if(coloring[i]==0){
continue; //we do so
}
if(coloring[i]==-1){
coloring[i]=1; //set to the default if not set...
}
//start contour drawing
gcode+=";printing contour #"+std::to_string(i)+"\n";
//select tool
gcode+="T"+std::to_string(coloring[i])+"\n";
//move to first point
gcode+="G0 X"+std::to_string(contours[i][0].x/10.0)+" Y"+std::to_string(contours[i][0].y/10.0)+"\n";
if(contours[i][0].x/10.0 > maxX){
maxX=contours[i][0].x/10.0;
}
if(contours[i][0].y/10.0 > maxY){
maxY=contours[i][0].y/10.0;
}
//move pen down
gcode+="M300 S10\n";
lines+=4;
//iterate through points
for(int o=1; o<contours[i].size(); o++){
gcode+="G1 X"+std::to_string(contours[i][o].x/10.0)+" Y"+std::to_string(contours[i][o].y/10.0)+"\n";
if(contours[i][o].x/10.0 > maxX){
maxX=contours[i][o].x/10.0;
}
if(contours[i][o].y/10.0 > maxY){
maxY=contours[i][o].y/10.0;
}
lines++;
}
//lift up pen
gcode+="M300 S50\n";
lines+=1;
}
//end
gcode+="T1000 ;deselect tool\n";
gcode+="M18 ;disable steppers\n";
gcode+="M2 ;program end\n";
lines+=3;
//print "final thoughts"
lines+=7;
gcode+="\n\n\n;Line count: "+std::to_string(lines)+"\n;Max X: "+std::to_string(maxX)+"\n;Max Y: "+std::to_string(maxY)+"\n;ENJOY!";
}
bool Project::exportGcode(std::string file){
FILE* f=fopen(file.c_str(), "w");
if(!f){
fprintf(stderr, "Error> Can't create file for gcode export. At: Project::exportGcode(std::string file) (file: %s, line: %i)\n", __FILE__, __LINE__);
return false;
}
fprintf(f, "%s", gcode.c_str());
fclose(f);
return true;
}