Skip to content

Commit

Permalink
python bindings - initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
LiangliangNan committed Dec 24, 2024
1 parent 80a964d commit 58fcdd5
Show file tree
Hide file tree
Showing 127 changed files with 15,633 additions and 693 deletions.
49 changes: 28 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@ cmake_minimum_required(VERSION 3.12)

################################################################################

# Build shared libraries
if (MINGW) # Workaround for using MinGW on Windows
set(Easy3D_BUILD_SHARED_LIBS OFF)
else()
option(Easy3D_BUILD_SHARED_LIBS "Build shared libaries" ON )
endif ()
# Build tutorials
option(Easy3D_BUILD_TUTORIALS "Build Easy3D tutorials" ON )
# Build documentation
option(Easy3D_BUILD_DOCUMENTATION "Build Easy3D documentation" OFF)
# Build tests
option(Easy3D_BUILD_TESTS "Build Easy3D tests programs" OFF)
# Build Python bindings
option(Easy3D_BUILD_PYTHON_BINDINGS "Build Python bindings" ON)
# Build advanced features that require CGAL (>= v5.1)
option(Easy3D_ENABLE_CGAL "Build advanced features that require CGAL (>= v5.1)" OFF)
# Build examples/applications based on Qt (Qt5 >= v5.6, or Qt6)
option(Easy3D_ENABLE_QT "Build examples/applications based on Qt (Qt5 >= v5.6, or Qt6)" OFF)
# Build the video encoding module that requires ffmpeg
option(Easy3D_ENABLE_FFMPEG "Build the video encoding module that requires ffmpeg (>= v3.4)" OFF)

################################################################################

set(Easy3D_VERSION_MAJOR 2)
set(Easy3D_VERSION_MINOR 5)
set(Easy3D_VERSION_PATCH 4)
Expand Down Expand Up @@ -76,27 +99,6 @@ file(WRITE ${Easy3D_INCLUDE_DIR}/easy3d/util/version.h "${file_content}")

################################################################################

# Build shared libraries
if (MINGW) # Workaround for using MinGW on Windows
set(Easy3D_BUILD_SHARED_LIBS OFF)
else()
option(Easy3D_BUILD_SHARED_LIBS "Build shared libaries" ON )
endif ()
# Build tutorials
option(Easy3D_BUILD_TUTORIALS "Build Easy3D tutorials" ON )
# Build documentation
option(Easy3D_BUILD_DOCUMENTATION "Build Easy3D documentation" OFF)
# Build tests
option(Easy3D_BUILD_TESTS "Build Easy3D tests programs" OFF)
# Build advanced features that require CGAL (>= v5.1)
option(Easy3D_ENABLE_CGAL "Build advanced features that require CGAL (>= v5.1)" OFF)
# Build examples/applications based on Qt (Qt5 >= v5.6, or Qt6)
option(Easy3D_ENABLE_QT "Build examples/applications based on Qt (Qt5 >= v5.6, or Qt6)" OFF)
# Build the video encoding module that requires ffmpeg
option(Easy3D_ENABLE_FFMPEG "Build the video encoding module that requires ffmpeg (>= v3.4)" OFF)

################################################################################

