Code Monkey home page Code Monkey logo

libnest2d's Introduction

Notice

This library was developed as part of the PrusaSlicer project.

You can find the original version here. This repository is a continuation of the original project (effectively a fork) that contains backported stable changes and is open to experimental new features.

Introduction

Libnest2D is a library and framework for the 2D bin packaging problem. Inspired from the SVGNest Javascript library the project is built from scratch in C++11. The library is written with a policy that it should be usable out of the box with a very simple interface but has to be customizable to the very core as well. The algorithms are defined in a header only fashion with templated geometry types. These geometries can have custom or already existing implementation to avoid copying or having unnecessary dependencies.

A default backend is provided if the user of the library just wants to use it out of the box without additional integration. This backend is reasonably fast and robust, being built on top of boost geometry and the polyclipping library. Usage of this default backend implies the dependency on these packages but its header only as well.

This software is still not feature complete and lacks a throughout documentation and some essential algorithms as well. At this stage it works well for rectangles and convex closed polygons without considering holes and concavities.

The no fit polygon based placer module combined with the first fit selection strategy is now used in the PrusaSlicer application's arrangement feature. It uses local optimization techniques to find the best placement of each new item based on some features of the arrangement.

Integration

Using libnest2d in its current state implies the following dependencies:

Integrating the library can be done in at least two ways. Use whichever suits your project the most.

  1. The project source tree can be used as a subdirectory (or git submodule) in any other CMake based C++ project by using add_subdirectory() command in the parent level CMakeLists.txt file. This method ensures that the appropriate dependencies are detected or (optionally) downloaded and built if not found. This means that by default, if Clipper and NLopt are not installed, they will be downloaded into the CMake binary directory, built there and linked with your project if RP_ENABLE_DOWNLOADING is ON. Just add the target_link_library(<your_target> libnest2d_headeronly) line to your CMake build script. You can also compile the library with the selected dependencies into a static or shared library. To do this just disable the LIBNEST2D_HEADER_ONLY option in the CMake config.

  2. Copying source files directly into a target project: The library can be header only and it is enough to just copy the content of the include directory or specify the location of these headers to the compiler. Be aware that in this case you are on your own regarding the geometry backend and optimizer selection. To keep things simple just define LIBNEST2D_GEOMETRIES_clipper and LIBNEST2D_OPTIMIZER_nlopt before including libnest2d.hpp. You will also need to link to these libraries manually.

  3. (Recommended) Install the library after it was configured and "built" using cmake. An example how to do this in a bash command line in the checked out source dir:

    mkdir build
    cd build
    cmake .. -DLIBNEST2D_HEADER_ONLY=OFF -DCMAKE_INSTALL_PREFIX=<installdir>
    cmake --build . --target install

    Substitute <installdir> with your preferred location. If you don't have the required dependencies installed, you can add -DRP_ENABLE_DOWNLOADING=ON and make it download and build everything in the configure step. The built dependencies will be shared or static depending on BUILD_SHARED_LIBS. You can also specify the install location of the dependencies by setting RP_INSTALL_PREFIX variable. Alternatively you can (and should) install the dependencies first e.g. on Ubuntu:

    sudo apt install libboost-dev libpolyclipping-dev libnlopt-cxx-dev
    

Please note that the clipper backend still uses some algorithms from boost::geometry (header only). Later releases will probably get rid of the direct dependency.

The goal is to provide more geometry backends (e.g. boost only) and optimizer engines (e.g. optimlib) in the future. This would make it possible to use the already available dependencies in your project tree without including new ones.

Example

A simple example may be the best way to demonstrate the usage of the library.

#include <iostream>
#include <string>

// Here we include the libnest2d library
#include <libnest2d/libnest2d.hpp>

int main(int argc, const char* argv[]) {
    using namespace libnest2d;

    // Example polygons 
    std::vector<Item> input1(23,
    {
        {-5000000, 8954050},
        {5000000, 8954050},
        {5000000, -45949},
        {4972609, -568550},
        {3500000, -8954050},
        {-3500000, -8954050},
        {-4972609, -568550},
        {-5000000, -45949},
        {-5000000, 8954050},
    });
    std::vector<Item> input2(15,
    {
       {-11750000, 13057900},
       {-9807860, 15000000},
       {4392139, 24000000},
       {11750000, 24000000},
       {11750000, -24000000},
       {4392139, -24000000},
       {-9807860, -15000000},
       {-11750000, -13057900},
       {-11750000, 13057900},
    });

    std::vector<Item> input;
    input.insert(input.end(), input1.begin(), input1.end());
    input.insert(input.end(), input2.begin(), input2.end());

    // Perform the nesting with a box shaped bin
    size_t bins = nest(input, Box(150000000, 150000000));

    // Retrieve resulting geometries
    for(Item& r : input) {
        auto polygon = r.transformedShape();
        // render polygon...
    }

    return EXIT_SUCCESS;
}

It is worth to note that the type of the polygon carried by the Item objects is the type defined as a polygon by the geometry backend. In the example we use the clipper backend and clipper works with integer coordinates.

