{"id":17933950,"url":"https://github.com/papooch/wasteoptimiser","last_synced_at":"2025-03-24T07:31:14.278Z","repository":{"id":41272876,"uuid":"222034891","full_name":"Papooch/WasteOptimiser","owner":"Papooch","description":"Irregular shape nesting software for waste material optimisation in 2D machining.","archived":false,"fork":false,"pushed_at":"2025-03-04T23:31:25.000Z","size":2144,"stargazers_count":34,"open_issues_count":0,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-19T03:05:48.527Z","etag":null,"topics":["algorithms","binpacking","cnc","optimization","python","thesis"],"latest_commit_sha":null,"homepage":"https://dspace.vutbr.cz/handle/11012/191851","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Papooch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-16T02:22:03.000Z","updated_at":"2025-03-14T06:47:56.000Z","dependencies_parsed_at":"2023-01-21T08:46:44.689Z","dependency_job_id":null,"html_url":"https://github.com/Papooch/WasteOptimiser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Papooch%2FWasteOptimiser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Papooch%2FWasteOptimiser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Papooch%2FWasteOptimiser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Papooch%2FWasteOptimiser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Papooch","download_url":"https://codeload.github.com/Papooch/WasteOptimiser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245227360,"owners_count":20580861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","binpacking","cnc","optimization","python","thesis"],"created_at":"2024-10-28T21:42:28.591Z","updated_at":"2025-03-24T07:31:14.269Z","avatar_url":"https://github.com/Papooch.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WasteOptimiser\nThis project is a part of my Master's thesis: [__Software for efficient use of material in 2D machining__](https://dspace.vutbr.cz/handle/11012/191851).\n\nIt implements a shape nesting algorithm and can be used as a GUI app, or you can use the underlying API to leverage the algorithms themselves.\n\n-------\n## Prerequisites\nrequired dependencies: \n* Shapely library\n* numpy\n* pybind11 (!required as of now, even if not using libnfporb, TODO: make optional)\n\noptional dependencies:\n* PyQt5, and therefore:\n    * matplotlib\n* libnfporb_interface (c++), and therefore:\n    * Boost library (\u003c= 1.65),\n    * cmake\n    * pybind11\n\nWhile the app itself is written in Python, a part of it relies on the [libnfporb library by Amir Hassan (kalabala)](https://github.com/kallaballa/libnfporb/) written in c++, which must be built before (see Building libnfporb), but it can be used without it, as there is a faster but way less accurate fallback algorithm in place.\n\n\u003e License notice: `libnfporb` is published under the GPL-3.0 license, so while the code in this repository is MIT-licensed, when used with `libnpforb`, it inherits the GPL-3.0 license as well.\n\nThe program also requires you to install the Shapely Python library, which is available through PyPi, but still has to be [built from source](https://github.com/Toblerity/Shapely), or the binary can be downloaded from [here (Windows only)](https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely) and installed manually. If you use Anaconda, it can be also easily installed using `conda install shapely`.\n\n------------\n## Building libnfporb\nYou will need the [Boost library](https://www.boost.org/) (or at least [Boost.geometry](https://www.boost.org/doc/libs/1_65_1/libs/geometry/doc/html/index.html) that it includes) IMPORTANT! Make sure to install version \u003c= 1.65, as there is a bug (or a fix) in Boost.geometry that breaks the libnfporb library's functionality.\n\nIf you decide to go with the recommended way, you will need to define two system environment variables: `%PYTHONPATH%` and `%BOOST_ROOT%`. \n\n### Visual Studio (Windows)\nFor Windows users, there is an auto build script provided inside `wasteoptimiser/nfp_interface`. It requires you to have cmake and Visual Studio 2017/2019 (for other versions, a slight modification of the script is needed).\n\nIn command prompt just `cd` to the `wasteoptimiser/nfp_interface` folder and then run it with `./build`. It should automatically load the Developer Command Prompt for Visual Studio. If it does not, you have to open it manually (Just start typing \"Developer C...\" into the search field and it should come right up, then proceed to launch the script from that). Then it will detect the Python version (64/32bit) and build the corresponding library for you.\n\nWhen you see no errors in the output, you can assume the library has been correctly built and a new file named libnfporb_interface.pyd will appear in the folder.\n\n### Other Platforms\nUse `cmake` to generate the project for your favourite compiler with the `CmakeLists.txt` file provided. In the `wasteoptimiser/nfp_interface` folder, run:\n``` cmd\nmkdir build\ncd build\ncmake .. -G \u003cyour favourite generator\u003e\n```\nThen, build it with your favourite compiler. After that, you need to place the build `libnfporb_interface.dll` into the `wasteoptimiser/nfp_interface` folder and rename it to `libnfporb_interface.pyd`.\n\n--------\n## Running the app\n### GUI\nIf you have installed PyQt5 and matplotlib, you can launch the GUI from the parent folder of `wasteoptimiser` with\n``` bash\n# by running the module as a script\npython -m wasteoptimiser\n# or simply by using the provided run script\npython run.py\n```\n\n![GUI](/screenshots/gui1.png)\n\nIn the _Input_ section, you can then browse to a folder with your g-codes, the parser will then try to parse each file as g-code and display the valid ones in the list. You can then select how much of each shape you want to place and whether to use the shape's convex hull as the reference (this is very much preferred for complicated shapes when using the \"Use NFP\" option in _Optimiser_, as it may take a loooong time to find a NFP for them).\n\nIn _Settings_ you can select the dimensions of your workspace, clearances between objects and the edge and the preferred location at which the shapes should be placed. \"Small holes first\" ensures that shapes are first tested for placement in the smallest regions found, before conforming to the \"Preferred location\" option.\n\nIn the actual _Workspace_, you can use the buttons \"Add\", \"Subtract\" and \"Remove\" to draw forbidden areas (i.e. holes) where the shapes cannot be placed.\n\nIn the _Optimiser_ section, you have the option to \"Use NFP\" (which leverages the libnfporb functionality) along with the number of rotations to test for. By disabling this option a fallback algorithm that uses the smallest enclosing circle will be used.\\\nThe \"Local optimisation\" which tries to place the shape as closely to other shapes by minimising the open area around it - it can achieve better results with irregular geometry, but slows down the process a bit.\\\nThe \"Start\" button starts the process of placing all the selected shapes, \"Stop\" can be used to stop it.\n\nThe top menu item \"Workspace\" lets you import and export created workspaces.\n\n### API\nIf you only need to use the API, import it in your Python script:\n``` Python\nfrom wasteoptimiser.api import api\n```\nThen, you can create an instance of it with\n``` Python\nmy_api = api.Api()\n```\nBy default, all the log messages will be printed to the console, if you want, you can use the built-in logger where you can select the logging and printing level (e.g. do not print debug messages and stuff).\n``` Python\nfrom wasteoptimiser.logger import logger\nmy_logger = logger.Logger(\"path/to/log\", ...) # for more options see API reference\n```\nand then supply it to the API constructor `my_api = api.Api(logger)`.\n\n\n### Quick start\n\nFirst, construct the shape dictionary using (note that an absolute path is needed as of now)\n\n``` Python\nmy_api.constructShapeDict(\"full/path/to/gcodes/\")\n```\n\nThis automatically parses the G-Codes from the given folder and constructs a dictionary of shapes in `my_api.shape_dict`. The keys are the file names and the values are dictionaries of the form `{'count': int, 'shape': shape, 'convex': bool}`, where `shape` is a list of polygons.\n\nThe count and whether to use the shape's convex hull (default) as its representation, can be set using\n\n``` Python\nmy_api.setShapeCount('shape.gcode', 3)\nmy_api.setShapeConvex('shape.gcode', False)\n```\n\nThe workspace with holes can be imported using\n```Python\nmy_api.loadWorkspace('path/to/workspace.json')\n```\n\nThe settings are currently a bit all over the place, but they can be set using\n\n``` Python\nmy_api.optimiser.hole_offset = 5  # minimual clearance between shapes and holes\nmy_api.optimiser.edge_offset = 5  # minimal clearance between shapes and boundary\nmy_api.optimiser.preffered_pos = 1 # 0-6 (top left, top right, bottom left..)\n\nmy_api.settings.use_nfp = True # False to use smallest enclosing circle method\nmy_api.settings.nfp_rotations = 4 # number of shape rotations for NFP construction\nmy_api.settings.local_optimisation = True\n```\n\nTo start the optimisation, run \n``` Python\nmy_api.placeAllSelectedShapes()\n```\nFor drawing purposes, the geometry can be extracted as list of polygons\n``` Python\nboard_polygon  = my_api.optimiser.getBoardShape()\nholes_polygons = my_api.optimiser.getHoles(htype='holes')\nshape_polygons = my_a0pi.optimiser.getHoles(htype='shapes')\n    # without htype returns both holes and shapes as holes\n```\nTo get the list of filenames, locations and angles for export, use\n```Python\nmy_api.optimiser.getShapeNamesPositions()\n```\n\n---------\n## API reference\n\nThe API is currently still under development and many things can change, please refer to the docstrings of functions in `wasteoptimiser/api/api.py`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpapooch%2Fwasteoptimiser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpapooch%2Fwasteoptimiser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpapooch%2Fwasteoptimiser/lists"}