Skip to content

Commit 4aea725

Browse files
Merge pull request #1 from petrasvestartas/nanobind
ShapeOp + COMPAS fully working version on Ubuntu.
2 parents cab6203 + b4aaa19 commit 4aea725

File tree

1,845 files changed

+431251
-121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,845 files changed

+431251
-121
lines changed

.github/__workflows/release.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ on:
99
- main
1010

1111
jobs:
12-
build:
12+
Build:
1313
if: "!contains(github.event.pull_request.labels.*.name, 'docs-only')"
1414
runs-on: ${{ matrix.os }}
1515
strategy:
1616
matrix:
1717
os: [ubuntu-latest, macos-latest, windows-latest]
18-
python: ["3.10", "3.11", "3.12"]
18+
python: ["3.10"]
1919

2020
steps:
2121
- uses: compas-dev/compas-actions.build@v4
2222
with:
23-
python: ${{ matrix.python }}
2423
invoke_lint: true
25-
invoke_test: true
24+
use_conda: true
25+
check_import: true
26+
python: ${{ matrix.python }}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
branches:
66
- main
77
tags:
8-
- 'v*'
8+
- "v*"
99
pull_request:
1010
branches:
1111
- main
@@ -17,3 +17,5 @@ jobs:
1717
- uses: compas-dev/compas-actions.docs@v4
1818
with:
1919
github_token: ${{ secrets.GITHUB_TOKEN }}
20+
use_conda: true
21+
doc_url: https://github.com/blockresearchgroup/compas_shapeop

.github/workflows/release.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*" # Runs only when a version tag (e.g., v1.0.0) is pushed.
7+
8+
jobs:
9+
create_release:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
14+
- name: Create GitHub Release
15+
id: create_release
16+
uses: actions/create-release@v1
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
with:
20+
tag_name: ${{ github.ref }}
21+
release_name: Release ${{ github.ref }}
22+
draft: false
23+
prerelease: false
24+
25+
build_wheels:
26+
name: Build wheels on ${{ matrix.platform }}
27+
runs-on: ${{ matrix.os }}
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
include:
32+
- os: ubuntu-latest
33+
platform: manylinux
34+
- os: macos-latest
35+
platform: mac
36+
- os: windows-latest
37+
platform: windows
38+
39+
steps:
40+
- uses: actions/checkout@v4
41+
with:
42+
fetch-depth: 0
43+
44+
- name: Install cibuildwheel
45+
run: pipx install cibuildwheel==2.23.1
46+
47+
- name: Build wheels
48+
run: cibuildwheel --output-dir wheelhouse .
49+
50+
- uses: actions/upload-artifact@v4
51+
with:
52+
name: wheels-${{ matrix.platform }}
53+
path: wheelhouse/*.whl
54+
55+
build_sdist:
56+
name: Build source distribution
57+
runs-on: ubuntu-latest
58+
steps:
59+
- uses: actions/checkout@v4
60+
with:
61+
fetch-depth: 0
62+
63+
- name: Build SDist
64+
run: pipx run build --sdist
65+
66+
- uses: actions/upload-artifact@v4
67+
with:
68+
name: sdist
69+
path: dist/*.tar.gz
70+
71+
publish:
72+
needs: [build_sdist, build_wheels]
73+
runs-on: ubuntu-latest
74+
environment:
75+
name: pypi
76+
url: https://pypi.org/project/compas_shapeop
77+
permissions:
78+
id-token: write # Required for PyPI trusted publishing
79+
80+
steps:
81+
- uses: actions/download-artifact@v4
82+
with:
83+
pattern: wheels-*
84+
path: dist
85+
merge-multiple: true
86+
87+
- uses: actions/download-artifact@v4
88+
with:
89+
name: sdist
90+
path: dist
91+
92+
- name: List files before upload
93+
run: ls -lhR dist
94+
95+
- name: Publish to PyPI
96+
uses: pypa/gh-action-pypi-publish@release/v1

.gitignore

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ __pycache__/
1010
.Python
1111
env/
1212
build/
13+
_build/
14+
**/build/
1315
develop-eggs/
1416
dist/
1517
downloads/
@@ -123,7 +125,7 @@ temp/**
123125

124126
src/.build/**
125127

126-
data/
128+
# data/
127129

128130
*.tar.gz
129131

@@ -137,4 +139,13 @@ docs/api/generated/
137139

138140
scripts/
139141

140-
.ruff_cache
142+
.ruff_cache
143+
144+
# ------------------------------------------------------------------------------
145+
# cmakelists
146+
# ------------------------------------------------------------------------------
147+
148+
# External dependencies
149+
# ext/**
150+
# external/
151+
# **/external/

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
### Removed
1515