Of course it is possible to configure the nesting in every possible way. The nest function can take placer and selection algorithms as template arguments and their configuration as runtime arguments. It is also possible to pass a progress indication functor and a stop condition predicate to control the nesting process. For more details see the libnest2d.h header file.

Example output

Alt text

Screenshot from Slic3r PE

For the record, Slic3r PE version 2.0 is now known as PrusaSlicer 2.0.

Alt text

References

libnest2d's People

Contributors

atimmer avatar karl-nilsson avatar manch1n avatar megidd avatar stegarev avatar tamasmeszaros avatar thopiekar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libnest2d's Issues

Unit test failure when cross-building i686

When cross-building i686, the unit test fails.

I'll try to build in a i686 vm.

Here's the output

[0/1] Running tests...
Test project /builddir/libnest2d-0.4/build
    Start 1: libnest2d_tests
1/1 Test #1: libnest2d_tests ..................***Failed    0.35 sec

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tests_clipper_nlopt is a Catch v2.13.4 host application.
Run with -? for options

-------------------------------------------------------------------------------
pointOnPolygonContour
-------------------------------------------------------------------------------
../tests/test.cpp:976
...............................................................................

../tests/test.cpp:993: FAILED:
  REQUIRE( shapelike::touches(v, input.transformedShape()) )
with expansion:
  false

===============================================================================
test cases:   19 |   18 passed | 1 failed
assertions: 1746 | 1745 passed | 1 failed



0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.35 sec

The following tests FAILED:
          1 - libnest2d_tests (Failed)
Errors while running CTest
FAILED: CMakeFiles/test.util 

@tamasmeszaros

@tamasmeszaros
Yes, I am asking about angles carried by Item objects. Using Item objects transformed shape, the output is written in SVG file format. The angle returned by the Item object and the placement of SVG object-orientation is different. Let's say, Item object angle is 180 degree ( I'm converting radians to a degree) and it is placed in SVG as 0 degrees and vice-versa. Please provide your comments on it.

Originally posted by @subhashreehari in #3 (comment)

Non-convex Nesting

Hi,

In the readme it is mentioned that non-convex nesting will be added to the library. Do you have any estimation of when this is ready, if you are working on it? If you are not planning to work on it, do you have an estimation on what needs to be added to include the non-convex nesting?

libnest2d::GeometryException

Hello, I have just built libnest2d on Windows x64 and ran a test example from README.md without any changes and got a Microsoft C++ exception: libnest2d::GeometryException at memory location 0x000000642939AEF8. I get this exception both using ENABLE_DOWNLOADING option in CMake and building it on my own. I got this error in the method libnest2d::nest.

I would appreciate any help. Thank you.

Irregular bins

Do you have any plans to support fitting shapes to irregular bins?

You briefly mentioned it here:
#7

But, you didn't say if you plan to improve it or expand upon it.
I would also be interested in seeing something like this.
Thanks.

Sample Code does not work at all

I tried running the sample code from the main page but it did not move any polygons and moved all of them in separate bins. Can you advice?
2021-08-31_124245_2

optimizer.hpp Issue

When attempting to build my application I receive an error for the definition of the struct limits definition.

I have attempted multiple methods of building the library and including it but nothing has been able to get things to a point where I can use the nesting functionality.

Any assistance would be much appreciated.

This is the piece of code in the optimizer.hpp file which is giving the error:

image
image

Nest example coding questions

Hello,
I'm new to libnest2d and I have a couple of questions.

  • How can I configure the call to nest() to include a certain amount of spacing around my shapes?
  • Is it possible to configure nest() to not rotate my shapes? Just translation, no rotation?

I'm looking at this example:

// Perform the nesting with a box shaped bin
auto result = nest(input, Box(150000000, 150000000));

Another question, how can I tell if all shapes were nested successfully without overflowing?
How do I pick the optimal bounding box size that will fit them all?

How can I build up a shape item by adding vertex points to it, one at a time?
Item item; // how to add points to this class, one at a time?

Thanks.

running the simple example... no output

I just found libnest2d and it looks awesome. thank you for sharing your code!

I am running the simple example code and it does nothing.
I guess it is related to this part of the code.

    // Retrieve resulting geometries
    for(Item& r : input) {
        auto polygon = r.transformedShape();
        // render polygon...
    }

Could you please share the version of the example that renders the beautifull 38 green objects. I assume this was generated using your lib.

I managed to doctor in some code from your other example (very ugly compared to your output).
image

#include <iostream>
#include <string>
#include <fstream>
#include <cstdint>

#include <libnest2d/libnest2d.hpp>

#include "../tools/printer_parts.hpp"
#include "../tools/svgtools.hpp"

// Here we include the libnest2d library
#include <libnest2d/libnest2d.hpp>

