Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 84 additions & 3 deletions libnest2d_js/libnest2d_js.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
#include <emscripten/val.h>
#include <libnest2d/backends/clipper/geometries.hpp>
#include <libnest2d/placers/bottomleftplacer.hpp>
#include <libnest2d/selections/firstfit.hpp>
#include <iostream>

using namespace emscripten;
using namespace libnest2d;
using namespace placers;
using namespace selections;

// Type aliases to match Python bindings
using Point = PointImpl;
Expand All @@ -32,6 +35,39 @@ EMSCRIPTEN_DECLARE_VAL_TYPE(ItemList);
EMSCRIPTEN_DECLARE_VAL_TYPE(DoubleList);
EMSCRIPTEN_DECLARE_VAL_TYPE(ResultAndItem);

void testFunction() {
std::vector<Item> input;

auto volume = libnest2d::Box(1000, 1000);

std::vector<Item> items;

items.emplace_back(libnest2d::Item({
Point(5, 10),
Point(10, 10),
Point(0, 0)
}));
auto& long_thin_triangle = items.back();

items.emplace_back(libnest2d::Item({
Point(0, 10),
Point(10, 10),
Point(10, 0),
Point(0, 0),
}));
auto& square = items.back();

items.emplace_back(libnest2d::Item({
Point(5, 10),
Point(10, 0),
Point(0, 0)
}));
auto& equilateral_triangle = items.back();

auto num_bins = libnest2d::nest(items, volume);
std::cout << "Number of bins used: " << num_bins << std::endl;
}

// Helper function to convert a Point to a JavaScript object
emscripten::val pointToJSObject(const Point& point) {
emscripten::val obj = emscripten::val::object();
Expand Down Expand Up @@ -73,23 +109,66 @@ std::vector<Point> jsArrayToPointVector(const emscripten::val& jsArray) {

// Wrapper function for nest() to handle JavaScript arrays
ResultAndItem nestWrapper(ItemList jsItems, const Box& bin) {
std::cerr << "[DEBUG] nestWrapper called" << std::endl;

// Convert JavaScript array to std::vector<Item>
std::vector<Item> items;
auto length = jsItems["length"].as<unsigned>();
items.reserve(length);

std::cerr << "[DEBUG] Processing " << length << " items" << std::endl;
std::cerr << "[DEBUG] Bin dimensions: " << bin.width() << "x" << bin.height() << std::endl;

for (unsigned i = 0; i < length; i++) {
Item item = jsItems[i].as<Item>();
items.push_back(item);
std::cerr << "[DEBUG] Item " << i << " - area: " << item.area()
<< ", vertexCount: " << item.vertexCount()
<< ", binId: " << item.binId() << std::endl;
}

size_t result = nest(items, bin);
std::cerr << "[DEBUG] Calling nest() function" << std::endl;

size_t result = 0;
try {
// Use the _Nester class directly with explicit strategies
using Placer = BottomLeftPlacer;
using Selector = FirstFitSelection;

std::cerr << "[DEBUG] Creating nester with BottomLeftPlacer and FirstFitSelection" << std::endl;
_Nester<Placer, Selector> nester(bin);

std::cerr << "[DEBUG] Executing nesting..." << std::endl;
result = nester.execute(items.begin(), items.end());

std::cerr << "[DEBUG] Nesting completed, result: " << result << std::endl;

// Get the pack result
auto& packResult = nester.lastResult();
std::cerr << "[DEBUG] Pack result has " << packResult.size() << " bins" << std::endl;

} catch (const std::exception& e) {
std::cerr << "[ERROR] Exception during nesting: " << e.what() << std::endl;
result = 0;
} catch (...) {
std::cerr << "[ERROR] Unknown exception during nesting" << std::endl;
result = 0;
}

std::cerr << "[DEBUG] nest() returned: " << result << std::endl;

// Check the state of items after nesting
for (size_t i = 0; i < items.size(); ++i) {
std::cerr << "[DEBUG] After nest - Item " << i << " binId: " << items[i].binId()
<< ", translation: (" << getX(items[i].translation()) << ", " << getY(items[i].translation()) << ")" << std::endl;
}

// Copy results back to original JavaScript items
for (size_t i = 0; i < items.size() && i < length; ++i) {
jsItems.set(i, val(items[i]));
}

std::cerr << "[DEBUG] Returning result: " << result << std::endl;
return resultAndItems(result, jsItems);
}

Expand Down Expand Up @@ -196,7 +275,7 @@ EMSCRIPTEN_BINDINGS(libnest2d_js) {
.constructor<double>()
.function("toDegrees", &Radians::toDegrees);

// Degrees class for rotation angles
// Degrees class for rotation angles
class_<Degrees>("Degrees")
.constructor<double>()
.function("toRadians", &Degrees::toRadians);
Expand All @@ -208,6 +287,8 @@ EMSCRIPTEN_BINDINGS(libnest2d_js) {

// Main nest function
function("nest", &nestWrapper);

function("testFunction", &testFunction);
}

#endif // LIBNEST2D_JS_H
#endif // LIBNEST2D_JS_H
36 changes: 36 additions & 0 deletions tests/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1097,3 +1097,39 @@ TEST_CASE("MinAreaBBWithRotatingCalipers", "[Geometry]") {
REQUIRE(succ);
}
}

TEST_CASE("SimpleNesting", "[Nesting]") {
std::vector<Item> input;

auto volume = libnest2d::Box(1000, 1000);

std::vector<Item> items;

items.emplace_back(libnest2d::Item({
Point(5, 10),
Point(10, 10),
Point(0, 0)
}));
auto& long_thin_triangle = items.back();

items.emplace_back(libnest2d::Item({
Point(0, 10),
Point(10, 10),
Point(10, 0),
Point(0, 0),
}));
auto& square = items.back();

items.emplace_back(libnest2d::Item({
Point(5, 10),
Point(10, 0),
Point(0, 0)
}));
auto& equilateral_triangle = items.back();

auto num_bins = libnest2d::nest(items, volume);
REQUIRE(num_bins == 1u);
REQUIRE(long_thin_triangle.binId() != libnest2d::BIN_ID_UNSET);
REQUIRE(square.binId() != libnest2d::BIN_ID_UNSET);
REQUIRE(equilateral_triangle.binId() != libnest2d::BIN_ID_UNSET);
}
Loading