Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
314d021
Add JS/WASM bindings for libnest2d via Emscripten
saumyaj3 Sep 11, 2025
84f3e5a
Update GitHub Actions to use external conan-package workflow and rena…
saumyaj3 Sep 11, 2025
c5b57c5
Remove obsolete npm-package workflow and integrate it into conan-pack…
saumyaj3 Sep 11, 2025
e137273
Update JS/WASM bindings to reflect template-based types in libnest2d …
saumyaj3 Sep 11, 2025
f35dc68
Enable WASM support in conan-package workflow
saumyaj3 Sep 11, 2025
d713742
Update JS/WASM bindings to expose `nest` function and enhance `optimi…
saumyaj3 Sep 11, 2025
7959453
lambda-based override for `optimize_min` in libnest2d
saumyaj3 Sep 11, 2025
1a246cd
Define `user.libnest2d:libnest2d` configuration path in Conan package…
saumyaj3 Sep 11, 2025
8e58a72
Rename `conan-package.yml` to `package.yml` in GitHub Actions workflo…
saumyaj3 Sep 11, 2025
128e788
Add `deploy` method to copy binaries in Conan package setup and remov…
saumyaj3 Sep 11, 2025
04207bb
Update workflow name from `conan-package` to `package` in GitHub Actions
saumyaj3 Sep 11, 2025
ae13717
Update `deploy` method to copy `libnest2d*` binaries instead of `nest…
saumyaj3 Sep 12, 2025
6280a8c
Define build and package paths for Emscripten and update includedirs …
saumyaj3 Sep 12, 2025
52b1cf4
added author
saumyaj3 Sep 12, 2025
a73024a
Add `url` field and fix `deploy` method in `conanfile.py`.
saumyaj3 Sep 12, 2025
f5e7627
Fix typo in pattern for copying `libnest2d*` binaries in `deploy` met…
saumyaj3 Sep 12, 2025
c89bda5
Update `package` method to copy `libnest2d_js` binaries and fix workf…
saumyaj3 Sep 12, 2025
46ea06e
Fix incorrect source path for copying `libnest2d*` binaries in `packa…
saumyaj3 Sep 12, 2025
18870ed
Update Emscripten binary naming and adjust `package` method to copy `…
saumyaj3 Sep 12, 2025
b7524d7
Add `libnest2d_js` library with Emscripten bindings and update Conan …
saumyaj3 Sep 12, 2025
fe6d100
Refactor CMake build: replace in-line `libnest2d_js` setup with `add_…
saumyaj3 Sep 12, 2025
d774e42
Add Emscripten-specific build options and define backend macro in `li…
saumyaj3 Sep 12, 2025
41a7b7a
Update GitHub Actions to include `libnest2d_js` in package workflow
saumyaj3 Sep 12, 2025
89ecdd0
Link Clipper library in `libnest2d_js` and update include directories…
saumyaj3 Sep 12, 2025
19c9229
Add Boost library support in CMake configuration for libnest2d_js
saumyaj3 Sep 12, 2025
4adbb80
Add nlopt library support and update CMake configuration for libnest2…
saumyaj3 Sep 12, 2025
c87a785
Remove `nlopt` library linkage and adjust include directory in `libne…
saumyaj3 Sep 12, 2025
61085a9
Update `libnest2d_js` CMake configuration to require NLopt as a depen…
saumyaj3 Sep 12, 2025
fe0d37a
Change libnest2d_js from a static library to an executable in CMake c…
saumyaj3 Sep 12, 2025
4d25512
Enhance CMake configuration for libnest2d_js: add thread support for …
saumyaj3 Sep 12, 2025
0fe4589
Expose `IntPointVector` type in libnest2d_js bindings.
saumyaj3 Sep 12, 2025
eaf6407
Expose additional vector types (`IntPointVectorVector`, `PolygonVecto…
saumyaj3 Sep 12, 2025
9cb5d5e
Expose `PolygonItem` and `OptionalPolygonItem` types in `libnest2d_js…
saumyaj3 Sep 12, 2025
48665ea
Simplify `PolygonItem` binding in `libnest2d_js` by replacing explici…
saumyaj3 Sep 12, 2025
d09d723
Expose `Box` type in `libnest2d_js` bindings.
saumyaj3 Sep 12, 2025
fd2f888
Remove unused type bindings and simplify `libnest2d_js` exports.
saumyaj3 Sep 15, 2025
a989e19
Enhance `libnest2d_js` bindings: register vector and core types, add …
saumyaj3 Sep 15, 2025
f6f9007
Expand `libnest2d_js` bindings
saumyaj3 Sep 16, 2025
0321362
add type aliases for compatibility
saumyaj3 Sep 16, 2025
045e48c
remove unused helper, add `Radians` conversions, and improve functio…
saumyaj3 Sep 16, 2025
f15dd2a
Refine function bindings with `select_overload`,
saumyaj3 Sep 16, 2025
a151ef2
removing `select_overload` where unnecessary.
saumyaj3 Sep 16, 2025
cb7442d
update constructor signature, remove unused transformation-related fu…
saumyaj3 Sep 16, 2025
2e4aaa5
Add type aliases for core entities in `libnest2d_js`, adjust `Item` b…
saumyaj3 Sep 16, 2025
39c9f2b
update cmakelist
saumyaj3 Sep 16, 2025
25c8838
Remove redundant helper functions and simplify `rotations` field bind…
saumyaj3 Sep 16, 2025
49703ac
Refine `libnest2d_js` bindings: fix getter/setter types, replace prop…
saumyaj3 Sep 16, 2025
992315a
Refine `libnest2d_js` bindings: add `Polygon`, `Radians`, and `Degree…
saumyaj3 Sep 16, 2025
b68e11d
update `nestWrapper` return type to `size_t`, add `Circle` class, en…
saumyaj3 Sep 16, 2025
6136549
remove `BottomLeftConfig`, add new `Item` functions (`isFixed`, `isD…
saumyaj3 Sep 16, 2025
9d8a1da
Format CMakeLists.txt: Adjust indentation and add `-sWASM_BIGINT=1` l…
saumyaj3 Sep 16, 2025
2263255
Refine `libnest2d_js` bindings: introduce `ItemArray` type, optimize …
saumyaj3 Sep 16, 2025
623e940
update `ItemArray` to `emscripten::val`, enhance array validation and…
saumyaj3 Sep 16, 2025
a0885fb
remove redundant `const` qualifiers in `nestConfig` and `result` dec…
saumyaj3 Sep 16, 2025
5c96773
remove `ItemArray` type alias, update `nestWrapper` parameter to `ems…
saumyaj3 Sep 16, 2025
decbdab
Add *.wasm copying to Conan package outputs in `libnest2d_js`.
saumyaj3 Sep 17, 2025
dcf133a
Add Emscripten support in Conan package: handle JS/WASM assets and se…
saumyaj3 Sep 17, 2025
2060f17
Update Emscripten target link options and clean up Conan configuration
saumyaj3 Sep 17, 2025
18b22d2
Enhance package function to copy JS/WASM assets and define asset path…
saumyaj3 Sep 17, 2025
2c9a888
Refactor nestWrapper to accept ItemList and remove unused JS array co…
saumyaj3 Sep 17, 2025
71d0993
Add helper functions for Point conversion to JS objects and arrays
saumyaj3 Sep 17, 2025
83a504a
Refactor nestWrapper to simplify parameters and remove unused distanc…
saumyaj3 Sep 17, 2025
41b0616
Fix pointToJSObject to cast coordinates to long and add rotation/tran…
saumyaj3 Sep 18, 2025
0fb1807
Make `ItemList` a refference
casperlamboo Sep 18, 2025
4225699
make the reult of nest as bin and items
saumyaj3 Sep 18, 2025
336723f
Add spdlog dependency and update CMake configuration for JS bindings
saumyaj3 Sep 18, 2025
5e514f0
Add non-parallel execution for WASM builds in parallel.hpp
saumyaj3 Sep 19, 2025
02f49c4
Add tests functions
casperlamboo Sep 19, 2025
c146274
Don't allow rotations when calling the default nest arranger
casperlamboo Sep 19, 2025
4fc5eda
Update nestWrapper to include scale factor and adjust test cases for …
saumyaj3 Sep 19, 2025
2eb5d9d
Enable assertions in Emscripten build for debugging (CMake configurat…
saumyaj3 Sep 23, 2025
fe819ee
Conditionally copy JS/WASM artifacts and assets only when working wit…
saumyaj3 Sep 25, 2025
b23997e
Use point list over custom js type point list
casperlamboo Sep 29, 2025
a8d81f1
Adjust distance between the two models
saumyaj3 Oct 1, 2025
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: conan-package
name: package

on:
push:
Expand All @@ -12,8 +12,9 @@ on:
- 'conandata.yml'
- 'CMakeLists.txt'
- 'requirements.txt'
- '.github/workflows/conan-package.yml'
- '.github/workflows/package.yml'
- '.github/workflows/requirements*'
- 'libnest2d_js/**'
branches:
- main
- 'CURA-*'
Expand All @@ -25,4 +26,13 @@ on:
jobs:
conan-package:
uses: ultimaker/cura-workflows/.github/workflows/conan-package.yml@main
with:
platform_wasm: true
secrets: inherit

npm-package:
needs: [ conan-package ]
uses: ultimaker/cura-workflows/.github/workflows/npm-package.yml@main
with:
package_version_full: ${{ needs.conan-package.outputs.package_version_full }}
secrets: inherit
33 changes: 20 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ cmake_minimum_required(VERSION 3.20)
cmake_policy(SET CMP0091 NEW)
project(libnest2d)
find_package(standardprojectsettings REQUIRED)
find_package(spdlog REQUIRED)

option(BUILD_SHARED_LIBS "Build shared libs instead of static (applies for dependencies as well)" OFF)
option(HEADER_ONLY "If enabled static library will not be built." ON)
option(ENABLE_TESTING "Build with Google unittest" OFF)
option(WITH_JS_BINDINGS "Build JS/WASM bindings for npm package" OFF)
set(GEOMETRIES clipper CACHE STRING "Geometry backend, available options: 'clipper' (default), 'boost'")
set(OPTIMIZER nlopt CACHE STRING "Optimization backend, available options: 'nlopt' (default), 'optimlib'")
set(THREADING std CACHE STRING "Multithreading, available options: 'std' (default), 'tbb', 'omp', 'none'")
Expand Down Expand Up @@ -54,7 +56,7 @@ target_compile_definitions(project_options INTERFACE LIBNEST2D_GEOMETRIES_${GEOM

if("${OPTIMIZER}" STREQUAL "nlopt")
find_package(NLopt REQUIRED)
target_link_libraries(project_options INTERFACE NLopt::nlopt)
target_link_libraries(project_options INTERFACE NLopt::nlopt spdlog::spdlog)
list(APPEND nest2d_HDRS
include/libnest2d/optimizers/nlopt/simplex.hpp
include/libnest2d/optimizers/nlopt/subplex.hpp
Expand Down Expand Up @@ -89,17 +91,22 @@ endif()
target_compile_definitions(project_options INTERFACE LIBNEST2D_THREADING_${THREADING})

set(libnest2d_SRCS
src/libnest2d.cpp
)
src/libnest2d.cpp
)

if(WITH_JS_BINDINGS OR EMSCRIPTEN)
add_subdirectory(libnest2d_js)
endif()


if(HEADER_ONLY)
add_library(nest2d INTERFACE ${libnest2d_HDRS})
target_link_libraries(nest2d INTERFACE project_options)
target_include_directories(nest2d
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
else()
if(BUILD_SHARED_LIBS)
add_library(nest2d SHARED ${libnest2d_SRCS} ${libnest2d_HDRS})
Expand All @@ -111,12 +118,12 @@ else()
endif()
target_link_libraries(nest2d PUBLIC project_options)
target_include_directories(nest2d
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
)
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
)
endif()

if(ENABLE_TESTING)
Expand Down
41 changes: 39 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,33 @@

class Nest2DConan(ConanFile):
name = "nest2d"
author = "UltiMaker"
url = "https://github.com/Ultimaker/libnest2d"
description = "2D irregular bin packaging and nesting library written in modern C++"
topics = ("conan", "cura", "prusaslicer", "nesting", "c++", "bin packaging")
settings = "os", "compiler", "build_type", "arch"
build_policy = "missing"
package_type = "library"
implements = ["auto_header_only"]

python_requires = "npmpackage/[>=1.0.0]"
options = {
"shared": [True, False],
"fPIC": [True, False],
"header_only": [True, False],
"geometries": ["clipper", "boost"],
"optimizer": ["nlopt", "optimlib"],
"threading": ["std", "tbb", "omp", "none"]
"threading": ["std", "tbb", "omp", "none"],
"with_js_bindings": [True, False]
}
default_options = {
"shared": True,
"fPIC": True,
"header_only": False,
"geometries": "clipper",
"optimizer": "nlopt",
"threading": "std"
"threading": "std",
"with_js_bindings": False
}

def set_version(self):
Expand Down Expand Up @@ -67,12 +72,24 @@ def export_sources(self):
copy(self, "*", path.join(self.recipe_folder, "include"), path.join(self.export_sources_folder, "include"))
copy(self, "*", path.join(self.recipe_folder, "tests"), path.join(self.export_sources_folder, "tests"))
copy(self, "*", path.join(self.recipe_folder, "tools"), path.join(self.export_sources_folder, "tools"))
copy(self, "*", path.join(self.recipe_folder, "libnest2d_js"),
os.path.join(self.export_sources_folder, "libnest2d_js"))

def layout(self):
cmake_layout(self)
self.cpp.build.bin = []
self.cpp.build.bindirs = []
self.cpp.package.bindirs = ["bin"]
self.cpp.package.libs = ["nest2d"]
if self.settings.os == "Emscripten":
self.cpp.build.bin = ["libnest2d_js.js"]
self.cpp.package.bin = ["libnest2d_js.js"]
self.cpp.build.bindirs += ["libnest2d_js"]

self.cpp.package.includedirs = ["include"]

def requirements(self):
self.requires("spdlog/[>=1.14.1]", transitive_headers=True)
if self.options.geometries == "clipper":
self.requires("clipper/6.4.2@ultimaker/stable", transitive_headers=True)
if self.options.geometries == "boost" or self.options.geometries == "clipper":
Expand Down Expand Up @@ -133,6 +150,7 @@ def generate(self):
tc.variables["GEOMETRIES"] = self.options.geometries
tc.variables["OPTIMIZER"] = self.options.optimizer
tc.variables["THREADING"] = self.options.threading
tc.variables["WITH_JS_BINDINGS"] = self.options.get_safe("with_js_bindings", False)

tc.generate()

Expand All @@ -142,7 +160,19 @@ def build(self):
cmake.build()
cmake.install()

def deploy(self):
if self.settings.os == "Emscripten" or self.options.get_safe("with_js_bindings", False):
copy(self, "libnest2d_js*", src=os.path.join(self.package_folder, "bin"), dst=self.install_folder)
copy(self, "*", src=os.path.join(self.package_folder, "bin"), dst=self.install_folder)

def package(self):

if self.settings.os == "Emscripten" or self.options.get_safe("with_js_bindings", False):
copy(self, pattern="libnest2d_js*", src=os.path.join(self.build_folder, "libnest2d_js"),
dst=os.path.join(self.package_folder, "bin"))
copy(self, f"*.d.ts", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path = False)
copy(self, f"*.js", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path = False)
copy(self, f"*.wasm", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path = False)
packager = AutoPackager(self)
packager.run()

Expand All @@ -162,3 +192,10 @@ def package_info(self):
self.cpp_info.defines.append(f"LIBNEST2D_THREADING_{self.options.threading}")
if self.settings.os in ["Linux", "FreeBSD", "Macos"] and self.options.threading == "std":
self.cpp_info.system_libs.append("pthread")

# npm package json for Emscripten builds
if self.settings.os == "Emscripten" or self.options.get_safe("with_js_bindings", False):
self.python_requires["npmpackage"].module.conf_package_json(self)
# Expose the path to the JS/WASM assets for consumers
js_asset_path = os.path.join(self.package_folder, "bin")
self.conf_info.define("user.nest2d:js_path", js_asset_path)
10 changes: 8 additions & 2 deletions include/libnest2d/parallel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#endif

namespace libnest2d { namespace __parallel {

template<class It>
using TIteratorValue = typename std::iterator_traits<It>::value_type;

Expand Down Expand Up @@ -56,8 +56,14 @@ inline void enumerate(

for(TN fi = 0; fi < N; ++fi) rets[fi].wait();
#endif

#ifdef __EMSCRIPTEN__
// For WASM/Emscripten builds, always use non-parallel execution
// due to limited threading support in WebAssembly
for(TN n = 0; n < N; n++) fn(*(from + n), n);
#endif
}

}}

#endif //LIBNEST2D_PARALLEL_HPP
#endif //LIBNEST2D_PARALLEL_HPP
64 changes: 64 additions & 0 deletions libnest2d_js/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
message(STATUS "Building for Emscripten")
cmake_minimum_required(VERSION 3.10)
project(libnest2d_js)

add_executable(libnest2d_js libnest2d_js.cpp)

if (NOT CMAKE_CXX_PLATFORM_ID STREQUAL "emscripten")
use_threads(libnest2d_js)
endif ()

# Emscripten bindings
set_target_properties(libnest2d_js PROPERTIES LINK_FLAGS "--bind")

# Find Clipper library (required for polyclipping/clipper.hpp)
find_package(clipper REQUIRED)

# Find Boost library (required for boost/geometry.hpp)
find_package(Boost REQUIRED)

find_package(NLopt REQUIRED)

# Include directories
target_include_directories(libnest2d_js PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}/../src
${clipper_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)

# Link Boost headers
target_link_libraries(libnest2d_js PRIVATE Boost::headers)

# Link Clipper library
target_link_libraries(libnest2d_js PRIVATE clipper::clipper)

target_link_libraries(libnest2d_js PRIVATE NLopt::nlopt)

target_link_libraries(libnest2d_js PUBLIC spdlog::spdlog)
# Define backend macro for Emscripten
target_compile_definitions(libnest2d_js PRIVATE LIBNEST2D_GEOMETRIES_clipper)
target_compile_definitions(libnest2d_js PRIVATE LIBNEST2D_OPTIMIZER_nlopt)

# Emscripten-specific options (optional, but recommended)
target_link_options(libnest2d_js
PUBLIC
"SHELL:-s USE_ES6_IMPORT_META=1"
"SHELL:-s FORCE_FILESYSTEM=1"
"SHELL:-s EXPORT_NAME=libnest2d_js"
"SHELL:-s MODULARIZE=1"
"SHELL:-s EXPORT_ES6=1"
"SHELL:-s SINGLE_FILE=1"
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=0"
"SHELL:--bind"
"SHELL:-l embind"
"SHELL: --emit-tsd libnest2d_js.d.ts"
"SHELL:-sWASM_BIGINT=1"
"SHELL:-sASSERTIONS=1"

)

# If you want to enable debug options, add them conditionally:
# $<$<CONFIG:Debug>:SHELL:-g3>
# $<$<CONFIG:Debug>:SHELL:-gsource-map>
Loading
Loading