# Discourage users to build Easy3D directly in its root directory
if (${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
if (NOT SAME_BUILD_AND_SOURCE_FOLDER_WARNING_ALREADY_ISSUED)
Expand Down Expand Up @@ -296,6 +298,10 @@ if (Easy3D_BUILD_TESTS)
add_subdirectory(tests)
endif ()

if (Easy3D_BUILD_PYTHON_BINDINGS)
add_subdirectory(python)
endif ()

add_subdirectory(applications)

################################################################################
Expand Down Expand Up @@ -371,6 +377,7 @@ message(STATUS " Build shared libraries : ${Easy3D_BUILD_SHARED_LIBS}")
message(STATUS " Build tutorials : ${Easy3D_BUILD_TUTORIALS}")
message(STATUS " Build documentation : ${Easy3D_BUILD_DOCUMENTATION}")
message(STATUS " Build tests : ${Easy3D_BUILD_TESTS}")
message(STATUS " Build Python bindings : ${Easy3D_BUILD_PYTHON_BINDINGS}")
message(STATUS " With CGAL (>= v5.1) : ${Easy3D_ENABLE_CGAL}")
message(STATUS " With Qt (>= v5.6) : ${Easy3D_ENABLE_QT}")
message(STATUS " With ffmpeg (>= v3.4) : ${Easy3D_ENABLE_FFMPEG}")
Expand Down
2 changes: 1 addition & 1 deletion easy3d/util/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace easy3d {
#define EASY3D_VERSION_NR 1020504

/// Easy3D release date, in the format YYYYMMDD.
#define EASY3D_RELEASE_DATE 20241223
#define EASY3D_RELEASE_DATE 20241224


#endif // EASY3D_UTIL_VERSION_H
201 changes: 188 additions & 13 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,196 @@
cmake_minimum_required(VERSION 3.12)
project(PyEasy3D)

set(CMAKE_CXX_STANDARD 14) # specify C++ standard
set(CMAKE_CXX_STANDARD 11)

find_package(Easy3D COMPONENTS viewer REQUIRED) # request Easy3D (recommended to request only needed components)
find_package(pybind11 REQUIRED)

pybind11_add_module(easy3d MODULE
easy3d.cpp
bindings/util.cpp
bindings/core.cpp
bindings/fileio.cpp
bindings/algo.cpp
bindings/viewer.cpp
#file(GLOB_RECURSE BINDING_SOURCES "bindings/*.cpp")
#string(REPLACE ";" "\n" BINDING_SOURCES_NEWLINE "${BINDING_SOURCES}") # Replace spaces with newlines for better readability
#message(STATUS "BINDING_SOURCES:\n${BINDING_SOURCES_NEWLINE}") # Print each file name on a new line

set(BINDING_SOURCES
"bindings/easy3d.cpp"

"bindings/easy3d/algo/collider.cpp"
"bindings/easy3d/algo/delaunay.cpp"
"bindings/easy3d/algo/extrusion.cpp"
"bindings/easy3d/algo/gaussian_noise.cpp"
"bindings/easy3d/algo/point_cloud_normals.cpp"
"bindings/easy3d/algo/point_cloud_poisson_reconstruction.cpp"
"bindings/easy3d/algo/point_cloud_ransac.cpp"
"bindings/easy3d/algo/point_cloud_simplification.cpp"
"bindings/easy3d/algo/polygon_partition.cpp"
"bindings/easy3d/algo/surface_mesh_components.cpp"
"bindings/easy3d/algo/surface_mesh_curvature.cpp"
"bindings/easy3d/algo/surface_mesh_enumerator.cpp"
"bindings/easy3d/algo/surface_mesh_factory.cpp"
"bindings/easy3d/algo/surface_mesh_fairing.cpp"
"bindings/easy3d/algo/surface_mesh_features.cpp"
"bindings/easy3d/algo/surface_mesh_geodesic.cpp"
"bindings/easy3d/algo/surface_mesh_geometry.cpp"
"bindings/easy3d/algo/surface_mesh_hole_filling.cpp"
"bindings/easy3d/algo/surface_mesh_parameterization.cpp"
"bindings/easy3d/algo/surface_mesh_polygonization.cpp"
"bindings/easy3d/algo/surface_mesh_remeshing.cpp"
"bindings/easy3d/algo/surface_mesh_sampler.cpp"
"bindings/easy3d/algo/surface_mesh_simplification.cpp"
"bindings/easy3d/algo/surface_mesh_smoothing.cpp"
"bindings/easy3d/algo/surface_mesh_stitching.cpp"
"bindings/easy3d/algo/surface_mesh_subdivision.cpp"
"bindings/easy3d/algo/surface_mesh_tetrahedralization.cpp"
"bindings/easy3d/algo/surface_mesh_topology.cpp"
"bindings/easy3d/algo/surface_mesh_triangulation.cpp"
"bindings/easy3d/algo/tessellator.cpp"
"bindings/easy3d/algo/text_mesher.cpp"
"bindings/easy3d/algo/triangle_mesh_kdtree.cpp"

"bindings/easy3d/core/box.cpp"
"bindings/easy3d/core/constant.cpp"
"bindings/easy3d/core/graph.cpp"
"bindings/easy3d/core/line.cpp"
"bindings/easy3d/core/mat.cpp"
"bindings/easy3d/core/model.cpp"
"bindings/easy3d/core/plane.cpp"
"bindings/easy3d/core/point_cloud.cpp"
"bindings/easy3d/core/poly_mesh.cpp"
"bindings/easy3d/core/property.cpp"
"bindings/easy3d/core/random.cpp"
"bindings/easy3d/core/signal.cpp"
"bindings/easy3d/core/surface_mesh.cpp"
"bindings/easy3d/core/surface_mesh_builder.cpp"
"bindings/easy3d/core/types.cpp"
"bindings/easy3d/core/vec.cpp"

"bindings/easy3d/fileio/graph_io.cpp"
"bindings/easy3d/fileio/image_io.cpp"
"bindings/easy3d/fileio/point_cloud_io.cpp"
"bindings/easy3d/fileio/poly_mesh_io.cpp"
"bindings/easy3d/fileio/surface_mesh_io.cpp"
"bindings/easy3d/fileio/translator.cpp"

"bindings/easy3d/kdtree/kdtree_search_eth.cpp"
"bindings/easy3d/kdtree/kdtree_search_ann.cpp"
"bindings/easy3d/kdtree/kdtree_search_flann.cpp"
"bindings/easy3d/kdtree/kdtree_search_nanoflann.cpp"

"bindings/easy3d/renderer/camera.cpp"

"bindings/easy3d/util/console_style.cpp"
"bindings/easy3d/util/dialog.cpp"
"bindings/easy3d/util/file_system.cpp"
"bindings/easy3d/util/initializer.cpp"
"bindings/easy3d/util/line_stream.cpp"
"bindings/easy3d/util/logging.cpp"
"bindings/easy3d/util/progress.cpp"
"bindings/easy3d/util/resource.cpp"
"bindings/easy3d/util/setting.cpp"
"bindings/easy3d/util/stop_watch.cpp"
"bindings/easy3d/util/string.cpp"
"bindings/easy3d/util/timer.cpp"
"bindings/easy3d/util/tokenizer.cpp"
"bindings/easy3d/util/version.cpp"

"bindings/easy3d/viewer/multi_viewer.cpp"
"bindings/easy3d/viewer/offscreen.cpp"
"bindings/easy3d/viewer/viewer.cpp"

# Seems never needed
# "bindings/easy3d/gui/picker.cpp"
# "bindings/easy3d/gui/picker_model.cpp"
# "bindings/easy3d/gui/picker_point_cloud.cpp"
# "bindings/easy3d/gui/picker_surface_mesh.cpp"
# "bindings/easy3d/renderer/ambient_occlusion.cpp"
# "bindings/easy3d/renderer/buffer.cpp"
# "bindings/easy3d/renderer/clipping_plane.cpp"
# "bindings/easy3d/renderer/constraint.cpp"
# "bindings/easy3d/renderer/drawable_lines.cpp"
# "bindings/easy3d/renderer/eye_dome_lighting.cpp"
# "bindings/easy3d/renderer/framebuffer_object.cpp"
# "bindings/easy3d/renderer/frustum.cpp"
# "bindings/easy3d/renderer/key_frame_interpolator.cpp"
# "bindings/easy3d/renderer/manipulated_frame.cpp"
# "bindings/easy3d/renderer/opengl_error.cpp"
# "bindings/easy3d/renderer/opengl_timer.cpp"
# "bindings/easy3d/renderer/read_pixel.cpp"
# "bindings/easy3d/renderer/renderer.cpp"
# "bindings/easy3d/renderer/shader_manager.cpp"
# "bindings/easy3d/renderer/shader_program.cpp"
# "bindings/easy3d/renderer/shadow.cpp"
# "bindings/easy3d/renderer/shape.cpp"
# "bindings/easy3d/renderer/soft_shadow.cpp"
# "bindings/easy3d/renderer/state.cpp"
# "bindings/easy3d/renderer/text_renderer.cpp"
# "bindings/easy3d/renderer/texture.cpp"
# "bindings/easy3d/renderer/texture_manager.cpp"
# "bindings/easy3d/renderer/transform.cpp"
# "bindings/easy3d/renderer/transparency.cpp"
# "bindings/easy3d/renderer/vertex_array_object.cpp"
)
target_link_libraries(easy3d PRIVATE easy3d::util easy3d::core easy3d::renderer easy3d::fileio easy3d::algo easy3d::viewer)
target_compile_definitions(easy3d PRIVATE PYBIND11_SIMPLE_GIL_SAFE_ABI) # to use the Python Stable ABI

if(Easy3D_HAS_CGAL)
list(APPEND SOURCES "bindings/easy3d/algo_ext/surfacer.cpp")
endif()

if(Easy3D_HAS_FFMPEG)
list(APPEND SOURCES "bindings/easy3d/video/video_encoder.cpp")
endif()

pybind11_add_module(${PROJECT_NAME} MODULE ${BINDING_SOURCES})
target_link_libraries(${PROJECT_NAME} PRIVATE
easy3d::algo
easy3d::core
easy3d::fileio
easy3d::gui
easy3d::kdtree
easy3d::renderer
easy3d::util
easy3d::viewer
)
if (Easy3D_HAS_CGAL)
target_compile_definitions(${PROJECT_NAME} PRIVATE HAS_CGAL)
target_link_libraries(${PROJECT_NAME} PRIVATE easy3d::algo_ext)
endif ()
if (Easy3D_HAS_FFMPEG)
target_compile_definitions(${PROJECT_NAME} PRIVATE HAS_FFMPEG)
target_link_libraries(${PROJECT_NAME} PRIVATE easy3d::video)
endif ()

target_compile_definitions(${PROJECT_NAME} PRIVATE PYBIND11_SIMPLE_GIL_SAFE_ABI) # to use the Python Stable ABI
# By default, the output .so will include the Python version. Use a CMake command to rename it to a version-independent name
set_target_properties(easy3d PROPERTIES SUFFIX ".so")
set_target_properties(easy3d PROPERTIES FOLDER "python")
set_target_properties(${PROJECT_NAME} PROPERTIES
SUFFIX ".so"
FOLDER "python"
)


# The following commands are actually not necessary for generating bindings.
# They are here to make the use of the bindings easier. Basically, the build the package structure, in CMakeAdd a custom command to copy the compiled PyEasy3D module to the Python package directory

# Specify the output directory for the Python package
set(PYTHON_PACKAGE_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/python/easy3d")

# Ensure the directory exists
file(MAKE_DIRECTORY ${PYTHON_PACKAGE_DIR})

# Generate the __init__.py file with the alias mechanism
file(WRITE ${PYTHON_PACKAGE_DIR}/__init__.py "
# Alias for the PyEasy3D module
try:
from .PyEasy3D import *
except ImportError:
from PyEasy3D import *
")

# Path to the compiled PyEasy3D module
set(COMPILED_MODULE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${PROJECT_NAME}.so")

# Copy the compiled PyEasy3D module to the Python package directory
add_custom_command(
TARGET PyEasy3D POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${COMPILED_MODULE} ${PYTHON_PACKAGE_DIR}/
COMMENT "Copying PyEasy3D module to Python package"
)

# Copy setup.py to the Python package directory
configure_file(${CMAKE_CURRENT_LIST_DIR}/setup.py.in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/python/setup.py COPYONLY)
50 changes: 0 additions & 50 deletions python/bindings/algo.cpp

This file was deleted.

Loading

0 comments on commit 58fcdd5

Please sign in to comment.