int main(int argc, const char* argv[]) {
    using namespace libnest2d;

    // Example polygons 
    std::vector<Item> input1(23,
    {
        {-5000000, 8954050},
        {5000000, 8954050},
        {5000000, -45949},
        {4972609, -568550},
        {3500000, -8954050},
        {-3500000, -8954050},
        {-4972609, -568550},
        {-5000000, -45949},
        {-5000000, 8954050},
    });
    std::vector<Item> input2(15,
    {
       {-11750000, 13057900},
       {-9807860, 15000000},
       {4392139, 24000000},
       {11750000, 24000000},
       {11750000, -24000000},
       {4392139, -24000000},
       {-9807860, -15000000},
       {-11750000, -13057900},
       {-11750000, 13057900},
    });

    std::vector<Item> input;
    input.insert(input.end(), input1.begin(), input1.end());
    input.insert(input.end(), input2.begin(), input2.end());

    // Perform the nesting with a box shaped bin
    size_t bins = nest(input, Box(150000000, 150000000));

    PackGroup pgrp(bins);
    
    for (Item &itm : input) {
        if (itm.binId() >= 0) pgrp[size_t(itm.binId())].emplace_back(itm);
    }

    using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>;
    SVGWriter::Config conf;
    conf.mm_in_coord_units = mm();
    SVGWriter svgw(conf);
    svgw.setSize(Box(mm(250), mm(210)));
    svgw.writePackGroup(pgrp);
    svgw.save("out");


    return EXIT_SUCCESS;
}

Installation

Hi Tamas,

after building with
cmake . -DLIBNEST2D_HEADER_ONLY=OFF -DCMAKE_INSTALL_PREFIX=/usr
I've installed with cmake --build . --target install

Weirdly the files are getting installed to /libnest2d/usr/lib/libnest2d_clipper_nlopt.a
What do you you recommend for standard (LSB) installation paths?

System: ArchLinux + current gcc

CMake install Definition, missing archive directories

This is issue two of two I ran into while configuring.

CMake exited with an error to the effect of:

install TARGETS given no ARCHIVE DESTINATION

Very similar (same?) to what #28 addressed and #32 undid.

I'm not a CMake expert, so I don't know why it doesn't work as-is on my system.

CMake is version 3.7.2.

About:Optimizer unimplemented!

Hello, thank you very much for your open source program. But when I was running, there was an error, the error content is: C2338 Optimizer unimplemented! Can you help me with this error

Installation & Running Example

Hello,

I have limited experience in C++ I might be missing some simple points in the installation but face some problems in the process.

Is it possible for anyone can demonstrate the step-by-step installation process? Because when I try to follow the instructions it does not run.

To have a clear platform I use Ubuntu 22.04 distribution in the docker environment.

These are the commands that I use to create my environment:

FROM ubuntu:22.04
ENV PORT 80
EXPOSE $PORT

RUN apt-get update 
RUN apt install -y  wget curl ssh git

RUN apt-get install build-essential -y
RUN apt-get update && apt-get -y install cmake

WORKDIR /app
RUN git clone https://github.com/tamasmeszaros/libnest2d.git

WORKDIR /app/libnest2d/build

Then in /app/libnest2d/build/ directory I run the following commands.

cmake .. -DLIBNEST2D_HEADER_ONLY=OFF -DCMAKE_INSTALL_PREFIX=/usr -DRP_ENABLE_DOWNLOADING=ON

cmake --build . --target install

I do not get an error at this step.

Then, I copied files in /app/libnest2d/include/libnest2d/ directory to /app/libnest2d/examples/

In /app/libnest2d/examples directory I ran g++ -I. -std=c++17 main.cpp -o main command to compile. But I got the error copied below. Probably I am failing to import some required libraries but I don't know how to fix this.

