From e6505b3b1836e0004aacec41662407a7588c4eb7 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 09:53:10 +0200 Subject: [PATCH 01/13] Ajout option text ou svg --- .gitignore | 2 + MaxRectsBinPackTest/BinPack.cpp | 87 +++++++++++++++++++++++++-------- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 3dcbda1..0f659ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ bin *.so *.dylib +*.o +BinPackTest diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index f7328bb..db79031 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -1,35 +1,74 @@ #include "../MaxRectsBinPack.h" #include +int showUsage(void) +{ + fprintf(stderr, "Usage: MaxRectsBinPackTest [options] binWidth binHeight w_0 h_0 w_1 h_1 w_2 h_2 ... w_n h_n\n"); + fprintf(stderr, " options :\n"); + fprintf(stderr, " -t (default) to print result in text format\n"); + fprintf(stderr, " -s to print result in svg format\n"); + fprintf(stderr, " where binWidth and binHeight define the size of the bin.\n"); + fprintf(stderr, " w_i is the width of the i'th rectangle to pack, and h_i the height.\n"); + fprintf(stderr, "Example: MaxRectsBinPackTest -s 256 256 30 20 50 20 10 80 90 20\n"); + + return 0; +} int main(int argc, char **argv) { - - if (argc < 5 || argc % 2 != 1) - { - printf("Usage: MaxRectsBinPackTest binWidth binHeight w_0 h_0 w_1 h_1 w_2 h_2 ... w_n h_n\n"); - printf(" where binWidth and binHeight define the size of the bin.\n"); - printf(" w_i is the width of the i'th rectangle to pack, and h_i the height.\n"); - printf("Example: MaxRectsBinPackTest 256 256 30 20 50 20 10 80 90 20\n"); - return 0; - } - using namespace rbp; // Create a bin to pack to, use the bin size from command line. MaxRectsBinPack bin; - int binWidth = atoi(argv[1]); - int binHeight = atoi(argv[2]); - printf("Initializing bin to size %dx%d.\n", binWidth, binHeight); + enum { TEXT_MODE, SVG_MODE } mode = TEXT_MODE; + size_t optind; + int *rects = (int *)malloc(sizeof(int)*(argc - 1)); + int nb_rect = 0; + for (optind = 1; optind < argc; optind++) + { + if(argv[optind][0] == '-') + { + switch(argv[optind][1]) + { + case 't': + mode = TEXT_MODE; + break; + case 's': + mode = SVG_MODE; + break; + default: + return showUsage(); + } + } + else + { + rects[nb_rect] = atoi(argv[optind]); + nb_rect++; + } + } + + if(nb_rect % 2 != 0) + { + return showUsage(); + } + + int binWidth = rects[0]; + int binHeight = rects[1]; + if(mode == TEXT_MODE) + printf("Initializing bin to size %dx%d.\n", binWidth, binHeight); + else + printf("\n", binWidth, binHeight); + bin.Init(binWidth, binHeight); // Pack each rectangle (w_i, h_i) the user inputted on the command line. - for(int i = 3; i < argc; i += 2) + for(int i = 2; i < nb_rect; i += 2) { // Read next rectangle to pack. - int rectWidth = atoi(argv[i]); - int rectHeight = atoi(argv[i+1]); - printf("Packing rectangle of size %dx%d: ", rectWidth, rectHeight); + int rectWidth = rects[i]; + int rectHeight = rects[i+1]; + if(mode == TEXT_MODE) + printf("Packing rectangle of size %dx%d: ", rectWidth, rectHeight); // Perform the packing. MaxRectsBinPack::FreeRectChoiceHeuristic heuristic = MaxRectsBinPack::RectBestShortSideFit; // This can be changed individually even for each rectangle packed. @@ -37,9 +76,17 @@ int main(int argc, char **argv) // Test success or failure. if (packedRect.height > 0) - printf("Packed to (x,y)=(%d,%d), (w,h)=(%d,%d). Free space left: %.2f%%\n", packedRect.x, packedRect.y, packedRect.width, packedRect.height, 100.f - bin.Occupancy()*100.f); + if(mode == TEXT_MODE) + printf("Packed to (x,y)=(%d,%d), (w,h)=(%d,%d). Free space left: %.2f%%\n", packedRect.x, packedRect.y, packedRect.width, packedRect.height, 100.f - bin.Occupancy()*100.f); + else + printf("\n", packedRect.width, packedRect.height,packedRect.x, packedRect.y); else - printf("Failed! Could not find a proper position to pack this rectangle into. Skipping this one.\n"); + fprintf(stderr, "Failed! Could not find a proper position to pack this rectangle into. Skipping this one.\n"); } - printf("Done. All rectangles packed.\n"); + if(mode == TEXT_MODE) + printf("Done. All rectangles packed.\n"); + else + printf("\n"); + + free(rects); } From 16b8ae67fb29428d6f607e3eda2217f04f362a0e Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 10:11:52 +0200 Subject: [PATCH 02/13] Change the rect fill color --- MaxRectsBinPackTest/BinPack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index db79031..cafb60e 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -79,7 +79,7 @@ int main(int argc, char **argv) if(mode == TEXT_MODE) printf("Packed to (x,y)=(%d,%d), (w,h)=(%d,%d). Free space left: %.2f%%\n", packedRect.x, packedRect.y, packedRect.width, packedRect.height, 100.f - bin.Occupancy()*100.f); else - printf("\n", packedRect.width, packedRect.height,packedRect.x, packedRect.y); + printf("\n", packedRect.width, packedRect.height,packedRect.x, packedRect.y); else fprintf(stderr, "Failed! Could not find a proper position to pack this rectangle into. Skipping this one.\n"); } From 1f6195434becf0f29d3325ae82f04a88bc4ead94 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 11:22:46 +0200 Subject: [PATCH 03/13] Gestion des trous --- MaxRectsBinPack.cpp | 14 ++++++++++++++ MaxRectsBinPack.h | 9 ++++++++- MaxRectsBinPackTest/BinPack.cpp | 10 +++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/MaxRectsBinPack.cpp b/MaxRectsBinPack.cpp index 00fcb99..1ade55f 100644 --- a/MaxRectsBinPack.cpp +++ b/MaxRectsBinPack.cpp @@ -109,6 +109,20 @@ void MaxRectsBinPack::Insert(std::vector &rects, std::vector &ds } } +bool MaxRectsBinPack::Insert(const Rect &rect) +{ + if (usedRectangles.size() == 0) + { + if ((rect.x + rect.width > binWidth && rect.y + rect.height > binHeight) || (rect.x + rect.width > binHeight && rect.y + rect.height > binWidth)) + return false; + + this->PlaceRect(rect); + + return true; + } + return false; +} + void MaxRectsBinPack::PlaceRect(const Rect &node) { for(size_t i = 0; i < freeRectangles.size();) diff --git a/MaxRectsBinPack.h b/MaxRectsBinPack.h index 345591b..713db41 100644 --- a/MaxRectsBinPack.h +++ b/MaxRectsBinPack.h @@ -36,7 +36,7 @@ class MaxRectsBinPack RectBestLongSideFit, ///< -BLSF: Positions the rectangle against the long side of a free rectangle into which it fits the best. RectBestAreaFit, ///< -BAF: Positions the rectangle into the smallest free rect into which it fits. RectBottomLeftRule, ///< -BL: Does the Tetris placement. - RectContactPointRule ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible. + RectContactPointRule, ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible. }; /// Inserts the given list of rectangles in an offline/batch mode, possibly rotated. @@ -48,6 +48,13 @@ class MaxRectsBinPack /// Inserts a single rectangle into the bin, possibly rotated. Rect Insert(int width, int height, FreeRectChoiceHeuristic method); + /// Inserts a single rectangle into the bin at the desire position. + /// This usefull to create an hile in the bin + /// You can't excute this after the start off the packing + /// @param rect The rectangle to insert. + /// @return True if rectangle was insert + bool Insert(const Rect &rect); + /// Computes the ratio of used surface area to the total bin area. double Occupancy() const; diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index cafb60e..9d06e0e 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -60,6 +60,14 @@ int main(int argc, char **argv) printf("\n", binWidth, binHeight); bin.Init(binWidth, binHeight); + + Rect hole; + hole.x = 50; + hole.y = 50; + hole.width = 50; + hole.height = 50; + bin.Insert(hole); + printf("\n", hole.width, hole.height, hole.x, hole.y); // Pack each rectangle (w_i, h_i) the user inputted on the command line. for(int i = 2; i < nb_rect; i += 2) @@ -71,7 +79,7 @@ int main(int argc, char **argv) printf("Packing rectangle of size %dx%d: ", rectWidth, rectHeight); // Perform the packing. - MaxRectsBinPack::FreeRectChoiceHeuristic heuristic = MaxRectsBinPack::RectBestShortSideFit; // This can be changed individually even for each rectangle packed. + MaxRectsBinPack::FreeRectChoiceHeuristic heuristic = MaxRectsBinPack::RectContactPointRule; // This can be changed individually even for each rectangle packed. Rect packedRect = bin.Insert(rectWidth, rectHeight, heuristic); // Test success or failure. From 1a51ca3f0241a134784f1d30cf7498b7cfb84bd3 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 11:23:53 +0200 Subject: [PATCH 04/13] Gestion des trous --- MaxRectsBinPackTest/BinPack.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index 9d06e0e..2e37ae4 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -62,10 +62,10 @@ int main(int argc, char **argv) bin.Init(binWidth, binHeight); Rect hole; - hole.x = 50; - hole.y = 50; - hole.width = 50; - hole.height = 50; + hole.x = 30; + hole.y = 120; + hole.width = 90; + hole.height = 70; bin.Insert(hole); printf("\n", hole.width, hole.height, hole.x, hole.y); From 556d695554a5481d2dd3ea905777bce285e5725f Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 11:48:21 +0200 Subject: [PATCH 05/13] Ajout de la notion de trou en ligne de commande --- MaxRectsBinPack.cpp | 11 +++++++---- MaxRectsBinPack.h | 2 +- MaxRectsBinPackTest/BinPack.cpp | 17 ++++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/MaxRectsBinPack.cpp b/MaxRectsBinPack.cpp index 1ade55f..ac86dfe 100644 --- a/MaxRectsBinPack.cpp +++ b/MaxRectsBinPack.cpp @@ -109,14 +109,17 @@ void MaxRectsBinPack::Insert(std::vector &rects, std::vector &ds } } -bool MaxRectsBinPack::Insert(const Rect &rect) +bool MaxRectsBinPack::Insert(std::vector &rects) { if (usedRectangles.size() == 0) { - if ((rect.x + rect.width > binWidth && rect.y + rect.height > binHeight) || (rect.x + rect.width > binHeight && rect.y + rect.height > binWidth)) - return false; + for(size_t i = 0; i < rects.size(); i++) + { + if ((rects[i].x + rects[i].width > binWidth && rects[i].y + rects[i].height > binHeight) || (rects[i].x + rects[i].width > binHeight && rects[i].y + rects[i].height > binWidth)) + return false; - this->PlaceRect(rect); + this->PlaceRect(rects[i]); + } return true; } diff --git a/MaxRectsBinPack.h b/MaxRectsBinPack.h index 713db41..cb46db7 100644 --- a/MaxRectsBinPack.h +++ b/MaxRectsBinPack.h @@ -53,7 +53,7 @@ class MaxRectsBinPack /// You can't excute this after the start off the packing /// @param rect The rectangle to insert. /// @return True if rectangle was insert - bool Insert(const Rect &rect); + bool Insert(std::vector &rects); /// Computes the ratio of used surface area to the total bin area. double Occupancy() const; diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index 2e37ae4..d1f9859 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -7,6 +7,7 @@ int showUsage(void) fprintf(stderr, " options :\n"); fprintf(stderr, " -t (default) to print result in text format\n"); fprintf(stderr, " -s to print result in svg format\n"); + fprintf(stderr, " -o x y w h to place on hole on specified coords\n"); fprintf(stderr, " where binWidth and binHeight define the size of the bin.\n"); fprintf(stderr, " w_i is the width of the i'th rectangle to pack, and h_i the height.\n"); fprintf(stderr, "Example: MaxRectsBinPackTest -s 256 256 30 20 50 20 10 80 90 20\n"); @@ -24,6 +25,7 @@ int main(int argc, char **argv) size_t optind; int *rects = (int *)malloc(sizeof(int)*(argc - 1)); int nb_rect = 0; + std::vector holes; for (optind = 1; optind < argc; optind++) { if(argv[optind][0] == '-') @@ -36,6 +38,9 @@ int main(int argc, char **argv) case 's': mode = SVG_MODE; break; + case 'o': + holes.push_back({ atoi(argv[++optind]), atoi(argv[++optind]), atoi(argv[++optind]), atoi(argv[++optind]) }); + break; default: return showUsage(); } @@ -61,13 +66,11 @@ int main(int argc, char **argv) bin.Init(binWidth, binHeight); - Rect hole; - hole.x = 30; - hole.y = 120; - hole.width = 90; - hole.height = 70; - bin.Insert(hole); - printf("\n", hole.width, hole.height, hole.x, hole.y); + for(size_t i = 0; i < holes.size(); i++) + { + printf("\n", holes[i].width, holes[i].height, holes[i].x, holes[i].y); + } + bin.Insert(holes); // Pack each rectangle (w_i, h_i) the user inputted on the command line. for(int i = 2; i < nb_rect; i += 2) From 819b3f3ee4118aadfdae409533bcfebf21c2ccf4 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 13:27:08 +0200 Subject: [PATCH 06/13] =?UTF-8?q?Mode=20par=20d=C3=A9faut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MaxRectsBinPackTest/BinPack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index d1f9859..dd463ff 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -82,7 +82,7 @@ int main(int argc, char **argv) printf("Packing rectangle of size %dx%d: ", rectWidth, rectHeight); // Perform the packing. - MaxRectsBinPack::FreeRectChoiceHeuristic heuristic = MaxRectsBinPack::RectContactPointRule; // This can be changed individually even for each rectangle packed. + MaxRectsBinPack::FreeRectChoiceHeuristic heuristic = MaxRectsBinPack::RectBestShortSideFit; // This can be changed individually even for each rectangle packed. Rect packedRect = bin.Insert(rectWidth, rectHeight, heuristic); // Test success or failure. From c8c60d738eaeb50dbcf10f21e3a23c7bd52642cd Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 10 Oct 2025 15:01:20 +0200 Subject: [PATCH 07/13] *int => vector --- MaxRectsBinPackTest/BinPack.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/MaxRectsBinPackTest/BinPack.cpp b/MaxRectsBinPackTest/BinPack.cpp index dd463ff..d1b11e7 100644 --- a/MaxRectsBinPackTest/BinPack.cpp +++ b/MaxRectsBinPackTest/BinPack.cpp @@ -23,8 +23,8 @@ int main(int argc, char **argv) MaxRectsBinPack bin; enum { TEXT_MODE, SVG_MODE } mode = TEXT_MODE; size_t optind; - int *rects = (int *)malloc(sizeof(int)*(argc - 1)); - int nb_rect = 0; + + std::vector sizes; std::vector holes; for (optind = 1; optind < argc; optind++) { @@ -47,18 +47,21 @@ int main(int argc, char **argv) } else { - rects[nb_rect] = atoi(argv[optind]); - nb_rect++; + sizes.push_back(atoi(argv[optind])); } } - if(nb_rect % 2 != 0) + if(sizes.size() % 2 != 0) { return showUsage(); } - int binWidth = rects[0]; - int binHeight = rects[1]; + int binWidth = sizes.at(0); + int binHeight = sizes.at(1); + + sizes.erase(sizes.begin()); + sizes.erase(sizes.begin()); + if(mode == TEXT_MODE) printf("Initializing bin to size %dx%d.\n", binWidth, binHeight); else @@ -73,11 +76,11 @@ int main(int argc, char **argv) bin.Insert(holes); // Pack each rectangle (w_i, h_i) the user inputted on the command line. - for(int i = 2; i < nb_rect; i += 2) + for(int i = 0; i < sizes.size(); i += 2) { // Read next rectangle to pack. - int rectWidth = rects[i]; - int rectHeight = rects[i+1]; + int rectWidth = sizes.at(i); + int rectHeight = sizes.at(i + 1); if(mode == TEXT_MODE) printf("Packing rectangle of size %dx%d: ", rectWidth, rectHeight); @@ -98,6 +101,4 @@ int main(int argc, char **argv) printf("Done. All rectangles packed.\n"); else printf("\n"); - - free(rects); } From 8bb355dca757fc947552430dbb1fba64fbb70ff6 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Mon, 20 Oct 2025 14:06:38 +0200 Subject: [PATCH 08/13] WIP ajout de qt --- RectangleBinPack.pro | 32 ++++++++++++++++++++++++++++++++ main.cpp | 13 +++++++++++++ mainwindow.cpp | 23 +++++++++++++++++++++++ mainwindow.h | 18 ++++++++++++++++++ mainwindow.ui | 20 ++++++++++++++++++++ 5 files changed, 106 insertions(+) create mode 100644 RectangleBinPack.pro create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui diff --git a/RectangleBinPack.pro b/RectangleBinPack.pro new file mode 100644 index 0000000..e46ba7b --- /dev/null +++ b/RectangleBinPack.pro @@ -0,0 +1,32 @@ +###################################################################### +# Automatically generated by qmake (3.1) Mon Oct 20 10:20:52 2025 +###################################################################### + +TEMPLATE = app +TARGET = RectangleBinPack +INCLUDEPATH += . +QT += core gui svg + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# You can make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# Please consult the documentation of the deprecated API in order to know +# how to port your code away from it. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +# Input +HEADERS += MaxRectsBinPack.h \ + Rect.h \ + mainwindow.h +SOURCES += MaxRectsBinPack.cpp \ + Rect.cpp \ +# MaxRectsBinPackTest/BinPack.cpp \ + main.cpp \ + mainwindow.cpp + +FORMS += \ + mainwindow.ui diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6676184 --- /dev/null +++ b/main.cpp @@ -0,0 +1,13 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + srand((unsigned) time(NULL)); + + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..5a29f0d --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,23 @@ +#include +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) +{ + setupUi(this); + + svgWidget = new QSvgWidget(this); + svgWidget->load(QString("show(); + + QVBoxLayout * verticalLayout = new QVBoxLayout(centralWidget()); // make a layout to put the svgwidget it so it scales with the window + verticalLayout->setContentsMargins(0, 0, 0, 0); // no borders + verticalLayout->addWidget(svgWidget);// the widget to it + centralWidget()->setLayout(verticalLayout); +} + +MainWindow::~MainWindow() +{ + delete svgWidget; +} + diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..c233c30 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,18 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include "ui_mainwindow.h" + +class MainWindow : public QMainWindow, private Ui::MainWindow +{ + Q_OBJECT +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); +private: + QSvgWidget *svgWidget; +}; + +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..9e846a3 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,20 @@ + + + MainWindow + + + + 0 + 0 + 824 + 673 + + + + MainWindow + + + + + + From 4625cea8c9047d21cdf38e1fff6ae36a913bcdc0 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Mon, 20 Oct 2025 14:29:23 +0000 Subject: [PATCH 09/13] Ok pour SVG --- mainwindow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 5a29f0d..edb0cf7 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,14 +1,15 @@ #include #include "mainwindow.h" #include "ui_mainwindow.h" +#include "MaxRectsBinPack.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupUi(this); svgWidget = new QSvgWidget(this); - svgWidget->load(QString("show(); + svgWidget->load(QString("").toLocal8Bit()); + // svgWidget->load(QString("/home/corentin/dev/RectangleBinPack/test.svg")); QVBoxLayout * verticalLayout = new QVBoxLayout(centralWidget()); // make a layout to put the svgwidget it so it scales with the window verticalLayout->setContentsMargins(0, 0, 0, 0); // no borders From 90bca9cc099343b2ae150bef4f67c3ed89b71b1d Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Mon, 20 Oct 2025 17:31:40 +0200 Subject: [PATCH 10/13] =?UTF-8?q?Param=C3=A9trage=20r=C3=A9sultat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mainwindow.cpp | 37 ++++++++++++++-- mainwindow.h | 5 +++ mainwindow.ui | 113 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 149 insertions(+), 6 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index edb0cf7..399a3f2 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,4 +1,5 @@ #include +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "MaxRectsBinPack.h" @@ -8,13 +9,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) setupUi(this); svgWidget = new QSvgWidget(this); - svgWidget->load(QString("").toLocal8Bit()); - // svgWidget->load(QString("/home/corentin/dev/RectangleBinPack/test.svg")); - QVBoxLayout * verticalLayout = new QVBoxLayout(centralWidget()); // make a layout to put the svgwidget it so it scales with the window + QVBoxLayout * verticalLayout = new QVBoxLayout(gbResultat); // make a layout to put the svgwidget it so it scales with the window verticalLayout->setContentsMargins(0, 0, 0, 0); // no borders verticalLayout->addWidget(svgWidget);// the widget to it - centralWidget()->setLayout(verticalLayout); + gbResultat->setLayout(verticalLayout); } MainWindow::~MainWindow() @@ -22,3 +21,33 @@ MainWindow::~MainWindow() delete svgWidget; } + QString MainWindow::process(void) + { + using namespace rbp; + int width = txtLargeur->toPlainText().toInt(); + int height = txtHauteur->toPlainText().toInt(); + QString svg = ""; + + svg += ""; + + // Create a bin to pack to, use the bin size from command line. + MaxRectsBinPack bin; + + bin.Init(width, height); + + svg += ""; + + return svg; + } + + void MainWindow::on_txtLargeur_textChanged() + { + QString svg = process(); + svgWidget->load(svg.toLocal8Bit()); + qDebug() << "test" << svg; + } + + void MainWindow::on_txtHauteur_textChanged() + { + svgWidget->load(process().toLocal8Bit()); + } diff --git a/mainwindow.h b/mainwindow.h index c233c30..8eb8598 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -13,6 +13,11 @@ class MainWindow : public QMainWindow, private Ui::MainWindow ~MainWindow(); private: QSvgWidget *svgWidget; + + QString process(void); +private slots: + void on_txtLargeur_textChanged(); + void on_txtHauteur_textChanged(); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 9e846a3..1444ac4 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,14 +6,123 @@ 0 0 - 824 + 645 673 + + + 0 + 0 + + MainWindow - + + + + + + + 0 + 0 + + + + Paramètres + + + + + + Largeur + + + + + + + + 0 + 0 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + + + + Hauteur + + + + + + + + 0 + 0 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + + + + Trous + + + + + + + Pavés + + + + + + + + + + + 0 + 0 + + + + Résultat + + + + + From 6d62e33587815eedeea20a2544a0b3b864ecc5b3 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 24 Oct 2025 11:29:04 +0200 Subject: [PATCH 11/13] Interface --- RectangleBinPack.pro | 3 + RectangleBinPack.qrc | 3 + mainwindow.ui | 183 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 164 insertions(+), 25 deletions(-) create mode 100644 RectangleBinPack.qrc diff --git a/RectangleBinPack.pro b/RectangleBinPack.pro index e46ba7b..62dc47e 100644 --- a/RectangleBinPack.pro +++ b/RectangleBinPack.pro @@ -30,3 +30,6 @@ SOURCES += MaxRectsBinPack.cpp \ FORMS += \ mainwindow.ui + +RESOURCES += \ + RectangleBinPack.qrc diff --git a/RectangleBinPack.qrc b/RectangleBinPack.qrc new file mode 100644 index 0000000..3d07e4e --- /dev/null +++ b/RectangleBinPack.qrc @@ -0,0 +1,3 @@ + + + diff --git a/mainwindow.ui b/mainwindow.ui index 1444ac4..f6e80a0 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -32,18 +32,11 @@ Paramètres - - - - - Largeur - - - - - + + + - + 0 0 @@ -62,15 +55,150 @@ - - + + + + + 0 + 0 + + + + + 0 + 25 + + - Hauteur + Largeur - - + + + + + 0 + 0 + + + + + 0 + 30 + + + + Qt::LeftToRight + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Trous + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ajouter + + + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Pavés + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ajouter + + + + + + + + 0 @@ -91,20 +219,25 @@ - - - - Trous + + + + + 0 + 25 + - - - - - Pavés + Hauteur + + + + + + From cfdfeb4a59abe6da3dc9322e346ed49785d4fdc1 Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Fri, 24 Oct 2025 13:57:22 +0200 Subject: [PATCH 12/13] Design final --- RectangleBinPack.pro | 3 + itemwidget.cpp | 6 ++ itemwidget.h | 14 +++++ itemwidget.ui | 142 +++++++++++++++++++++++++++++++++++++++++++ mainwindow.cpp | 19 +++++- mainwindow.h | 5 ++ mainwindow.ui | 100 ++++++++++++++++++++++++++++-- 7 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 itemwidget.cpp create mode 100644 itemwidget.h create mode 100644 itemwidget.ui diff --git a/RectangleBinPack.pro b/RectangleBinPack.pro index 62dc47e..b840cf0 100644 --- a/RectangleBinPack.pro +++ b/RectangleBinPack.pro @@ -21,14 +21,17 @@ CONFIG += c++11 # Input HEADERS += MaxRectsBinPack.h \ Rect.h \ + itemwidget.h \ mainwindow.h SOURCES += MaxRectsBinPack.cpp \ Rect.cpp \ # MaxRectsBinPackTest/BinPack.cpp \ + itemwidget.cpp \ main.cpp \ mainwindow.cpp FORMS += \ + itemwidget.ui \ mainwindow.ui RESOURCES += \ diff --git a/itemwidget.cpp b/itemwidget.cpp new file mode 100644 index 0000000..6a2811d --- /dev/null +++ b/itemwidget.cpp @@ -0,0 +1,6 @@ +#include "itemwidget.h" + +ItemWidget::ItemWidget(QWidget *parent) : QWidget(parent) +{ + setupUi(this); +} diff --git a/itemwidget.h b/itemwidget.h new file mode 100644 index 0000000..883f181 --- /dev/null +++ b/itemwidget.h @@ -0,0 +1,14 @@ +#ifndef ITEMWIDGET_H +#define ITEMWIDGET_H + +#include +#include "ui_itemwidget.h" + +class ItemWidget : public QWidget, private Ui::ItemWidget +{ + Q_OBJECT +public: + ItemWidget(QWidget *parent); +}; + +#endif // ITEMWIDGET_H diff --git a/itemwidget.ui b/itemwidget.ui new file mode 100644 index 0000000..f5234e4 --- /dev/null +++ b/itemwidget.ui @@ -0,0 +1,142 @@ + + + ItemWidget + + + + 0 + 0 + 257 + 30 + + + + + 0 + 0 + + + + + 0 + 30 + + + + + 16777215 + 70 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Supprimer + + + + + + + + diff --git a/mainwindow.cpp b/mainwindow.cpp index 399a3f2..3b6100b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,7 +1,6 @@ #include #include #include "mainwindow.h" -#include "ui_mainwindow.h" #include "MaxRectsBinPack.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -51,3 +50,21 @@ MainWindow::~MainWindow() { svgWidget->load(process().toLocal8Bit()); } + + void MainWindow::on_pbAddTrou_clicked(bool) + { + ItemWidget *iw = new ItemWidget(this); + + trous.append(iw); + + widgetTrous->layout()->addWidget(iw); + } + + void MainWindow::on_pbAddPave_clicked(bool) + { + ItemWidget *iw = new ItemWidget(this); + + paves.append(iw); + + widgetPaves->layout()->addWidget(iw); + } diff --git a/mainwindow.h b/mainwindow.h index 8eb8598..5c084dc 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -4,6 +4,7 @@ #include #include #include "ui_mainwindow.h" +#include "itemwidget.h" class MainWindow : public QMainWindow, private Ui::MainWindow { @@ -13,11 +14,15 @@ class MainWindow : public QMainWindow, private Ui::MainWindow ~MainWindow(); private: QSvgWidget *svgWidget; + QListtrous; + QListpaves; QString process(void); private slots: void on_txtLargeur_textChanged(); void on_txtHauteur_textChanged(); + void on_pbAddTrou_clicked(bool checked = false); + void on_pbAddPave_clicked(bool checked = false); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index f6e80a0..b64e3fd 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,7 +6,7 @@ 0 0 - 645 + 996 673 @@ -17,7 +17,7 @@ - MainWindow + Pavage @@ -233,10 +233,102 @@ - + + + + 0 + 0 + + + + + 257 + 0 + + + + + 257 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 513 + + + + + + - + + + + 0 + 0 + + + + + 257 + 0 + + + + + 257 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 513 + + + + + + From a95ec8ec40706bcfa29feb052fea6013c0ddeeca Mon Sep 17 00:00:00 2001 From: Corentin Le Bail Date: Tue, 28 Oct 2025 16:08:47 +0100 Subject: [PATCH 13/13] =?UTF-8?q?Pav=C3=A9s=20+=20trous?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RectangleBinPack.pro | 15 +- itemwidget.cpp | 6 - itemwidget.h | 14 -- mainwindow.cpp | 41 ++++-- mainwindow.h | 13 +- mainwindow.ui | 252 ++++++++++++++++----------------- pavewidget.cpp | 11 ++ pavewidget.h | 18 +++ itemwidget.ui => pavewidget.ui | 38 ++--- trouwidget.cpp | 11 ++ trouwidget.h | 18 +++ trouwidget.ui | 164 +++++++++++++++++++++ 12 files changed, 414 insertions(+), 187 deletions(-) delete mode 100644 itemwidget.cpp delete mode 100644 itemwidget.h create mode 100644 pavewidget.cpp create mode 100644 pavewidget.h rename itemwidget.ui => pavewidget.ui (80%) create mode 100644 trouwidget.cpp create mode 100644 trouwidget.h create mode 100644 trouwidget.ui diff --git a/RectangleBinPack.pro b/RectangleBinPack.pro index b840cf0..fd3e7cf 100644 --- a/RectangleBinPack.pro +++ b/RectangleBinPack.pro @@ -21,18 +21,21 @@ CONFIG += c++11 # Input HEADERS += MaxRectsBinPack.h \ Rect.h \ - itemwidget.h \ - mainwindow.h + mainwindow.h \ + pavewidget.h \ + trouwidget.h SOURCES += MaxRectsBinPack.cpp \ Rect.cpp \ # MaxRectsBinPackTest/BinPack.cpp \ - itemwidget.cpp \ main.cpp \ - mainwindow.cpp + mainwindow.cpp \ + pavewidget.cpp \ + trouwidget.cpp FORMS += \ - itemwidget.ui \ - mainwindow.ui + mainwindow.ui \ + pavewidget.ui \ + trouwidget.ui RESOURCES += \ RectangleBinPack.qrc diff --git a/itemwidget.cpp b/itemwidget.cpp deleted file mode 100644 index 6a2811d..0000000 --- a/itemwidget.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "itemwidget.h" - -ItemWidget::ItemWidget(QWidget *parent) : QWidget(parent) -{ - setupUi(this); -} diff --git a/itemwidget.h b/itemwidget.h deleted file mode 100644 index 883f181..0000000 --- a/itemwidget.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ITEMWIDGET_H -#define ITEMWIDGET_H - -#include -#include "ui_itemwidget.h" - -class ItemWidget : public QWidget, private Ui::ItemWidget -{ - Q_OBJECT -public: - ItemWidget(QWidget *parent); -}; - -#endif // ITEMWIDGET_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 3b6100b..6a8b842 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -23,8 +23,8 @@ MainWindow::~MainWindow() QString MainWindow::process(void) { using namespace rbp; - int width = txtLargeur->toPlainText().toInt(); - int height = txtHauteur->toPlainText().toInt(); + int width = leWidth->text().toInt(); + int height = leHeight->text().toInt(); QString svg = ""; svg += ""; @@ -39,32 +39,51 @@ MainWindow::~MainWindow() return svg; } - void MainWindow::on_txtLargeur_textChanged() + void MainWindow::on_leWidth_textChanged() { QString svg = process(); svgWidget->load(svg.toLocal8Bit()); - qDebug() << "test" << svg; } - void MainWindow::on_txtHauteur_textChanged() + void MainWindow::on_leHeight_textChanged() { svgWidget->load(process().toLocal8Bit()); } void MainWindow::on_pbAddTrou_clicked(bool) { - ItemWidget *iw = new ItemWidget(this); + TrouWidget *tw = new TrouWidget(this); + connect(tw, SIGNAL(deleted(TrouWidget *)), this, SLOT(trouDeleted(TrouWidget *))); - trous.append(iw); + dynamic_cast(scrollTrous->widget()->layout())->insertWidget(trous.count(), tw); + trous.append(tw); - widgetTrous->layout()->addWidget(iw); + process(); } void MainWindow::on_pbAddPave_clicked(bool) { - ItemWidget *iw = new ItemWidget(this); + PaveWidget *pw = new PaveWidget(this); + connect(pw, SIGNAL(deleted(PaveWidget *)), this, SLOT(paveDeleted(PaveWidget *))); - paves.append(iw); + dynamic_cast(scrollPaves->widget()->layout())->insertWidget(paves.count(), pw); + paves.append(pw); - widgetPaves->layout()->addWidget(iw); + process(); + } + + void MainWindow::trouDeleted(TrouWidget *item) + { + dynamic_cast(scrollTrous->widget()->layout())->removeWidget(item); + trous.removeOne(item); + + delete item; + } + + void MainWindow::paveDeleted(PaveWidget *item) + { + dynamic_cast(scrollPaves->widget()->layout())->removeWidget(item); + paves.removeOne(item); + + delete item; } diff --git a/mainwindow.h b/mainwindow.h index 5c084dc..2b91f87 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -4,7 +4,8 @@ #include #include #include "ui_mainwindow.h" -#include "itemwidget.h" +#include "pavewidget.h" +#include "trouwidget.h" class MainWindow : public QMainWindow, private Ui::MainWindow { @@ -14,15 +15,17 @@ class MainWindow : public QMainWindow, private Ui::MainWindow ~MainWindow(); private: QSvgWidget *svgWidget; - QListtrous; - QListpaves; + QListtrous; + QListpaves; QString process(void); private slots: - void on_txtLargeur_textChanged(); - void on_txtHauteur_textChanged(); + void on_leWidth_textChanged(); + void on_leHeight_textChanged(); void on_pbAddTrou_clicked(bool checked = false); void on_pbAddPave_clicked(bool checked = false); + void trouDeleted(TrouWidget *item); + void paveDeleted(PaveWidget *item); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index b64e3fd..e6b7c7f 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -33,36 +33,8 @@ Paramètres - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - - - - - 0 - 0 - - + + 0 @@ -70,7 +42,7 @@ - Largeur + Hauteur @@ -137,6 +109,25 @@ + + + + + 0 + 0 + + + + + 0 + 25 + + + + Largeur + + + @@ -197,139 +188,148 @@ - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - - - - - 0 - 25 - - - - Hauteur - - - - + - + 0 0 - 257 + 320 0 - 257 + 320 16777215 - - - 0 - - - 0 - - - 0 - - - 0 + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 306 + 519 + - - - - Qt::Vertical - - - - 20 - 513 - - - - - + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - + - + 0 0 - 257 + 280 0 - 257 + 280 16777215 - - - 0 - - - 0 - - - 0 - - - 0 + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 266 + 519 + - - - - Qt::Vertical - - - - 20 - 513 - - - - - + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 516 + + + + + + + + + + + + diff --git a/pavewidget.cpp b/pavewidget.cpp new file mode 100644 index 0000000..e49f2b5 --- /dev/null +++ b/pavewidget.cpp @@ -0,0 +1,11 @@ +#include "pavewidget.h" + +PaveWidget::PaveWidget(QWidget *parent) : QWidget(parent) +{ + setupUi(this); +} + +void PaveWidget::on_pbDelete_clicked(bool) +{ + emit(deleted(this)); +} diff --git a/pavewidget.h b/pavewidget.h new file mode 100644 index 0000000..1e8fa02 --- /dev/null +++ b/pavewidget.h @@ -0,0 +1,18 @@ +#ifndef PAVEWIDGET_H +#define PAVEWIDGET_H + +#include +#include "ui_pavewidget.h" + +class PaveWidget : public QWidget, private Ui::PaveWidget +{ + Q_OBJECT +public: + PaveWidget(QWidget *parent); +signals: + void deleted(PaveWidget *item); +private slots: + void on_pbDelete_clicked(bool checked = false); +}; + +#endif // PAVEWIDGET_H diff --git a/itemwidget.ui b/pavewidget.ui similarity index 80% rename from itemwidget.ui rename to pavewidget.ui index f5234e4..294871f 100644 --- a/itemwidget.ui +++ b/pavewidget.ui @@ -1,31 +1,31 @@ - ItemWidget - + PaveWidget + 0 0 - 257 + 260 30 - + 0 0 - 0 + 260 30 - 16777215 - 70 + 260 + 30 @@ -45,9 +45,9 @@ 0 - + - + 0 0 @@ -55,19 +55,19 @@ 50 - 0 + 30 50 - 16777215 + 30 - + 0 @@ -77,19 +77,19 @@ 50 - 0 + 30 50 - 16777215 + 30 - + 0 @@ -99,13 +99,13 @@ 50 - 0 + 30 50 - 16777215 + 30 @@ -121,13 +121,13 @@ 80 - 0 + 22 80 - 16777215 + 22 diff --git a/trouwidget.cpp b/trouwidget.cpp new file mode 100644 index 0000000..d1c264e --- /dev/null +++ b/trouwidget.cpp @@ -0,0 +1,11 @@ +#include "trouwidget.h" + +TrouWidget::TrouWidget(QWidget *parent) : QWidget(parent) +{ + setupUi(this); +} + +void TrouWidget::on_pbDelete_clicked(bool) +{ + emit(deleted(this)); +} diff --git a/trouwidget.h b/trouwidget.h new file mode 100644 index 0000000..a39b594 --- /dev/null +++ b/trouwidget.h @@ -0,0 +1,18 @@ +#ifndef TROUWIDGET_H +#define TROUWIDGET_H + +#include +#include "ui_trouwidget.h" + +class TrouWidget : public QWidget, private Ui::TrouWidget +{ + Q_OBJECT +public: + TrouWidget(QWidget *parent); +signals: + void deleted(TrouWidget *item); +private slots: + void on_pbDelete_clicked(bool checked = false); +}; + +#endif // TROUWIDGET_H diff --git a/trouwidget.ui b/trouwidget.ui new file mode 100644 index 0000000..f6fe253 --- /dev/null +++ b/trouwidget.ui @@ -0,0 +1,164 @@ + + + TrouWidget + + + + 0 + 0 + 304 + 30 + + + + + 0 + 0 + + + + + 304 + 30 + + + + + 304 + 30 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 50 + 30 + + + + + 50 + 30 + + + + + + + + + 0 + 0 + + + + + 50 + 30 + + + + + 50 + 30 + + + + + + + + + 0 + 0 + + + + + 50 + 30 + + + + + 50 + 30 + + + + + + + + + 0 + 0 + + + + + 50 + 30 + + + + + 50 + 30 + + + + + + + + + 0 + 0 + + + + + 80 + 22 + + + + + 80 + 22 + + + + Supprimer + + + + + + + +