Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Krande committed Jun 29, 2023
0 parents commit 5764ab0
Show file tree
Hide file tree
Showing 30 changed files with 1,584 additions and 0 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/ci-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: ci-nano-min

# bump 1
on:
push:
paths-ignore:
- README.md
- .gitignore

jobs:
build_test:
name: nano-min-${{ matrix.platform.name }}-${{ matrix.pyver.name }}
runs-on: ${{ matrix.platform.distver }}
defaults:
run:
shell: bash -l {0}
strategy:
fail-fast: false
matrix:
pyver: [
{ name: py311, distver: '3.11' },
]
platform: [
{ name: win, distver: windows-latest },
{ name: linux, distver: ubuntu-latest },
{ name: macOS, distver: macos-latest }
]
steps:
- uses: actions/checkout@v3
# Add ninja
- name: Install ninja
run: |
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo apt-get install ninja-build
elif [[ "$OSTYPE" == "darwin"* ]]; then
brew install ninja
elif [[ "$OSTYPE" == "win32" ]]; then
choco install ninja
fi
- uses: mamba-org/setup-micromamba@v1 # https://github.com/mamba-org/setup-micromamba
with:
channels: conda-forge
environment-file: environment.build.yml
create-args: >-
python=${{ matrix.pyver.distver }}
- name: build local packages
run: |
boa build conda --python ${{ matrix.pyver.distver }} -m ./conda/conda_build_config.yaml
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
.idea/
cmake-build*/
76 changes: 76 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
cmake_minimum_required(VERSION 3.20)

project(ada-cpp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)

if (CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Building for x64 architecture")
else ()
message(FATAL_ERROR "This project requires a 64-bit toolchain. Please update your toolchain arch to 'x86_amd64'")
endif ()

if (NOT CMAKE_BUILD_TYPE)
message(STATUS "Build type not set, defaulting to Release")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif ()
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})

find_package(Python 3 COMPONENTS Interpreter Development.Module REQUIRED)

# Create a list called ADA_CPP_SOURCES of all cpp files inside the src dir
set(ADA_CPP_SOURCES
src/adacpp.cpp
src/helpers/helpers.cpp
src/models/Models.cpp
src/exchange/step_writer.cpp
src/exchange/gltf_writer.cpp
src/geom/ShapeTesselator.cpp
src/geom/tess_helpers.cpp
)

# Find OpenCASCADE
find_package(OpenCASCADE REQUIRED)
if (OpenCASCADE_FOUND)
message(STATUS "OpenCASCADE version found: " ${OpenCASCADE_MAJOR_VERSION} ".." ${OpenCASCADE_MINOR_VERSION} ".." ${OpenCASCADE_MAINTENANCE_VERSION})
message(STATUS "OpenCASCADE include directory: " ${OpenCASCADE_INCLUDE_DIR})
message(STATUS "OpenCASCADE binary directory: " ${OpenCASCADE_BINARY_DIR})
message(STATUS "OpenCASCADE library directory: " ${OpenCASCADE_LIBRARY_DIR})

include_directories(${OpenCASCADE_INCLUDE_DIR})
link_directories(${OpenCASCADE_LIBRARY_DIR})
endif (OpenCASCADE_FOUND)


# Detect the installed nanobind package and import it into CMake
execute_process(
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE NB_DIR)

message(STATUS "NanoBind Cmake directory: " ${NB_DIR})
list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}")

# Import nanobind through CMake's find_package mechanism
find_package(nanobind CONFIG REQUIRED)

# Print the list of cpp files separated by spaces without altering it
string(REPLACE ";" " " ADA_CPP_SOURCES_STR "${ADA_CPP_SOURCES}")
message(STATUS "AdaCpp sources: " ${ADA_CPP_SOURCES_STR})

# Create a Python module
nanobind_add_module(_ada_cpp_ext_impl ${ADA_CPP_SOURCES})

target_link_libraries(_ada_cpp_ext_impl
PRIVATE
TKernel
TKMath
TKBRep
TKPrim
TKTopAlgo
TKSTEP
TKXDESTEP
TKRWMesh
)

# Link the module to OpenCASCADE
install(TARGETS _ada_cpp_ext_impl LIBRARY DESTINATION .)
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Ada-CPP

A drop-in replacement library for adapy created to improve performance using c++.
The compilation and binding methods are based on the [nanobind-minimal repo](https://github.com/Krande/nanobind-minimal)

## Performance metrics
Todo

## Installation

First install the pre-requisites for both occt and nanobind + build requirements from conda-forge.

```bash
mamba env update -f environment.build.yml --prune
```

Activate the environment and install the package in editable mode.

```bash
pip install --no-build-isolation .
```

### Conda Build install

Installing as conda package

```bash
mamba mambabuild . -c conda-forge --python 3.11 --override-channels
mamba install --use-local ada-cpp
```


4 changes: 4 additions & 0 deletions conda/conda_build_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
occt:
- 7.7.0
- 7.7.1=*novtk*
- 7.7.1=*all*
43 changes: 43 additions & 0 deletions conda/recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
context:
name: ada-cpp
version: 0.0.1

package:
name: '{{ name|lower }}'
version: '{{ version }}'

source:
path: ../

build:
number: 1
script: python -m pip install --no-deps --ignore-installed .

requirements:
host:
- python
- occt
- scikit-build-core
- nanobind
- pip
run:
- python
- "{{ pin_compatible('occt', max_pin='x.x.x') }}"

test:
source_files:
- tests
requires:
- pytest
commands:
- pytest tests

about:
home: https://github.com/Krande/adacpp
license: "GPL-3.0-or-later"
license_family: GPL3
summary: "A module with drop-in replacement functions for ada-py written in c++ to improve performance."

extra:
recipe-maintainers:
- Krande
13 changes: 13 additions & 0 deletions environment.build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: ada-cpp
channels:
- conda-forge
dependencies:
- occt ==7.7.0
- nanobind ==1.2.0
- pytest ==7.3.1
- scikit-build-core ==0.3.3
- cmake ==3.26.3
- conda-verify ==3.1.1
- numpy ==1.24.3
- nomkl
- boa ==0.15.1
45 changes: 45 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[build-system]
requires = [
"scikit-build-core[pyproject]",
"nanobind>=1.1.0"
]

build-backend = "scikit_build_core.build"

[project]
name = "ada-cpp"
version = "0.0.1"
authors = [
{ name = "Kristoffer H. Andersen", email = "[email protected]" },
]
description = "A minimal python wrapping of OCCT using nanobind"
readme = "README.md"
requires-python = ">=3.10"
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.10",
"Topic :: Scientific/Engineering",
"Topic :: Utilities",
]