In file included from main.cpp:6: /usr/include/libnest2d/libnest2d.hpp:25:15: error: 'PointImpl' does not name a type; did you mean 'PointType'? 25 | using Point = PointImpl; | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:26:22: error: 'PointImpl' was not declared in this scope; did you mean 'PointType'? 26 | using Coord = TCoord<PointImpl>; | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:26:31: error: template argument 1 is invalid 26 | using Coord = TCoord<PointImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:27:18: error: 'PointImpl' was not declared in this scope; did you mean 'PointType'? 27 | using Box = _Box<PointImpl>; | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:27:27: error: template argument 1 is invalid 27 | using Box = _Box<PointImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:28:26: error: 'PointImpl' was not declared in this scope; did you mean 'PointType'? 28 | using Segment = _Segment<PointImpl>; | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:28:35: error: template argument 1 is invalid 28 | using Segment = _Segment<PointImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:29:24: error: 'PointImpl' was not declared in this scope; did you mean 'PointType'? 29 | using Circle = _Circle<PointImpl>; | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:29:33: error: template argument 1 is invalid 29 | using Circle = _Circle<PointImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:30:34: error: 'PolygonImpl' was not declared in this scope 30 | using MultiPolygon = TMultiShape<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:30:45: error: template argument 1 is invalid 30 | using MultiPolygon = TMultiShape<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:32:20: error: 'PolygonImpl' was not declared in this scope 32 | using Item = _Item<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:32:31: error: template argument 1 is invalid 32 | using Item = _Item<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:33:30: error: 'PolygonImpl' was not declared in this scope 33 | using Rectangle = _Rectangle<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:33:41: error: template argument 1 is invalid 33 | using Rectangle = _Rectangle<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:34:30: error: 'PolygonImpl' was not declared in this scope 34 | using PackGroup = _PackGroup<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:34:41: error: template argument 1 is invalid 34 | using PackGroup = _PackGroup<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:36:54: error: 'PolygonImpl' was not declared in this scope 36 | using FillerSelection = selections::_FillerSelection<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:36:65: error: template argument 1 is invalid 36 | using FillerSelection = selections::_FillerSelection<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:37:58: error: 'PolygonImpl' was not declared in this scope 37 | using FirstFitSelection = selections::_FirstFitSelection<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:37:69: error: template argument 1 is invalid 37 | using FirstFitSelection = selections::_FirstFitSelection<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:38:49: error: 'PolygonImpl' was not declared in this scope 38 | using DJDHeuristic = selections::_DJDHeuristic<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:38:60: error: template argument 1 is invalid 38 | using DJDHeuristic = selections::_DJDHeuristic<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:41:46: error: 'PolygonImpl' was not declared in this scope 41 | using _NfpPlacer = placers::_NofitPolyPlacer<PolygonImpl, Bin>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:41:62: error: template argument 1 is invalid 41 | using _NfpPlacer = placers::_NofitPolyPlacer<PolygonImpl, Bin>; | ^ /usr/include/libnest2d/libnest2d.hpp:44:19: error: '_NfpPlacer' does not name a type 44 | using NfpPlacer = _NfpPlacer<Box>; | ^~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:47:53: error: 'PolygonImpl' was not declared in this scope 47 | using BottomLeftPlacer = placers::_BottomLeftPlacer<PolygonImpl>; | ^~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:47:64: error: template argument 1 is invalid 47 | using BottomLeftPlacer = placers::_BottomLeftPlacer<PolygonImpl>; | ^ /usr/include/libnest2d/libnest2d.hpp:60:25: error: 'NfpPlacer' does not name a type 60 | template<class Placer = NfpPlacer, class Selector = FirstFitSelection> | ^~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:60:53: error: 'FirstFitSelection' does not name a type 60 | template<class Placer = NfpPlacer, class Selector = FirstFitSelection> | ^~~~~~~~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:87:25: error: 'NfpPlacer' does not name a type 87 | template<class Placer = NfpPlacer, | ^~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:88:27: error: 'FirstFitSelection' does not name a type 88 | class Selector = FirstFitSelection, | ^~~~~~~~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:89:39: error: 'Item' was not declared in this scope 89 | class Iterator = std::vector<Item>::iterator> | ^~~~ /usr/include/libnest2d/libnest2d.hpp:89:43: error: template argument 1 is invalid 89 | class Iterator = std::vector<Item>::iterator> | ^ /usr/include/libnest2d/libnest2d.hpp:89:43: error: template argument 2 is invalid /usr/include/libnest2d/libnest2d.hpp:89:46: error: expected '>' before 'iterator' 89 | class Iterator = std::vector<Item>::iterator> | ^~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:92:18: error: 'Coord' has not been declared 92 | Coord dist = 0, | ^~~~~ /usr/include/libnest2d/libnest2d.hpp:121:25: error: 'NfpPlacer' does not name a type 121 | template<class Placer = NfpPlacer, | ^~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:122:27: error: 'FirstFitSelection' does not name a type 122 | class Selector = FirstFitSelection, | ^~~~~~~~~~~~~~~~~ /usr/include/libnest2d/libnest2d.hpp:123:40: error: 'Item' was not declared in this scope 123 | class Container = std::vector<Item>> | ^~~~ /usr/include/libnest2d/libnest2d.hpp:123:40: error: template argument 1 is invalid /usr/include/libnest2d/libnest2d.hpp:123:40: error: template argument 2 is invalid /usr/include/libnest2d/libnest2d.hpp:126:18: error: 'Coord' has not been declared 126 | Coord dist = 0, | ^~~~~ /usr/include/libnest2d/libnest2d.hpp:133:77: error: 'PointImpl' was not declared in this scope; did you mean 'PointType'? 133 | template<class T = double> enable_if_t<std::is_arithmetic<T>::value, TCoord<PointImpl>> mm(T val = T(1)) | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:133:77: error: template argument 1 is invalid /usr/include/libnest2d/libnest2d.hpp:133:86: error: template argument 2 is invalid 133 | template<class T = double> enable_if_t<std::is_arithmetic<T>::value, TCoord<PointImpl>> mm(T val = T(1)) | ^~ /usr/include/libnest2d/libnest2d.hpp: In function 'int libnest2d::mm(T)': /usr/include/libnest2d/libnest2d.hpp:135:19: error: 'PointImpl' was not declared in this scope; did you mean 'PointType'? 135 | return TCoord<PointImpl>(val * CoordType<PointImpl>::MM_IN_COORDS); | ^~~~~~~~~ | PointType /usr/include/libnest2d/libnest2d.hpp:135:28: error: template argument 1 is invalid 135 | return TCoord<PointImpl>(val * CoordType<PointImpl>::MM_IN_COORDS); | ^ In file included from main.cpp:8: ../tools/printer_parts.hpp: At global scope: ../tools/printer_parts.hpp:7:41: error: 'PathImpl' is not a member of 'libnest2d' 7 | using TestData = std::vector<libnest2d::PathImpl>; | ^~~~~~~~ ../tools/printer_parts.hpp:7:49: error: template argument 1 is invalid 7 | using TestData = std::vector<libnest2d::PathImpl>; | ^ ../tools/printer_parts.hpp:7:49: error: template argument 2 is invalid ../tools/printer_parts.hpp:8:43: error: 'PolygonImpl' is not a member of 'libnest2d' 8 | using TestDataEx = std::vector<libnest2d::PolygonImpl>; | ^~~~~~~~~~~ ../tools/printer_parts.hpp:8:54: error: template argument 1 is invalid 8 | using TestDataEx = std::vector<libnest2d::PolygonImpl>; | ^ ../tools/printer_parts.hpp:8:54: error: template argument 2 is invalid ../tools/printer_parts.hpp:10:14: error: 'TestData' does not name a type 10 | extern const TestData PRINTER_PART_POLYGONS; | ^~~~~~~~ ../tools/printer_parts.hpp:11:14: error: 'TestData' does not name a type 11 | extern const TestData STEGOSAUR_POLYGONS; | ^~~~~~~~ ../tools/printer_parts.hpp:12:14: error: 'TestDataEx' does not name a type 12 | extern const TestDataEx PRINTER_PART_POLYGONS_EX; | ^~~~~~~~~~ main.cpp:13:26: error: 'Item' was not declared in this scope; did you mean 'tm'? 13 | static const std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data) | ^~~~ | tm main.cpp:13:30: error: template argument 1 is invalid 13 | static const std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data) | ^ main.cpp:13:30: error: template argument 2 is invalid main.cpp:13:52: error: 'Item' was not declared in this scope; did you mean 'tm'? 13 | static const std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data) | ^~~~ | tm main.cpp:13:56: error: template argument 1 is invalid 13 | static const std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data) | ^ main.cpp:13:56: error: template argument 2 is invalid main.cpp:13:70: error: 'TestData' does not name a type 13 | static const std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data) | ^~~~~~~~ main.cpp: In function 'const int& _parts(int&, const int&)': main.cpp:15:12: error: request for member 'empty' in 'ret', which is of non-class type 'int' 15 | if(ret.empty()) { | ^~~~~ main.cpp:16:13: error: request for member 'reserve' in 'ret', which is of non-class type 'int' 16 | ret.reserve(data.size()); | ^~~~~~~ main.cpp:16:26: error: request for member 'size' in 'data', which is of non-class type 'const int' 16 | ret.reserve(data.size()); | ^~~~ main.cpp:17:25: error: 'begin' was not declared in this scope 17 | for(auto& inp : data) | ^~~~ main.cpp:17:25: note: suggested alternatives: In file included from /usr/include/c++/11/string:54, from /usr/include/c++/11/bits/locale_classes.h:40, from /usr/include/c++/11/bits/ios_base.h:41, from /usr/include/c++/11/ios:42, from /usr/include/c++/11/ostream:38, from /usr/include/c++/11/iostream:39, from main.cpp:1: /usr/include/c++/11/bits/range_access.h:108:37: note: 'std::begin' 108 | template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept; | ^~~~~ In file included from /usr/include/libnest2d/nester.hpp:11, from /usr/include/libnest2d/libnest2d.hpp:16, from main.cpp:6: /usr/include/libnest2d/geometry_traits.hpp:791:13: note: 'libnest2d::shapelike::begin' 791 | inline auto begin(S& sh) -> decltype(begin(sh, Tag<S>())) | ^~~~~ main.cpp:17:25: error: 'end' was not declared in this scope 17 | for(auto& inp : data) | ^~~~ main.cpp:17:25: note: suggested alternatives: In file included from /usr/include/c++/11/string:54, from /usr/include/c++/11/bits/locale_classes.h:40, from /usr/include/c++/11/bits/ios_base.h:41, from /usr/include/c++/11/ios:42, from /usr/include/c++/11/ostream:38, from /usr/include/c++/11/iostream:39, from main.cpp:1: /usr/include/c++/11/bits/range_access.h:110:37: note: 'std::end' 110 | template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept; | ^~~ In file included from /usr/include/libnest2d/nester.hpp:11, from /usr/include/libnest2d/libnest2d.hpp:16, from main.cpp:6: /usr/include/libnest2d/geometry_traits.hpp:817:13: note: 'libnest2d::shapelike::end' 817 | inline auto end(S& sh) -> decltype(begin(sh, Tag<S>())) | ^~~ main.cpp:18:17: error: request for member 'emplace_back' in 'ret', which is of non-class type 'int' 18 | ret.emplace_back(inp); | ^~~~~~~~~~~~ main.cpp: At global scope: main.cpp:24:26: error: 'Item' was not declared in this scope; did you mean 'tm'? 24 | static const std::vector<Item>& prusaParts() { | ^~~~ | tm main.cpp:24:30: error: template argument 1 is invalid 24 | static const std::vector<Item>& prusaParts() { | ^ main.cpp:24:30: error: template argument 2 is invalid main.cpp: In function 'const int& prusaParts()': main.cpp:25:24: error: 'Item' was not declared in this scope; did you mean 'tm'? 25 | static std::vector<Item> ret; | ^~~~ | tm main.cpp:25:28: error: template argument 1 is invalid 25 | static std::vector<Item> ret; | ^ main.cpp:25:28: error: template argument 2 is invalid main.cpp:26:24: error: 'PRINTER_PART_POLYGONS' was not declared in this scope 26 | return _parts(ret, PRINTER_PART_POLYGONS); | ^~~~~~~~~~~~~~~~~~~~~ main.cpp: In function 'int main()': main.cpp:31:17: error: 'Item' was not declared in this scope; did you mean 'tm'? 31 | std::vector<Item> input = prusaParts(); | ^~~~ | tm main.cpp:31:21: error: template argument 1 is invalid 31 | std::vector<Item> input = prusaParts(); | ^ main.cpp:31:21: error: template argument 2 is invalid main.cpp:33:42: error: 'Box' was not declared in this scope 33 | size_t bins = libnest2d::nest(input, Box(mm(250), mm(210)), 0, {}, | ^~~ main.cpp:38:5: error: 'PackGroup' was not declared in this scope 38 | PackGroup pgrp(bins); | ^~~~~~~~~ main.cpp:40:20: error: found ':' in nested-name-specifier, expected '::' 40 | for (Item &itm : input) { | ^ | :: main.cpp:40:16: error: 'itm' has not been declared 40 | for (Item &itm : input) { | ^~~ main.cpp:44:5: error: expected primary-expression before 'using' 44 | using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>; | ^~~~~ main.cpp:42:6: error: expected ';' before 'using' 42 | } | ^ | ; 43 | 44 | using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>; | ~~~~~ main.cpp:44:5: error: expected primary-expression before 'using' 44 | using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>; | ^~~~~ main.cpp:42:6: error: expected ')' before 'using' 42 | } | ^ | ) 43 | 44 | using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>; | ~~~~~ main.cpp:40:9: note: to match this '(' 40 | for (Item &itm : input) { | ^ main.cpp:44:49: error: 'PolygonImpl' was not declared in this scope 44 | using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>; | ^~~~~~~~~~~ main.cpp:44:60: error: template argument 1 is invalid 44 | using SVGWriter = libnest2d::svg::SVGWriter<PolygonImpl>; | ^ main.cpp:45:5: error: 'SVGWriter' has not been declared 45 | SVGWriter::Config conf; | ^~~~~~~~~ main.cpp:46:5: error: 'conf' was not declared in this scope; did you mean 'cosf'? 46 | conf.mm_in_coord_units = mm(); | ^~~~ | cosf main.cpp:47:5: error: 'SVGWriter' was not declared in this scope; did you mean 'libnest2d::svg::SVGWriter'? 47 | SVGWriter svgw(conf); | ^~~~~~~~~ | libnest2d::svg::SVGWriter In file included from main.cpp:9: ../tools/svgtools.hpp:13:7: note: 'libnest2d::svg::SVGWriter' declared here 13 | class SVGWriter { | ^~~~~~~~~ main.cpp:48:5: error: 'svgw' was not declared in this scope 48 | svgw.setSize(Box(mm(250), mm(210))); | ^~~~ main.cpp:49:25: error: 'pgrp' was not declared in this scope 49 | svgw.writePackGroup(pgrp);

So I failed to run the script. Any help or hint would be appreciated.

GeometryException

Hi, I'm trying to use libnest2d in a VS2019 project. I tried all your install variants, it compiles and links but when I run your simple example it always throws the GeometryException(GeomErr::MERGE); in geometries.hpp:328

Any idea why valid would be false there and how I can debug what's going wrong?

Interfacing libnest2d from Ruby

Hi @tamasmeszaros,

first of all thanks for the effort you put into libnest2d. It's actually something I was looking for for some time some.
I'm trying to wrap the library into a Ruby library as all my other application is in Ruby. For this I'm using https://github.com/jasonroelofs/rice as it supports class binding to C++ classes.
I managed to enable C++11 support but compiling fails with the following issue which is somehow caused by missing the Clipper library.

/usr/local/include/libnest2d/libnest2d.hpp:25:15: error: unknown type name 'PointImpl'
using Point = PointImpl;

Compiling the example provided by you works perfectly on my system using CMake. Could you provide an example on how to compile the example without CMake? That would be extremely helpful to mimic this in my makefiles.

Kind regards,
Patrick

error: unknown type name 'PointImpl'

Hi,

I am trying to get libnest2d up and running. But i have little issue going on.

I did a git clone, and copied to files into my qt project, then included the header.
#include <libnest2d/libnest2d.hpp>

Then i get a message:

error: unknown type name 'PointImpl'
error: use of undeclared identifier 'PolygonImpl'
error: no template named '_NfpPlacer'
error: unknown type name 'FirstFitSelection'

Are there file's missing?

I did install the 3 dependencies via command line. Is there a simple solution for this to repair?

Thanks in advange !

Error on building project on Windows - Cannot find CLIPPER LIBRARIES

Hi everyone!

I'm trying to build to build the project in my machine

Windows SDK version 10.0.19041.0 to target Windows 10.0.19043

C compiler identification is MSVC 19.32.31332.0

CXX compiler identification is MSVC 19.32.31332.0

I've already builded and installed Clipper. Also defined an envyroment variable CLIPPER_PATH

But when I try to build the project, I keep getting the following error:

-- Building for: Visual Studio 17 2022
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19043.
-- The C compiler identification is MSVC 19.32.31332.0
-- The CXX compiler identification is MSVC 19.32.31332.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.32.31326/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.32.31326/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
CMake Error at C:/Program Files/CMake/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Clipper library cannot be found.  Consider set CLIPPER_PATH environment
  variable (missing: CLIPPER_INCLUDE_DIRS CLIPPER_LIBRARIES)
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  cmake_modules/FindClipper.cmake:39 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  cmake_modules/RequirePackage.cmake:255 (find_package)
  include/libnest2d/backends/clipper/CMakeLists.txt:3 (require_package)


-- Configuring incomplete, errors occurred!
See also "C:/Users/tslima/Downloads/libnest2d-master/build/CMakeFiles/CMakeOutput.log".
See also "C:/Users/tslima/Downloads/libnest2d-master/build/CMakeFiles/CMakeError.log". 

ConfigPackageLocation is invalid for Windows

set(ConfigPackageLocation lib/cmake/${PROJECT_NAME})

This matches the the following template in
https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/ (Unix)

but this is not included in the default search paths for Windows. For Windows, either a different location should be set, or both Windows/Unix should use one of the common patterns (W/U):

<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/         (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/               (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U)

Multiple random results?

Hi,
For my use case, I would like to get multiple (hopefully significantly different) nestings of polygons in a certain space. Is this possible / documented somewhere?

Strange "starting_point" behavior in NfpPlacer

Hey, I'm trying to pack polygons into one or several tight square bins.
I had a problem that result contained a lot of free space in corners, an example is below.
image

I started experimenting with NfpPlacer settings and found that "starting_point" parameter contains the most suitable result but at the same time it has a very strange bug.
For some reason first few items are placed "wrong" and then a square zone starts that seems normal, example and code used below.
NestConfig<NfpPlacer> cfg;
cfg.placer_config.alignment = NfpPlacer::Config::Alignment::BOTTOM_LEFT;
cfg.placer_config.starting_point = NfpPlacer::Config::Alignment::BOTTOM_LEFT;
size_t bins = nest( items, Box(2048, 2048, { 1024 , 1024 }), 2 cfg, {} );
`
image

From very beginning of my adventure with this library, I tried BottomLeftPlacer algorithm, but it also leaves a lot of space in some cases, so I decided to try NfpPlacer and here I am

Change license to LGPL

I found your algorithm very intuitive and I would like to request on behalf of the Cura team if it is possible to change the license to LGPL so that we can use this library in Cura (which is also LGPL and cannot use AGPL-licensed libraries). Would that be possible?

Overlapping between irregular shapes shapes

Hi first of all thanks for the code.
I was using this and it works but it overlaps shapes. This happens when I use shapes with curves

I was hopping you can tell me where the problem is and can guide me how to solve it. or if can get a direction where the function is implemented to check the overlapping or anything else.

currently I am using its python version and if the issue is not solved I can move to cpp as well. So if you have solution in any implementation, you can give it
Would really appreciate your help
Thanks
output

Issue with Building Project and Executing Example

Hi,

I executed the "cmake ." "make" and "sudo make install" command.
A bunch of clipper and nlopt folders were created. Boost was already installed so no new folders for the boost source.

I then switched to the examples folder and executed the "g++ -I../include -I../clipper_library-src -I../nlopt-src main.cpp" command.

The consol outputs a bunch of errors:
"In file included from main.cpp:7:
../include/libnest2d.h:25:15: error: ‘PointImpl’ does not name a type; did you mean ‘PointType’?
using Point = PointImpl;
^~~~~~~~~
PointType
../include/libnest2d.h:26:22: error: ‘PointImpl’ was not declared in this scope
using Coord = TCoord;
"
Could someone help me in the execution of the example?

Any way to guarantee no overlaps?

Hi, thanks for this library. I'm trying to accomplish what feels like a basic problem but am getting overlaps in the resulting pack:

merged

My shapes are all clockwise and convex. The shape geometry data is attached (array of point arrays) and I'm packing them into a 2800x2800 box.

shapes.zip

I'm not sure what else I should be doing to avoid overlaps. It seems like there is plenty of space for that other piece to go, so not sure why it's being placed there.

Latest update

The October update appears to be broken. The provided examples don't work anymore. The code doesn't fully execute without crashing. Do you plan to address these issues? Thanks.

Rectangle deformed after shapelike::rotate called with Clipper backend

Calling transformedShape on a rectangle item sometimes gives deformed shape. After debugging I find out that shapelike::rotate introduces small error even with X90 degrees rotation.
Change
auto cosa = rads.cos();
auto sina = rads.sin();
into
auto cosa = int(rads.cos());
auto sina = int(rads.sin());

fix this but it won't work on arbitrary rotation.

I encountered this problem in NfpPlacer, but BottomLeftPlacer works ok.

Is it an issue?

CMake find boost cannot find headers component

This is one of two CMake issues I ran into.

While running CMake, I ran into an issue where in /include/libnest2d/backends/clipper/CMakeLists.txt the line:

require_package(Boost VERSION 1.58 REQUIRED COMPONENTS headers)

... caused the configuration to fail with error saying it could not locate boost_headers.

I fixed by changing the above to:

require_package(Boost VERSION 1.58)

CMake version is 3.7.2 (from about Jan. 2017). I'm assuming either older or newer CMakes don't have this issue, not entirely sure.

Can't get the library to work

I'm really having trouble to get this library to work. Followed all the instructions exactly as specified and i'm constantly getting the error
error: ‘PointImpl’ does not name a type; did you mean ‘PointType’
among a million other errors. I'm speculating it's because it can't link to geometry backend and optimizer but have no clue how to solve that. Any help would be appreciated!

A question of license

Out of curiosity,
Since this project was 'inspired' by SVGNest, why did you choose a GPL3 license instead of following the MIT license of the original project?

I've been looking for a better bin packing implementation for inclusion in FreeCAD but GPL3 is a non-starter for us.

The polygons are not arranged

Hello! Thanks for your library.
I generate a series of poygons at random, and the polygons can be drawn on a widget with Qt. I can also output the vertexes with the function Item::toString. However, the number of bins that used is always zero, The result polygons' postion also haven't been changed. What the mistake I make.
Here is the output
info1
Here is the polygons I generate
info2
Here is the screenshoot of code
info3

DRP_ENABLE_DOWNLOADING doesn't work well if BOOST_ROOT already exists in the environment

OS: Windows 10

When building libnest2d with the -DRP_ENABLE_DOWNLOADING=ON tag, if the BOOST_ROOT is set in the environment, CMake identifies it and does not download and build boost itself. As a result, when using libnest2d (in this case through pynest2d) libnest2d complains that it cannot find boost/geometry.hpp because it looks for the boost headers in its dependencies (libnest2d\build\dependencies), where CMake downloaded Clipper & NLopt but skipped boost.

The workaround of course is to temporarily set BOOST_ROOT in the cmd where this is being built, but it is not ideal since if you already have boost it will try to download and build it again.

Would it be possible to modify the build process to properly look in the BOOST_ROOT if it already exists in the environment?

crash: division by 0

Hello
I had a division by 0 in the geometry_traits_nfp:l285
the reason is that lsq1 is equal to 0 because e1.second() == e1.first()
I don't know if it's the intended behaviour or not.
I fixed it by replacing

            auto pcos1 = Ratio(lcos[0]) / lsq1 * sign * lcos[0];
            auto pcos2 = Ratio(lcos[1]) / lsq2 * sign * lcos[1];

by

            auto pcos1 = lsq1 != 0 ? Ratio(lcos[0]) / lsq1 * sign * lcos[0] : 1 * sign * lcos[0];
            auto pcos2 = lsq2 != 0 ? Ratio(lcos[1]) / lsq2 * sign * lcos[1] : 1 * sign * lcos[1];

Or maybe add an assert to test the input if it's the intended behaviour.

Running the example throws an error

Was looking for 2D bin packers and this was some of the best code I found by far! Thank you for sharing this. I just had a problem with running the example program from ReadMe or the one in the examples folder. I get the following message :

libc++abi.dylib: terminating with uncaught exception of type libnest2d::GeometryException: Error while merging geometries!

Do you have any idea what it could be? I'm working on macOS 10.14, and compiled a static library using CMake. I also have the libraries for all the dependencies including boost, clipper, NLopt in there.

@tamasmeszaros

@tamasmeszaros
I was able to get the rotation angle of the object in final output but there is a change in visual observance in .svg file and value of the angle.
which angle should i consider.
can you please share your valuable comment!

Thankyou!

Originally posted by @subhashreehari in #3 (comment)

Using Iregular shapes as bin

Hello! I'm currently working on a project where I need to nest some SVG shapes into an irregular container. I was wondering if it would be possible to use an SVG file as the bin and pass it to the nester as a shape? If that's not feasible, would it be possible to convert the SVG into Items and use them in the nesting process? It would be very helpful if you could provide an example or guide on how to accomplish this. Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.