Skip to content

Commit

Permalink
Add boost files to enable python interoperability.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pelle Jacobs authored and Pelle Jacobs committed Dec 2, 2016
1 parent 379cb25 commit 12f1f56
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
bin
*.so
*.dylib
49 changes: 49 additions & 0 deletions Jamroot
@@ -0,0 +1,49 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

import python ;

if ! [ python.configured ]
{
ECHO "notice: no Python configured in user-config.jam" ;
ECHO "notice: will use default configuration" ;
using python ;
}

# Specify the path to the Boost project. If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost
: /path/to/boost/installation ;

# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.
project
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;

# Declare the three extension modules. You can specify multiple
# source files after the colon separated by spaces.
python-extension boost_binpacker_ext : boost_binpacker.cpp MaxRectsBinPack.cpp GuillotineBinPack.cpp ShelfBinPack.cpp SkylineBinPack.cpp Rect.cpp ;

# Put the extension and Boost.Python DLL in the current directory, so
# that running script by hand works.
install convenient_copy
: boost_binpacker_ext
: <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
<location>.
;

# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
local rule run-test ( test-name : sources + )
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
}

# Declare test targets
run-test boost_binpacker : boost_binpacker_ext boost_binpacker.py ;
7 changes: 5 additions & 2 deletions Readme.txt
Expand Up @@ -8,8 +8,11 @@ For more information, read the paper, which is also contained as a .pdf in this

The repository contains a build solution for Visual C++ 2010. It is configured to build a single static
library of the algorithms. The preferred method of embedding these algorithms into your own code is to
simply copy the code files into your own project and build them along your own build system. There are
no build scripts for other platforms provided.
simply copy the code files into your own project and build them along your own build system.

To use these algorithms in Python, you can make use Boost.Python to enable interoperability between the C++ algorithms and your Python code.

There are no build scripts for other platforms provided.

For more information, see a series of blog posts at

Expand Down
99 changes: 99 additions & 0 deletions boost_binpacker.cpp
@@ -0,0 +1,99 @@
#include <boost/python.hpp>
#include <vector>
#include "./MaxRectsBinPack.h"
#include "./GuillotineBinPack.h"
#include "./ShelfBinPack.h"
#include "./SkylineBinPack.h"
#include <cstdio>

using namespace boost::python;