[project.urls]
"Homepage" = "https://github.com/Krande/adacpp"
"Bug Tracker" = "https://github.com/Krande/adacpp/issues"

[tool.scikit-build]
cmake.args = ["-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.14", "-Wno-dev"]
cmake.verbose = true
#cmake.build-type = "Debug"

build-dir = "build/{wheel_tag}"

# This is the only editable mode currently
editable.mode = "redirect"

wheel.packages = ["src/adacpp"]
wheel.install-dir = "adacpp"
9 changes: 9 additions & 0 deletions src/adacpp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "binding_core.h"
#include "exchange/step_writer.h"
#include "geom/tess_helpers.h"

// Define the modules that will be exposed in python
NB_MODULE(_ada_cpp_ext_impl, m) {
step_writer_module(m);
geom_module(m);
}
4 changes: 4 additions & 0 deletions src/adacpp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from ._ada_cpp_ext_impl import write_box_to_step, write_boxes_to_step, get_box_mesh
from .utils import do_this

__doc__ = "A module with drop-in replacement functions for ada-py written in c++ to improve performance."
3 changes: 3 additions & 0 deletions src/adacpp/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def do_this():
"""A function that prints 'do_this()' to the console."""
print("do_this()")
17 changes: 17 additions & 0 deletions src/binding_core.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Created by Kristoffer on 07/05/2023.
//

#ifndef NANO_OCCT_BINDING_CORE_H
#define NANO_OCCT_BINDING_CORE_H


#include <nanobind/nanobind.h>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include <nanobind/ndarray.h>

namespace nb = nanobind;
using namespace nb::literals;

#endif //NANO_OCCT_BINDING_CORE_H
78 changes: 78 additions & 0 deletions src/exchange/gltf_writer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// Created by Kristoffer on 07/05/2023.
//

#include <iostream>
#include <string>
#include <vector>
#include <filesystem>

#include <Message_ProgressRange.hxx>
#include <RWGltf_CafWriter.hxx>
#include <RWGltf_WriterTrsfFormat.hxx>
#include <RWMesh_CoordinateSystem.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
#include <TColStd_IndexedDataMapOfStringString.hxx>
#include <TDocStd_Document.hxx>
#include <TopoDS_Compound.hxx>
#include <XCAFDoc_ColorTool.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include "../models/OccShape.h"
#include "../helpers/helpers.h"
#include "../geom/tess_helpers.h"
#include "../models/Mesh.h"


enum class Units {
M,
MM,
};

void to_gltf(
const std::filesystem::path& gltf_file,
const std::vector<OccShape>& occ_shape_iterable,
Units export_units = Units::M,
Units source_units = Units::M
) {
Handle(TDocStd_Document) doc = new TDocStd_Document(TCollection_ExtendedString("ada-py"));
Handle(XCAFDoc_ShapeTool) shape_tool = XCAFDoc_DocumentTool::ShapeTool(doc->Main());
Handle(XCAFDoc_ColorTool) color_tool = XCAFDoc_DocumentTool::ColorTool(doc->Main());

int i = 1;
for (const auto& step_shape : occ_shape_iterable) {
TopoDS_Shape shp = step_shape.shape;
if (shp.ShapeType() == TopAbs_COMPOUND) {
continue;
}

// Mesh mesh = tessellate_shape(shp, true, 1.0, false);

TDF_Label sub_shape_label = shape_tool->AddShape(shp);
set_color(sub_shape_label, step_shape.color, color_tool);
set_name(sub_shape_label, step_shape.name);

i++;
}

RWGltf_WriterTrsfFormat a_format = RWGltf_WriterTrsfFormat_Compact;

TColStd_IndexedDataMapOfStringString a_file_info;
a_file_info.Add(TCollection_AsciiString("Authors"), TCollection_AsciiString("ada-py"));

bool binary = gltf_file.extension() == ".glb";

RWGltf_CafWriter glb_writer(TCollection_AsciiString(gltf_file.string().c_str()), binary);
if (export_units == Units::M && source_units == Units::MM) {
glb_writer.ChangeCoordinateSystemConverter().SetInputLengthUnit(0.001);
} else if (export_units == Units::MM && source_units == Units::M) {
glb_writer.ChangeCoordinateSystemConverter().SetInputLengthUnit(1000);
}

glb_writer.ChangeCoordinateSystemConverter().SetInputCoordinateSystem(RWMesh_CoordinateSystem_Zup);
glb_writer.SetTransformationFormat(a_format);
Message_ProgressRange pr;
glb_writer.Perform(doc, a_file_info, pr);
}

Loading

0 comments on commit 5764ab0

Please sign in to comment.