From 1ac728a38314858d1435220da5b578e19e81cf0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Callyhoskinson=E2=80=9D?= Date: Sun, 26 Mar 2023 18:09:15 -0500 Subject: [PATCH] Started working with top and bottom headers --- FactsHandler.cpp | 25 +++++- FactsHandler.h | 3 +- IFPainter.cpp | 179 +++++++++++++++++++++++++--------------- IFPainter.h | 6 +- InformationGatherer.cpp | 22 +++-- InformationGatherer.h | 2 +- Options.cpp | 9 ++ Options.h | 4 + main.cpp | 12 ++- 9 files changed, 182 insertions(+), 80 deletions(-) diff --git a/FactsHandler.cpp b/FactsHandler.cpp index 50b519dfcb5..78c39bca902 100644 --- a/FactsHandler.cpp +++ b/FactsHandler.cpp @@ -1,5 +1,28 @@ #include "FactsHandler.h" -void makeInfoSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) { +void makeTopSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) { + //Draw black rectangle + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(0,0,0)); + //Draw text on top + std::string owner = "Owner: " + info.getInfo("owner"); + img.drawText(offsetX+150, offsetY + 30, 1, 1, owner, false, true); + + std::string version = "Version: " + info.getInfo("version"); + img.drawText(offsetX + 550, offsetY + 30, 1, 1, version, false, true); + + std::string lastUpdate = "Last Updated: " + info.getInfo("lastUpdate"); + img.drawText(offsetX + 900, offsetY + 30, 1, 1, lastUpdate, false, true); + + std::string classification = "Classification: " + info.getInfo("classification"); + img.drawText(offsetX + 1250, offsetY + 30, 1, 1, classification, false, true); +} + +void makeBottomSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) { + //Draw black rectangle + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(0, 0, 0)); + + //Draw text on top + std::string preparer = "Preparer: " + info.getInfo("preparer"); + img.drawText(offsetX + 150, offsetY + 30, 1, 1, preparer, false, true); } \ No newline at end of file diff --git a/FactsHandler.h b/FactsHandler.h index 2a688a32b07..731f3124ab0 100644 --- a/FactsHandler.h +++ b/FactsHandler.h @@ -16,4 +16,5 @@ class InformationGatherer; class IFPainter; -void makeInfoSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); \ No newline at end of file +void makeTopSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); +void makeBottomSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); \ No newline at end of file diff --git a/IFPainter.cpp b/IFPainter.cpp index 29514310473..8896840ac47 100644 --- a/IFPainter.cpp +++ b/IFPainter.cpp @@ -1,68 +1,113 @@ -#include "IFPainter.h" - - -IFPainter::IFPainter(int width, int height) - : img(width, height, CV_8UC3, cv::Scalar(255, 255, 255)) -{ - if (img.empty()) - { - std::cerr << "ISSUE: Image Frame failed to load (in IFPainter.cpp)" << std::endl; - } - // TODO: this -} - -IFPainter::~IFPainter() -{ - // TODO: this -} - -void IFPainter::drawImage(int x, int y, int width, int height, std::string imgPath) -{ - // TODO (Michael): Along with writing this method, figure out the best way to represent images in code. - // Perhaps there's a better way to store images; reading in images multiple times is inefficient, though if we only need - // to read in the image once (which I believe is the case), then reading images from a file should also be fine. - // TODO: this -} - -void IFPainter::drawText(int x, int y, int fontSize, int width, std::string text) -{ - // TODO: this - // keep in mind that we'll need options for bold, italics, etc. - // Try to make these methods as intuitive as possible in the idea of "we want text here, so we're confident that text will go here" - // Keep in mind text wrapping. -} - -void IFPainter::drawLine(int x1, int y1, int x2, int y2, int width, cv::Scalar color) -{ - // TODO: this -} - -void IFPainter::drawRect(int x1, int y1, int x2, int y2, cv::Scalar color) -{ - // TODO: this -} - - -void IFPainter::openInGUI() -{ - cv::namedWindow("Report", cv::WINDOW_AUTOSIZE); - cv::imshow("Report", this->img); - - cv::waitKey(0); //wait infinite time for a keypress - - try - { - cv::destroyWindow("Report"); - } - catch (std::exception& e) - { - } - // TODO: this -} - -void IFPainter::exportToFile(std::string filePath) -{ - cv::imwrite(filePath, this->img); - - // TODO: this +#include "IFPainter.h" + + +IFPainter::IFPainter(int width, int height) + : img(width, height, CV_8UC3, cv::Scalar(255, 255, 255)) +{ + if (img.empty()) + { + std::cerr << "ISSUE: Image Frame failed to load (in IFPainter.cpp)" << std::endl; + } + // TODO: this +} + +IFPainter::~IFPainter() +{ + // TODO: this +} + +void IFPainter::drawImage(int x, int y, int width, int height, std::string imgPath) +{ + // TODO (Michael): Along with writing this method, figure out the best way to represent images in code. + // Perhaps there's a better way to store images; reading in images multiple times is inefficient, though if we only need + // to read in the image once (which I believe is the case), then reading images from a file should also be fine. + // TODO: this + cv::Mat lilImage = imread(imgPath, cv::IMREAD_UNCHANGED); + cv::Mat resized_image; + resize(lilImage, resized_image, cv::Size(width, height), cv::INTER_LINEAR); + + //Trying to copyto the image on to the private image frame, img + cv::Mat destRoi; + try { + destRoi = img(cv::Rect(x, y, resized_image.cols, resized_image.rows)); + } + catch (...) { + std::cerr << "Trying to create roi out of image boundaries" << std::endl; + return; + } + resized_image.copyTo(destRoi); +} + +void IFPainter::drawText(int x, int y, double fontSize, int font_weight, std::string text, bool italics, bool isWhite) +{ + // TODO: this + // keep in mind that we'll need options for bold, italics, etc. + // Try to make these methods as intuitive as possible in the idea of "we want text here, so we're confident that text will go here" + // Keep in mind text wrapping. + + cv::Point text_position(x, y); + //boldness can be adjusted through font_weight + //The italics doesnt look really look like the traditional italics + if (italics) { + putText(img, text, text_position, cv::FONT_ITALIC, fontSize, cv::Scalar(0, 0, 0), font_weight); + } + else if (isWhite) { + putText(img, text, text_position, cv::FONT_HERSHEY_PLAIN, fontSize, cv::Scalar(255, 255, 255), font_weight); + } + else { + putText(img, text, text_position, cv::FONT_HERSHEY_PLAIN, fontSize, cv::Scalar(0, 0, 0), font_weight); + } +} + +void IFPainter::drawLine(int x1, int y1, int x2, int y2, int width, cv::Scalar color) +{ + // TODO: this + int lineType = cv::LINE_8; + cv::Point start(x1, y1); + cv::Point end(x2, y2); + line(img, + start, + end, + color, + width, + lineType); +} + +void IFPainter::drawRect(int x1, int y1, int x2, int y2, int width, cv::Scalar color) +{ + // TODO: this + //Should I try to fill the rectangle? + cv::Point topLeft(x1, y1); + cv::Point bottomRight(x2, y2); + rectangle(img, + topLeft, + bottomRight, + color, + width, + cv::LINE_8); +} + + +void IFPainter::openInGUI() +{ + cv::namedWindow("Report", cv::WINDOW_AUTOSIZE); + cv::imshow("Report", this->img); + + cv::waitKey(0); //wait infinite time for a keypress + + try + { + cv::destroyWindow("Report"); + } + catch (std::exception& e) + { + } + // TODO: this +} + +void IFPainter::exportToFile(std::string filePath) +{ + cv::imwrite(filePath, this->img); + + // TODO: this } \ No newline at end of file diff --git a/IFPainter.h b/IFPainter.h index d800477e22e..4c03a4db48b 100644 --- a/IFPainter.h +++ b/IFPainter.h @@ -5,7 +5,7 @@ /* * The IFPainter class serves to store the actual image frame that will be modified and output in the report. * All drawing and exporting operations will be done via function calls to this class. - * + * */ #pragma once @@ -21,9 +21,9 @@ class IFPainter ~IFPainter(); void drawImage(int x, int y, int width, int height, std::string imgPath); - void drawText(int x, int y, int fontSize, int width, std::string text); + void drawText(int x, int y, double fontSize, int font_weight, std::string text, bool italics, bool isWhite); void drawLine(int x1, int y1, int x2, int y2, int width, cv::Scalar color); - void drawRect(int x1, int y1, int x2, int y2, cv::Scalar color); + void drawRect(int x1, int y1, int x2, int y2, int width, cv::Scalar color); void openInGUI(); void exportToFile(std::string filePath); diff --git a/InformationGatherer.cpp b/InformationGatherer.cpp index ee2d54cc426..74fb83bbb29 100644 --- a/InformationGatherer.cpp +++ b/InformationGatherer.cpp @@ -10,16 +10,28 @@ InformationGatherer::~InformationGatherer() // TODO: this } -bool InformationGatherer::gatherInformation(std::string filePath) +bool InformationGatherer::gatherInformation(std::string filePath, std::string name) { // TODO: this - //Gather title - const char* cmd[2] = {"title", NULL}; + //Open database struct ged* g = ged_open("db", filePath.c_str(), 1); + //Gather title + const char* cmd[2] = { "title", NULL }; ged_exec(g, 1, cmd); - printf("Title: %s\n", bu_vls_addr(g->ged_result_str)); + infoMap.insert(std::pair("title", bu_vls_addr(g->ged_result_str))); + + //Gather name of preparer + infoMap.insert(std::pair < std::string, std::string>("preparer", name)); + + //Hard code other stuff into map for now + infoMap.insert(std::pair("owner", "Ally Hoskinson")); + infoMap.insert(std::pair("version", "1.1")); + infoMap.insert(std::pair("lastUpdate", "3/24/2023")); + infoMap.insert(std::pair("classification", "Confidential")); + + //Close database ged_close(g); return true; } @@ -27,5 +39,5 @@ bool InformationGatherer::gatherInformation(std::string filePath) std::string InformationGatherer::getInfo(std::string key) { // TODO: this - return ""; + return infoMap[key]; } \ No newline at end of file diff --git a/InformationGatherer.h b/InformationGatherer.h index 623e9fff066..16ce4c16aab 100644 --- a/InformationGatherer.h +++ b/InformationGatherer.h @@ -21,7 +21,7 @@ class InformationGatherer InformationGatherer(); ~InformationGatherer(); - bool gatherInformation(std::string filePath); + bool gatherInformation(std::string filePath, std::string name); std::string getInfo(std::string key); }; \ No newline at end of file diff --git a/Options.cpp b/Options.cpp index 95725fadb88..9169a6f5912 100644 --- a/Options.cpp +++ b/Options.cpp @@ -9,6 +9,7 @@ Options::Options() openGUI = false; exportToFile = false; fileName = ""; + name = "N/A"; } Options::~Options() @@ -44,6 +45,10 @@ void Options::setFileName(std::string n) { fileName = n; } +void Options::setName(std::string n) { + name = n; +} + std::string Options::getFilepath() { return filepath; } @@ -70,4 +75,8 @@ bool Options::getExportToFile() { std::string Options::getFileName() { return fileName; +} + +std::string Options::getName() { + return name; } \ No newline at end of file diff --git a/Options.h b/Options.h index 48fbb901dfc..1c06974b312 100644 --- a/Options.h +++ b/Options.h @@ -26,6 +26,7 @@ class Options void setOpenGUI(); void setExportToFile(); void setFileName(std::string n); + void setName(std::string n); //Getter functions std::string getFilepath(); int getWidth(); @@ -34,6 +35,7 @@ class Options bool getOpenGUI(); bool getExportToFile(); std::string getFileName(); + std::string getName(); private: //Path to file that will be used to generate report std::string filepath; @@ -48,4 +50,6 @@ class Options bool exportToFile; //Name of export file std::string fileName; + //Name of preparer + std::string name; }; \ No newline at end of file diff --git a/main.cpp b/main.cpp index 887b368b1d2..16ca42d9595 100644 --- a/main.cpp +++ b/main.cpp @@ -18,6 +18,7 @@ int main(int argc, char **argv) { bu_log(" F = path specified is a folder of models\n"); bu_log(" g = GUI output\n"); bu_log(" f = filename of png export, MUST end in .png\n"); + bu_log(" n = name of preparer, to be used in report\n"); return 0; } //If user has no arguments or did not specify filepath, give shortened help @@ -63,7 +64,7 @@ void readParameters(int argc, char** argv, Options &opt, bool &h, bool &f) int opts; - while ((opts = bu_getopt(argc, argv, "Fg?p:w:l:f:")) != -1) { + while ((opts = bu_getopt(argc, argv, "Fg?p:w:l:f:n:")) != -1) { switch (opts) { case 'p': f = true; @@ -85,6 +86,9 @@ void readParameters(int argc, char** argv, Options &opt, bool &h, bool &f) opt.setExportToFile(); opt.setFileName(bu_optarg); break; + case 'n': + opt.setName(bu_optarg); + break; case '?': h = true; break; @@ -108,7 +112,7 @@ void generateReport(Options opt) InformationGatherer info; // read in all information from model file - if (!info.gatherInformation(opt.getFilepath())) + if (!info.gatherInformation(opt.getFilepath(), opt.getName())) { std::cerr << "Error on Information Gathering. Report Generation skipped..." << std::endl; return; @@ -122,6 +126,10 @@ void generateReport(Options opt) // paintSidebar // etc... + makeTopSection(img, info, 10, 10, 1590, 50); + + makeBottomSection(img, info, 10, 990, 1590, 50); + // optionally, display the scene if (opt.getOpenGUI()) {