BOOST_PYTHON_MODULE(boost_binpacker_ext)
{
using namespace rbp;

class_<Rect>("Rect")
.add_property("x", &Rect::x)
.add_property("y", &Rect::y)
.add_property("width", &Rect::width)
.add_property("height", &Rect::height)
;

// MaxRectBinpack
enum_<MaxRectsBinPack::FreeRectChoiceHeuristic>("MaxRectsFreeRectChoiceHeuristic")
.value("RectBestShortSideFit", MaxRectsBinPack::RectBestShortSideFit)
.value("RectBestLongSideFit", MaxRectsBinPack::RectBestLongSideFit)
.value("RectBestAreaFit", MaxRectsBinPack::RectBestAreaFit)
.value("RectBottomLeftRule", MaxRectsBinPack::RectBottomLeftRule)
.value("RectContactPointRule", MaxRectsBinPack::RectContactPointRule)
;

Rect (MaxRectsBinPack::*MaxRectsInsert)(int, int, MaxRectsBinPack::FreeRectChoiceHeuristic) = &MaxRectsBinPack::Insert;

class_<MaxRectsBinPack>("MaxRectsBinPack", init<int, int>())
.def(init<>())
.def("init", &MaxRectsBinPack::Init)
.def("insert", MaxRectsInsert)
.def("occupancy", &MaxRectsBinPack::Occupancy)
;

// GuillotineBinPack
enum_<GuillotineBinPack::FreeRectChoiceHeuristic>("GuillotineFreeRectChoiceHeuristic")
.value("RectBestAreaFit", GuillotineBinPack::RectBestAreaFit)
.value("RectBestShortSideFit", GuillotineBinPack::RectBestShortSideFit)
.value("RectBestLongSideFit", GuillotineBinPack::RectBestLongSideFit)
.value("RectWorstAreaFit", GuillotineBinPack::RectWorstAreaFit)
.value("RectWorstShortSideFit", GuillotineBinPack::RectWorstShortSideFit)
.value("RectWorstLongSideFit", GuillotineBinPack::RectWorstLongSideFit)
;
enum_<GuillotineBinPack::GuillotineSplitHeuristic>("GuillotineSplitHeuristic")
.value("SplitShorterLeftoverAxis", GuillotineBinPack::SplitShorterLeftoverAxis)
.value("SplitLongerLeftoverAxis", GuillotineBinPack::SplitLongerLeftoverAxis)
.value("SplitMinimizeArea", GuillotineBinPack::SplitMinimizeArea)
.value("SplitMaximizeArea", GuillotineBinPack::SplitMaximizeArea)
.value("SplitShorterAxis", GuillotineBinPack::SplitShorterAxis)
.value("SplitLongerAxis", GuillotineBinPack::SplitLongerAxis)
;

Rect (GuillotineBinPack::*GuillotineInsert)(int, int, bool, GuillotineBinPack::FreeRectChoiceHeuristic, GuillotineBinPack::GuillotineSplitHeuristic) = &GuillotineBinPack::Insert;

class_<GuillotineBinPack>("GuillotineBinPack", init<int, int>())
.def(init<>())
.def("init", &GuillotineBinPack::Init)
.def("insert", GuillotineInsert)
.def("occupancy", &GuillotineBinPack::Occupancy)
;

// ShelfBinPack
enum_<ShelfBinPack::ShelfChoiceHeuristic>("ShelfChoiceHeuristic")
.value("ShelfNextFit", ShelfBinPack::ShelfNextFit)
.value("ShelfFirstFit", ShelfBinPack::ShelfFirstFit)
.value("ShelfBestAreaFit", ShelfBinPack::ShelfBestAreaFit)
.value("ShelfWorstAreaFit", ShelfBinPack::ShelfWorstAreaFit)
.value("ShelfBestHeightFit", ShelfBinPack::ShelfBestHeightFit)
.value("ShelfBestWidthFit", ShelfBinPack::ShelfBestWidthFit)
.value("ShelfWorstWidthFit", ShelfBinPack::ShelfWorstWidthFit)
;

class_<ShelfBinPack>("ShelfBinPack", init<int, int, bool>())
.def(init<>())
.def("init", &ShelfBinPack::Init)
.def("insert", &ShelfBinPack::Insert)
.def("occupancy", &ShelfBinPack::Occupancy)
;

// SkylineBinPack
enum_<SkylineBinPack::LevelChoiceHeuristic>("SkylineLevelChoiceHeuristic")
.value("LevelBottomLeft", SkylineBinPack::LevelBottomLeft)
.value("LevelMinWasteFit", SkylineBinPack::LevelMinWasteFit)
;

Rect (SkylineBinPack::*SkylineInsert)(int, int, SkylineBinPack::LevelChoiceHeuristic) = &SkylineBinPack::Insert;

class_<SkylineBinPack>("SkylineBinPack", init<int, int, bool>())
.def(init<>())
.def("init", &SkylineBinPack::Init)
.def("insert", SkylineInsert)
.def("occupancy", &SkylineBinPack::Occupancy)
;
}
22 changes: 22 additions & 0 deletions boost_binpacker.py
@@ -0,0 +1,22 @@
import boost_binpacker_ext

max_rect_packer = boost_binpacker_ext.MaxRectsBinPack(100, 100)
second_packer = boost_binpacker_ext.MaxRectsBinPack()
second_packer.init(100, 200)

heuristic = boost_binpacker_ext.MaxRectsFreeRectChoiceHeuristic.RectBestShortSideFit
print max_rect_packer.insert(20, 20, heuristic).height # '20': fits
print max_rect_packer.insert(200, 20, heuristic).height # '0': does not fit

guillotine_packer = boost_binpacker_ext.GuillotineBinPack(100, 100)
heuristic = boost_binpacker_ext.GuillotineFreeRectChoiceHeuristic.RectBestShortSideFit
splitmethod = boost_binpacker_ext.GuillotineSplitHeuristic.SplitMinimizeArea
print guillotine_packer.insert(20, 20, True, heuristic, splitmethod).height # '20': fits

shelf_packer = boost_binpacker_ext.ShelfBinPack(100, 100, True)
heuristic = boost_binpacker_ext.ShelfChoiceHeuristic.ShelfNextFit
print shelf_packer.insert(20, 20, heuristic).height # '20': fits

skyline_packer = boost_binpacker_ext.SkylineBinPack(100, 100, True)
heuristic = boost_binpacker_ext.SkylineLevelChoiceHeuristic.LevelBottomLeft
print skyline_packer.insert(20, 20, heuristic).height # '20': fits

0 comments on commit 12f1f56

Please sign in to comment.