16+
17+
## [0.0.1] 2025-04-01
18+
19+
### Added
20+
21+
* Nanobind for ShapeOp solver.
22+
* Currently constraints: `ShapeOp::ClosenessConstraint`, `ShapeOp::EdgeStrainConstraint`, `ShapeOp::GravityForce`, `ShapeOp::ClosenessConstraint`, `ShapeOp::NormalForce`.
23+
24+
### Changed
25+
26+
### Removed

CMakeLists.txt

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
cmake_minimum_required(VERSION 3.15...3.26)
2+
project(compas_shapeop LANGUAGES CXX)
3+
4+
# ==============================================================================
5+
# Build configuration
6+
# ==============================================================================
7+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
8+
set(CMAKE_CXX_STANDARD 20)
9+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
10+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
11+
12+
# Build options
13+
option(ENABLE_PRECOMPILED_HEADERS "Enable precompiled headers" ON)
14+
option(FAST_COMPILE "Optimize for faster compilation (-O0) vs execution (-O3)" OFF)
15+
option(USE_OPENMP "Enable OpenMP support for parallel processing" ON)
16+
17+
# Apply optimization flags
18+
if(FAST_COMPILE)
19+
add_compile_options(-O0)
20+
else()
21+
add_compile_options(-O3)
22+
endif()
23+
24+
# ==============================================================================
25+
# Dependencies
26+
# ==============================================================================
27+
28+
# Setup Eigen
29+
set(EIGEN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/eigen)
30+
find_package(Eigen3 QUIET)
31+
if(NOT Eigen3_FOUND)
32+
# Download Eigen if not found
33+
if(NOT EXISTS ${EIGEN_INCLUDE_DIR})
34+
message(STATUS "Downloading Eigen...")
35+
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external)
36+
file(DOWNLOAD
37+
https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip
38+
${CMAKE_CURRENT_SOURCE_DIR}/eigen.zip
39+
SHOW_PROGRESS
40+
)
41+
execute_process(
42+
COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_CURRENT_SOURCE_DIR}/eigen.zip
43+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external
44+
)
45+
execute_process(
46+
COMMAND ${CMAKE_COMMAND} -E rename
47+
${CMAKE_CURRENT_SOURCE_DIR}/external/eigen-3.4.0
48+
${EIGEN_INCLUDE_DIR}
49+
)
50+
file(REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/eigen.zip)
51+
endif()
52+
set(EIGEN3_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR})
53+
endif()
54+
55+
# Find Python and nanobind
56+
find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module)
57+
find_package(nanobind CONFIG REQUIRED)
58+
find_package(Threads REQUIRED)
59+
60+
# Setup OpenMP
61+
if(USE_OPENMP)
62+
find_package(OpenMP QUIET)
63+
if(OpenMP_CXX_FOUND)
64+
message(STATUS "OpenMP found - enabling parallel processing")
65+
add_definitions(-DSHAPEOP_OPENMP)
66+
else()
67+
message(STATUS "OpenMP not found - parallel processing disabled")
68+
endif()
69+
endif()
70+
71+
# ==============================================================================
72+
# ShapeOp library
73+
# ==============================================================================
74+
75+
# Set directories
76+
set(SHAPEOP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/shapeop)
77+
set(SHAPEOP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
78+
79+
# ShapeOp library with core and custom components
80+
add_library(shapeop STATIC
81+
# Core ShapeOp files
82+
${SHAPEOP_SRC_DIR}/Constraint.cpp
83+
${SHAPEOP_SRC_DIR}/Force.cpp
84+
${SHAPEOP_SRC_DIR}/LSSolver.cpp
85+
${SHAPEOP_SRC_DIR}/Solver.cpp
86+
# Custom constraints/forces
87+
${SHAPEOP_SRC_DIR}/custom_constraints/normalforce.cpp
88+
)
89+
90+
target_include_directories(shapeop PUBLIC
91+
${CMAKE_CURRENT_SOURCE_DIR}/src
92+
${EIGEN3_INCLUDE_DIRS}
93+
)
94+
95+
target_compile_options(shapeop PRIVATE -fPIC)
96+
if(OpenMP_CXX_FOUND)
97+
target_compile_options(shapeop PUBLIC ${OpenMP_CXX_FLAGS})
98+
target_link_libraries(shapeop PUBLIC ${OpenMP_CXX_LIBRARIES})
99+
endif()
100+
101+
# ==============================================================================
102+
# Precompiled headers
103+
# ==============================================================================
104+
105+
if(ENABLE_PRECOMPILED_HEADERS)
106+
add_library(compas_pch INTERFACE)
107+
target_precompile_headers(compas_pch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/compas.h)
108+
target_include_directories(compas_pch INTERFACE
109+
${CMAKE_CURRENT_SOURCE_DIR}/src
110+
${EIGEN3_INCLUDE_DIRS}
111+
${nanobind_INCLUDE_DIRS}
112+
)
113+
endif()
114+
115+
# ==============================================================================
116+
# Python module
117+
# ==============================================================================
118+
119+
# Add the Solver Python module
120+
nanobind_add_module(
121+
_shapeop
122+
STABLE_ABI
123+
NB_STATIC
124+
src/shapeop.cpp
125+
)
126+
127+
target_include_directories(_shapeop PRIVATE
128+
${CMAKE_CURRENT_SOURCE_DIR}/src
129+
${EIGEN3_INCLUDE_DIRS}
130+
${nanobind_INCLUDE_DIRS}
131+
)
132+
133+
target_link_libraries(_shapeop PRIVATE shapeop)
134+
if(ENABLE_PRECOMPILED_HEADERS)
135+
target_link_libraries(_shapeop PRIVATE compas_pch)
136+
endif()
137+
138+
install(TARGETS _shapeop LIBRARY DESTINATION compas_shapeop)
139+
140+
# ==============================================================================
141+
# Summary
142+
# ==============================================================================
143+
144+
message(STATUS "============= Build Configuration =============")
145+
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
146+
message(STATUS "C++ Standard: C++${CMAKE_CXX_STANDARD}")
147+
message(STATUS "Optimization: ${FAST_COMPILE} (O0 if ON, O3 if OFF)")
148+
message(STATUS "Precompiled Headers: ${ENABLE_PRECOMPILED_HEADERS}")
149+
message(STATUS "=============================================")

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ To install the latest version for development, do:
1515
```bash
1616
git clone https://github.com/blockresearchgroup/compas_shapeop.git
1717
cd compas_shapeop
18-
pip install -e ".[dev]"
18+
pip install --no-build-isolation -ve . -Ceditable.rebuild=true
1919
```
2020

2121
## Documentation
@@ -25,4 +25,4 @@ please check out the online documentation here: [COMPAS ShapeOp docs](https://bl
2525

2626
## Issue Tracker
2727

28-
If you find a bug or if you have a problem with running the code, please file an issue on the [Issue Tracker](https://github.com/blockresearchgroup/compas_shapeop/issues).
28+
If you find a bug or if you have a problem with running the code, please file an issue on the [Issue Tracker](https://github.com/blockresearchgroup/compas_shapeop/issues).

0 commit comments

Comments
 (0)