From 2aa3cd55ff2e1605f456fbea4c88ffefa893ac1a Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 25 Feb 2022 20:03:16 -0500 Subject: [PATCH 01/20] proof of concept binding igl::copyleft::cgal::convex_hull --- CMakeLists.txt | 22 ++++++++++---- igl/__init__.py | 1 + src/copyleft/cgal/convex_hull.cpp | 48 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/copyleft/cgal/convex_hull.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b465ee0a..d9c37e87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,12 @@ include(Warnings) include(CXXFeatures) option(PY_IGL_PYTHON_TESTS "Run Python tests" ON) +message(STATUS "PY_IGL_PYTHON_TESTS: ${PY_IGL_PYTHON_TESTS}") -include(PyiglDependencies) +option(LIBIGL_COPYLEFT_CGAL "Build target igl_copyleft::cgal" ON) +# libigl options must come before include(PyiglDependencies) +include(PyiglDependencies) if(NOT TARGET igl::core) include(libigl) endif() @@ -31,16 +34,23 @@ include(numpyeigen) # A module for writing bindings with our framework file(GLOB PYIGL_SOURCES src/*.cpp) - npe_add_module(pyigl BINDING_SOURCES - ${PYIGL_SOURCES} - ${PYIGL_SOURCES_COPYLEFT}) - -#TODO move additional libs to variable + ${PYIGL_SOURCES}) target_link_libraries(pyigl PRIVATE igl::core) target_include_directories(pyigl PRIVATE "src/include") +if(LIBIGL_COPYLEFT_CGAL) + file(GLOB PYIGL_COPYLEFT_CGAL_SOURCES src/copyleft/cgal/*.cpp) + npe_add_module(pyigl_copyleft_cgal + BINDING_SOURCES + ${PYIGL_COPYLEFT_CGAL_SOURCES}) + target_link_libraries(pyigl_copyleft_cgal PRIVATE igl::core igl_copyleft::cgal) + target_include_directories(pyigl_copyleft_cgal PRIVATE "src/include") + target_link_libraries(pyigl INTERFACE pyigl_copyleft_cgal) +endif() + + add_library(pyigl_classes MODULE classes/classes.cpp) target_link_libraries(pyigl_classes PRIVATE npe igl::core) target_link_libraries(pyigl_classes PRIVATE pybind11::module) diff --git a/igl/__init__.py b/igl/__init__.py index 6f8e6a4e..fdb26700 100644 --- a/igl/__init__.py +++ b/igl/__init__.py @@ -1,3 +1,4 @@ from .pyigl import * +from .pyigl_copyleft_cgal import * from .helpers import * from .pyigl_classes import * diff --git a/src/copyleft/cgal/convex_hull.cpp b/src/copyleft/cgal/convex_hull.cpp new file mode 100644 index 00000000..86c9c013 --- /dev/null +++ b/src/copyleft/cgal/convex_hull.cpp @@ -0,0 +1,48 @@ +#include +#include + +#include + +const char* ds_convex_hull = R"igl_Qu8mg5v7( + +Parameters +---------- + + +Returns +------- + + +See also +-------- + + +Notes +----- +None + +Examples +-------- + + Given a set of points (V), compute the convex hull as a triangle mesh (W,G) + + Inputs: + V #V by 3 list of input points + Outputs: + W #W by 3 list of convex hull points + G #G by 3 list of triangle indices into W +)igl_Qu8mg5v7"; + +npe_function(convex_hull) +npe_doc(ds_convex_hull) + +npe_arg(v, dense_float, dense_double) +npe_begin_code() + + EigenDenseLike w; + EigenDenseInt g; + igl::copyleft::cgal::convex_hull(v, w, g); + return std::make_tuple(npe::move(w), npe::move(g)); + +npe_end_code() + From 1a4d554a1950ee347f3b2209b8f56ac090c8025e Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Sat, 26 Feb 2022 22:44:05 -0500 Subject: [PATCH 02/20] generalize cmake for modules --- CMakeLists.txt | 43 ++++++++++++++++++++++++------- cmake/PyiglDependencies.cmake | 2 +- igl/__init__.py | 1 - scripts/generate_bindings.py | 4 +-- src/copyleft/cgal/convex_hull.cpp | 35 +++++++------------------ 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9c37e87..d20e0fc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,16 +39,39 @@ npe_add_module(pyigl ${PYIGL_SOURCES}) target_link_libraries(pyigl PRIVATE igl::core) target_include_directories(pyigl PRIVATE "src/include") - -if(LIBIGL_COPYLEFT_CGAL) - file(GLOB PYIGL_COPYLEFT_CGAL_SOURCES src/copyleft/cgal/*.cpp) - npe_add_module(pyigl_copyleft_cgal - BINDING_SOURCES - ${PYIGL_COPYLEFT_CGAL_SOURCES}) - target_link_libraries(pyigl_copyleft_cgal PRIVATE igl::core igl_copyleft::cgal) - target_include_directories(pyigl_copyleft_cgal PRIVATE "src/include") - target_link_libraries(pyigl INTERFACE pyigl_copyleft_cgal) -endif() +set_target_properties(pyigl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + +# don't need to worry about nested modules (opengl/** are the only ones and +# those probably aren't ever getting python bindings) +# +# prefix is either "", "copyleft", or "restricted" +function(pyigl_include prefix name) + string(TOUPPER "${prefix}" prefix_uc) + string(TOUPPER "${name}" name_uc) + if(prefix_uc) + string(PREPEND prefix_uc _) + endif() + string(TOLOWER "${prefix_uc}" prefix_lc) + if(LIBIGL${prefix_uc}_${name_uc}) + if(${prefix} STREQUAL "copyleft") + set(subpath "copyleft/${name}") + else() # "" or "restricted" + set(subpath "${name}") + endif() + file(GLOB sources src/${subpath}/*.cpp) + set(target_name "pyigl${prefix_lc}_${name}") + npe_add_module( ${target_name} BINDING_SOURCES ${sources}) + target_link_libraries( ${target_name} PRIVATE igl::core igl${prefix_lc}::${name}) + target_include_directories( ${target_name} PRIVATE "src/include") + set(output_dir "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${subpath}") + file(MAKE_DIRECTORY ${output_dir}) + file(WRITE "${output_dir}/__init__.py" "from .${target_name} import *") + set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${output_dir}") + target_link_libraries( pyigl INTERFACE ${target_name}) + endif() +endfunction() + +pyigl_include("copyleft" "cgal") add_library(pyigl_classes MODULE classes/classes.cpp) diff --git a/cmake/PyiglDependencies.cmake b/cmake/PyiglDependencies.cmake index 68b0840d..4bc8018b 100644 --- a/cmake/PyiglDependencies.cmake +++ b/cmake/PyiglDependencies.cmake @@ -20,7 +20,7 @@ include(FetchContent) FetchContent_Declare( libigl GIT_REPOSITORY https://github.com/libigl/libigl.git - GIT_TAG v2.4.0 + GIT_TAG 4fa1e22c8f30536477d20013f555dec2d7dba119 ) FetchContent_MakeAvailable(libigl) diff --git a/igl/__init__.py b/igl/__init__.py index fdb26700..6f8e6a4e 100644 --- a/igl/__init__.py +++ b/igl/__init__.py @@ -1,4 +1,3 @@ from .pyigl import * -from .pyigl_copyleft_cgal import * from .helpers import * from .pyigl_classes import * diff --git a/scripts/generate_bindings.py b/scripts/generate_bindings.py index cc75d0d7..5f5116e3 100755 --- a/scripts/generate_bindings.py +++ b/scripts/generate_bindings.py @@ -192,7 +192,7 @@ def map_parameter_types(name, cpp_type, parsed_types, errors, enum_types): # Parse c++ header files print("Parsing header files...") - load_headers = True + load_headers = False if load_headers: with open("headers.dat", 'rb') as fs: dicts = pickle.load(fs) @@ -291,7 +291,7 @@ def map_parameter_types(name, cpp_type, parsed_types, errors, enum_types): # Write binding files try: tpl = Template(filename='basic_function.mako') - #print(correct_functions) + print(correct_functions) includes = ["", ""] rendered = tpl.render(functions=correct_functions, enums=enums, includes=includes) tpl1 = Template(filename='basic_function.mako') diff --git a/src/copyleft/cgal/convex_hull.cpp b/src/copyleft/cgal/convex_hull.cpp index 86c9c013..8e225e95 100644 --- a/src/copyleft/cgal/convex_hull.cpp +++ b/src/copyleft/cgal/convex_hull.cpp @@ -4,33 +4,15 @@ #include const char* ds_convex_hull = R"igl_Qu8mg5v7( - +Given a set of points (V), compute the convex hull as a triangle mesh (F) + Parameters ---------- - +V : #V by 3 list of input points Returns ------- - - -See also --------- - - -Notes ------ -None - -Examples --------- - - Given a set of points (V), compute the convex hull as a triangle mesh (W,G) - - Inputs: - V #V by 3 list of input points - Outputs: - W #W by 3 list of convex hull points - G #G by 3 list of triangle indices into W +F #F by 3 list of triangle indices into V )igl_Qu8mg5v7"; npe_function(convex_hull) @@ -39,10 +21,11 @@ npe_doc(ds_convex_hull) npe_arg(v, dense_float, dense_double) npe_begin_code() - EigenDenseLike w; EigenDenseInt g; - igl::copyleft::cgal::convex_hull(v, w, g); - return std::make_tuple(npe::move(w), npe::move(g)); + // when https://github.com/libigl/libigl/pull/1989 is merged this copy should + // be removed + Eigen::MatrixXd v_copy = v.template cast(); + igl::copyleft::cgal::convex_hull(v_copy, g); + return npe::move(g); npe_end_code() - From aa689801d1210cbfa6594909c5e673cadf8c0ba0 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Sat, 26 Feb 2022 23:31:58 -0500 Subject: [PATCH 03/20] mesh_boolean --- src/copyleft/cgal/mesh_boolean.cpp | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/copyleft/cgal/mesh_boolean.cpp diff --git a/src/copyleft/cgal/mesh_boolean.cpp b/src/copyleft/cgal/mesh_boolean.cpp new file mode 100644 index 00000000..2a565f0b --- /dev/null +++ b/src/copyleft/cgal/mesh_boolean.cpp @@ -0,0 +1,63 @@ +#include +#include +#include + + +const char* ds_mesh_boolean = R"igl_Qu8mg5v7( +MESH_BOOLEAN Compute boolean csg operations on "solid", consistently oriented +meshes. + + +Parameters +---------- +VA : #VA by 3 list of vertex positions of first mesh +FA : #FA by 3 list of triangle indices into VA +VB : #VB by 3 list of vertex positions of second mesh +FB : #FB by 3 list of triangle indices into VB + +Returns +------- +VC : #VC by 3 list of vertex positions of boolean result mesh +FC : #FC by 3 list of triangle indices into VC +J : #FC list of indices into [FA;FA.rows()+FB] revealing "birth" facet + +See also +-------- +mesh_boolean_cork, intersect_other, remesh_self_intersections +)igl_Qu8mg5v7"; + +npe_function(mesh_boolean) +npe_doc(ds_mesh_boolean) + +npe_arg(va, dense_float, dense_double) +npe_arg(fa, dense_int, dense_long, dense_longlong) +npe_arg(vb, npe_matches(va)) +npe_arg(fb, npe_matches(fa)) +npe_arg(type, std::string) + + +npe_begin_code() + Eigen::MatrixXd va_copy = va.template cast(); + Eigen::MatrixXd vb_copy = vb.template cast(); + Eigen::MatrixXi fa_copy = fa.template cast(); + Eigen::MatrixXi fb_copy = fb.template cast(); + + Eigen::MatrixXd vc_copy; + Eigen::MatrixXi fc_copy; + Eigen::VectorXi j_copy; + igl::copyleft::cgal::mesh_boolean( + va_copy, + fa_copy, + vb_copy, + fb_copy, + type, + vc_copy, + fc_copy, + j_copy); + + EigenDenseLike vc = vc_copy.cast(); + EigenDenseLike fc = fc_copy.cast(); + EigenDenseLike j = j_copy.cast(); + return std::make_tuple(npe::move(vc), npe::move(fc), npe::move(j)); +npe_end_code() + From 729e513c99845256b58794403260b5f93549e0c6 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 1 Apr 2022 17:52:58 -0400 Subject: [PATCH 04/20] remesh_self_intersections --- .../cgal/remesh_self_intersections.cpp | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/copyleft/cgal/remesh_self_intersections.cpp diff --git a/src/copyleft/cgal/remesh_self_intersections.cpp b/src/copyleft/cgal/remesh_self_intersections.cpp new file mode 100644 index 00000000..074802c5 --- /dev/null +++ b/src/copyleft/cgal/remesh_self_intersections.cpp @@ -0,0 +1,79 @@ +#include +#include +#include + + + +const char* ds_remesh_self_intersections = R"igl_Qu8mg5v7( +REMESH_SELF_INTERSECTIONS Given a triangle mesh (V,F) compute a new mesh (VV,FF) +which is the same as (V,F) except that any self-intersecting triangles in (V,F) +have been subdivided (new vertices and face created) so that the +self-intersection contour lies exactly on edges in (VV,FF). New vertices will +appear in original faces or on original edges. New vertices on edges are +"merged" only across original faces sharing that edge. This means that if the +input triangle mesh is a closed manifold the output will be too. + + +Parameters +---------- +V : #V by 3 list of vertex positions of mesh +F : #F by 3 list of triangle indices into rows of V +detect_only : avoid constructing intersections results when possible {false} +first_only : return after detecting the first intersection (if + first_only==true, then detect_only should also be true) {false} +stitch_all : whether to stitch all resulting constructed elements into a + (non-manifold) mesh {false} +slow_and_more_precise_rounding : whether to use slow and more precise + rounding (see assign_scalar) {false} + + +Returns +------- +VV : #VV by 3 list of vertex positions +FF : #FF by 3 list of triangle indices into VV +IF : #intersecting face pairs by 2 list of intersecting face pairs, indexing F +J : #FF list of indices into F denoting birth triangle +IM : #VV list of indices into VV of unique vertices. + +See also +-------- +mesh_boolean +)igl_Qu8mg5v7"; + +npe_function(remesh_self_intersections) +npe_doc(ds_remesh_self_intersections) + +npe_arg(V, dense_float, dense_double) +npe_arg(F, dense_int, dense_long, dense_longlong) +npe_default_arg(detect_only, bool, false) +npe_default_arg(first_only, bool, false) +npe_default_arg(stitch_all, bool, false) +// Awaiting bump in libigl +//npe_default_arg(slow_and_more_precise_rounding, bool, false) + + +npe_begin_code() + Eigen::MatrixXd Vcpy = V.template cast(); + Eigen::MatrixXi Fcpy = F.template cast(); + + Eigen::MatrixXd VVcpy; + Eigen::MatrixXi FFcpy; + Eigen::VectorXi Jcpy; + Eigen::VectorXi IMcpy; + Eigen::MatrixXi IFcpy; + igl::copyleft::cgal::RemeshSelfIntersectionsParam params; + params.detect_only = detect_only; + params.first_only = first_only; + params.stitch_all = stitch_all; + //params.slow_and_more_precise_rounding = slow_and_more_precise_rounding; + igl::copyleft::cgal::remesh_self_intersections( + Vcpy,Fcpy,params,VVcpy,FFcpy,IFcpy,Jcpy,IMcpy); + + EigenDenseLike VV = VVcpy.cast(); + EigenDenseLike FF = FFcpy.cast(); + EigenDenseLike IF = IFcpy.cast(); + EigenDenseLike J = Jcpy.cast(); + EigenDenseLike IM = IMcpy.cast(); + return std::make_tuple(npe::move(VV), npe::move(FF), npe::move(IF), npe::move(J), npe::move(IM)); +npe_end_code() + From 4169d365a3e584bbd8886540068f2255a0e54662 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 1 Apr 2022 18:16:23 -0400 Subject: [PATCH 05/20] intersect_other --- src/copyleft/cgal/intersect_other.cpp | 87 +++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/copyleft/cgal/intersect_other.cpp diff --git a/src/copyleft/cgal/intersect_other.cpp b/src/copyleft/cgal/intersect_other.cpp new file mode 100644 index 00000000..d03e7fd0 --- /dev/null +++ b/src/copyleft/cgal/intersect_other.cpp @@ -0,0 +1,87 @@ +#include +#include +#include + + + +const char* ds_intersect_other = R"igl_Qu8mg5v7( +INTERSECT_OTHER Given a triangle mesh (VA,FA) and another mesh (VB,FB) find all +pairs of intersecting faces. Note that self-intersections are ignored. + + +Parameters +---------- +VA : #VA by 3 list of vertex positions of first mesh +FA : #FA by 3 list of triangle indices into VA +VB : #VB by 3 list of vertex positions of second mesh +FB : #FB by 3 list of triangle indices into VB +detect_only : avoid constructing intersections results when possible {false} +first_only : return after detecting the first intersection (if + first_only==true, then detect_only should also be true) {false} +stitch_all : whether to stitch all resulting constructed elements into a + (non-manifold) mesh {false} +slow_and_more_precise_rounding : whether to use slow and more precise + rounding (see assign_scalar) {false} + + +Returns +------- +IF : #intersecting face pairs by 2 list of intersecting face pairs, indexing F +VVAB : #VVAB by 3 list of vertex positions +FFAB : #FFAB by 3 list of triangle indices into VVAB +JAB : #FFAB list of indices into [FA;FB] denoting birth triangle +IMAB : #VVAB list of indices stitching duplicates (resulting from + mesh intersections) together + +See also +-------- +mesh_boolean +)igl_Qu8mg5v7"; + +npe_function(intersect_other) +npe_doc( ds_intersect_other) + +npe_arg(VA, dense_float, dense_double) +npe_arg(FA, dense_int, dense_long, dense_longlong) +npe_arg(VB, npe_matches(VA)) +npe_arg(FB, npe_matches(FA)) +npe_default_arg(detect_only, bool, false) +npe_default_arg(first_only, bool, false) +npe_default_arg(stitch_all, bool, false) +// Awaiting bump in libigl +//npe_default_arg(slow_and_more_precise_rounding, bool, false) + + +npe_begin_code() + Eigen::MatrixXd VAcpy = VA.template cast(); + Eigen::MatrixXi FAcpy = FA.template cast(); + Eigen::MatrixXd VBcpy = VB.template cast(); + Eigen::MatrixXi FBcpy = FB.template cast(); + + Eigen::MatrixXd VVABcpy; + Eigen::MatrixXi FFABcpy; + Eigen::VectorXi JABcpy; + Eigen::VectorXi IMABcpy; + Eigen::MatrixXi IFcpy; + igl::copyleft::cgal::RemeshSelfIntersectionsParam params; + params.detect_only = detect_only; + params.first_only = first_only; + params.stitch_all = stitch_all; + //params.slow_and_more_precise_rounding = slow_and_more_precise_rounding; + igl::copyleft::cgal::intersect_other( + VAcpy,FAcpy,VBcpy,FBcpy,params,IFcpy,VVABcpy,FFABcpy,JABcpy,IMABcpy); + + EigenDenseLike IF = IFcpy.cast(); + EigenDenseLike VVAB = VVABcpy.cast(); + EigenDenseLike FFAB = FFABcpy.cast(); + EigenDenseLike JAB = JABcpy.cast(); + EigenDenseLike IMAB = IMABcpy.cast(); + return std::make_tuple( + npe::move(IF), + npe::move(VVAB), + npe::move(FFAB), + npe::move( JAB), + npe::move(IMAB)); +npe_end_code() + + From 6aeec3058c3423bb5b42009ec76be074f5a54493 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 1 Apr 2022 19:22:21 -0400 Subject: [PATCH 06/20] bump libigl --- cmake/PyiglDependencies.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/PyiglDependencies.cmake b/cmake/PyiglDependencies.cmake index 4bc8018b..e9b1701b 100644 --- a/cmake/PyiglDependencies.cmake +++ b/cmake/PyiglDependencies.cmake @@ -20,7 +20,7 @@ include(FetchContent) FetchContent_Declare( libigl GIT_REPOSITORY https://github.com/libigl/libigl.git - GIT_TAG 4fa1e22c8f30536477d20013f555dec2d7dba119 + GIT_TAG 1c3d487d8e77f816934374c271ef978807003405 ) FetchContent_MakeAvailable(libigl) From 92bf5720fb89d931831dd8bfa783a1e66a62196e Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Tue, 7 Feb 2023 08:50:27 -0500 Subject: [PATCH 07/20] rm repair wheel --- .github/workflows/wheels.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 9fe470e9..175daa1d 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -50,8 +50,6 @@ jobs: env: CIBW_BUILD_VERBOSITY: 3 # This is very dubious... It *may* work because these are just cpp libraries that should not depend on the python version. Still, super-dubious. - CIBW_BEFORE_BUILD_WINDOWS: "python -m pip install delvewheel" - CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "python -m delvewheel repair --no-mangle-all --add-path build\\temp.win-amd64-3.6\\Release;build\\temp.win-amd64-3.6\\Release\\Release;build\\temp.win-amd64-3.6\\Release\\_deps\\gmp-src\\lib;build\\temp.win-amd64-3.6\\Release\\_deps\\mpfr-src\\lib -w {dest_dir} {wheel} " CIBW_TEST_COMMAND: "python {project}/tests/test_basic.py {project}/data/" CIBW_BUILD: "${{ matrix.cpversion }}-${{ matrix.os.cibw-arch }}" CIBW_TEST_SKIP: "*-macosx_arm64" From 7b5b46288640648aeb5321cff5570c0645133221 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 10:36:47 -0500 Subject: [PATCH 08/20] fix for windows? --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58cd94b8..7f2f0a4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,10 @@ function(pyigl_include prefix name) set(output_dir "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${subpath}") file(MAKE_DIRECTORY ${output_dir}) file(WRITE "${output_dir}/__init__.py" "from .${target_name} import *") - set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${output_dir}") + # https://stackoverflow.com/a/56514534/148668 + set_target_properties(${target_name} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${output_dir}" + RUNTIME_OUTPUT_DIRECTORY "${output_dir}") target_link_libraries( pyigl INTERFACE ${target_name}) endif() endfunction() From 5311d051593d0ea56a48390b718c9fde067f0089 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 10:54:15 -0500 Subject: [PATCH 09/20] bug fix --- CMakeLists.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f2f0a4b..5d7d8c30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,15 @@ cmake_minimum_required(VERSION 3.16.0) project(pyigl) -if (NOT DEFINED ${PYLIBIGL_EXTERNAL}) +if (NOT DEFINED PYLIBIGL_EXTERNAL) set(PYLIBIGL_EXTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/external) endif() +message(STATUS "PYIGL_OUTPUT_DIRECTORY: ${PYIGL_OUTPUT_DIRECTORY}") +if (NOT DEFINED PYIGL_OUTPUT_DIRECTORY) + message(FATAL_ERROR "PYIGL_OUTPUT_DIRECTORY must be defined externally") +endif() + list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # Color output include(UseColors) @@ -32,7 +37,10 @@ npe_add_module(pyigl ${PYIGL_SOURCES}) target_link_libraries(pyigl PRIVATE igl::core) target_include_directories(pyigl PRIVATE "src/include") -set_target_properties(pyigl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") +set_target_properties(pyigl PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" + RUNTIME_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" + ) # don't need to worry about nested modules (opengl/** are the only ones and # those probably aren't ever getting python bindings) @@ -56,7 +64,7 @@ function(pyigl_include prefix name) npe_add_module( ${target_name} BINDING_SOURCES ${sources}) target_link_libraries( ${target_name} PRIVATE igl::core igl${prefix_lc}::${name}) target_include_directories( ${target_name} PRIVATE "src/include") - set(output_dir "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${subpath}") + set(output_dir "${PYIGL_OUTPUT_DIRECTORY}/${subpath}") file(MAKE_DIRECTORY ${output_dir}) file(WRITE "${output_dir}/__init__.py" "from .${target_name} import *") # https://stackoverflow.com/a/56514534/148668 @@ -76,6 +84,10 @@ target_link_libraries(pyigl_classes PRIVATE pybind11::module) set_target_properties(pyigl_classes PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" SUFFIX "${PYTHON_MODULE_EXTENSION}") target_include_directories(pyigl_classes PRIVATE "src/include") target_include_directories(pyigl_classes PRIVATE "${PYLIBIGL_EXTERNAL}/numpyeigen/src") +set_target_properties(pyigl_classes PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" + RUNTIME_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" + ) # Sort projects inside the solution set_property(GLOBAL PROPERTY USE_FOLDERS ON) From 8fc3cc157907c2cfc3b7f67a92a15aa9f0db87a8 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 10:54:26 -0500 Subject: [PATCH 10/20] bug fix --- setup.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/setup.py b/setup.py index c50b6e7e..149ecfdd 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ def run(self): def build_extension(self, ext): extdir = os.path.join(os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))),"igl") - cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + cmake_args = ['-DPYIGL_OUTPUT_DIRECTORY=' + extdir, '-DPYTHON_EXECUTABLE=' + sys.executable] @@ -46,18 +46,10 @@ def build_extension(self, ext): cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] # cmake_args += ['-DDEBUG_TRACE=ON'] - if platform.system() == "Windows": - cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] - cmake_generator = os.environ.get('CMAKE_GENERATOR', '') - if cmake_generator != "NMake Makefiles" and "Ninja" not in cmake_generator: - if sys.maxsize > 2**32: - cmake_args += ['-A', 'x64'] - # build_args += ['--', '/m'] - else: - if "MAX_JOBS" in os.environ: - build_args += ['--', f"-j{os.environ['MAX_JOBS']}"] - else: - build_args += ['--', '-j8'] + if "MAX_JOBS" in os.environ: + build_args += ['--', f"-j{os.environ['MAX_JOBS']}"] + else: + build_args += ['--', '-j8'] tmp = os.environ.get("AR", "") @@ -97,7 +89,6 @@ def build_extension(self, ext): if "arm" in tmp: cmake_args += ["-DCMAKE_OSX_ARCHITECTURES=arm64"] - # print(cmake_args) # tmp = os.getenv('CMAKE_ARGS', '') # if tmp: From 668c27f68ac4e6a8cfacb2a30b1abcfff45f8cdf Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 10:57:55 -0500 Subject: [PATCH 11/20] windows skip -j8 --- setup.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 149ecfdd..a1bd26b5 100644 --- a/setup.py +++ b/setup.py @@ -46,10 +46,19 @@ def build_extension(self, ext): cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] # cmake_args += ['-DDEBUG_TRACE=ON'] - if "MAX_JOBS" in os.environ: - build_args += ['--', f"-j{os.environ['MAX_JOBS']}"] - else: - build_args += ['--', '-j8'] + if platform.system() == "Windows": + #cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] + cmake_generator = os.environ.get('CMAKE_GENERATOR', '') + print(f"cmake_generator: {cmake_generator}") + if cmake_generator != "NMake Makefiles" and "Ninja" not in cmake_generator: + if sys.maxsize > 2**32: + cmake_args += ['-A', 'x64'] + # build_args += ['--', '/m'] + else: + if "MAX_JOBS" in os.environ: + build_args += ['--', f"-j{os.environ['MAX_JOBS']}"] + else: + build_args += ['--', '-j8'] tmp = os.environ.get("AR", "") From aea45276c26496bd950dcb32634e0ee6c26d207b Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 11:13:51 -0500 Subject: [PATCH 12/20] generic parallel build --- setup.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index a1bd26b5..b1b6183a 100644 --- a/setup.py +++ b/setup.py @@ -54,11 +54,13 @@ def build_extension(self, ext): if sys.maxsize > 2**32: cmake_args += ['-A', 'x64'] # build_args += ['--', '/m'] - else: - if "MAX_JOBS" in os.environ: - build_args += ['--', f"-j{os.environ['MAX_JOBS']}"] - else: - build_args += ['--', '-j8'] + + if "MAX_JOBS" in os.environ: + MAX_JOBS = os.environ['MAX_JOBS'] + else: + MAX_JOBS = 8 + + cmake_args += [f'-DCMAKE_BUILD_PARALLEL_LEVEL={MAX_JOBS}'] tmp = os.environ.get("AR", "") From 7c095c820db9ce80f6207e6da0e5e06699fdf91d Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 11:21:14 -0500 Subject: [PATCH 13/20] MAX_JOBS -> CMAKE_BUILD_PARALLEL_LEVEL --- setup.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/setup.py b/setup.py index b1b6183a..682f099f 100644 --- a/setup.py +++ b/setup.py @@ -55,13 +55,8 @@ def build_extension(self, ext): cmake_args += ['-A', 'x64'] # build_args += ['--', '/m'] - if "MAX_JOBS" in os.environ: - MAX_JOBS = os.environ['MAX_JOBS'] - else: - MAX_JOBS = 8 - - cmake_args += [f'-DCMAKE_BUILD_PARALLEL_LEVEL={MAX_JOBS}'] - + if not "CMAKE_BUILD_PARALLEL_LEVEL" in os.environ: + os.environ['CMAKE_BUILD_PARALLEL_LEVEL'] = "8" tmp = os.environ.get("AR", "") if "arm64-apple" in tmp: From fe4d886a2926011154031dda518826d93bfb2f62 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 11:37:13 -0500 Subject: [PATCH 14/20] revert --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d7d8c30..7e91e08d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,8 @@ target_include_directories(pyigl PRIVATE "src/include") set_target_properties(pyigl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" RUNTIME_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" + LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PYIGL_OUTPUT_DIRECTORY}" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PYIGL_OUTPUT_DIRECTORY}" ) # don't need to worry about nested modules (opengl/** are the only ones and @@ -70,7 +72,9 @@ function(pyigl_include prefix name) # https://stackoverflow.com/a/56514534/148668 set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${output_dir}" - RUNTIME_OUTPUT_DIRECTORY "${output_dir}") + RUNTIME_OUTPUT_DIRECTORY "${output_dir}" + LIBRARY_OUTPUT_DIRECTORY_RELEASE "${output_dir}" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${output_dir}") target_link_libraries( pyigl INTERFACE ${target_name}) endif() endfunction() @@ -87,6 +91,8 @@ target_include_directories(pyigl_classes PRIVATE "${PYLIBIGL_EXTERNAL}/numpyeige set_target_properties(pyigl_classes PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" RUNTIME_OUTPUT_DIRECTORY "${PYIGL_OUTPUT_DIRECTORY}" + LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PYIGL_OUTPUT_DIRECTORY}" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PYIGL_OUTPUT_DIRECTORY}" ) # Sort projects inside the solution From cba386ddbf1fc96874bb922bb50087acce9ea07d Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Wed, 8 Feb 2023 11:37:18 -0500 Subject: [PATCH 15/20] revert --- setup.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 682f099f..8b2884da 100644 --- a/setup.py +++ b/setup.py @@ -47,16 +47,17 @@ def build_extension(self, ext): # cmake_args += ['-DDEBUG_TRACE=ON'] if platform.system() == "Windows": - #cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] cmake_generator = os.environ.get('CMAKE_GENERATOR', '') - print(f"cmake_generator: {cmake_generator}") if cmake_generator != "NMake Makefiles" and "Ninja" not in cmake_generator: if sys.maxsize > 2**32: cmake_args += ['-A', 'x64'] # build_args += ['--', '/m'] + else: + if "MAX_JOBS" in os.environ: + build_args += ['--', f"-j{os.environ['MAX_JOBS']}"] + else: + build_args += ['--', '-j8'] - if not "CMAKE_BUILD_PARALLEL_LEVEL" in os.environ: - os.environ['CMAKE_BUILD_PARALLEL_LEVEL'] = "8" tmp = os.environ.get("AR", "") if "arm64-apple" in tmp: @@ -95,6 +96,7 @@ def build_extension(self, ext): if "arm" in tmp: cmake_args += ["-DCMAKE_OSX_ARCHITECTURES=arm64"] + # print(cmake_args) # tmp = os.getenv('CMAKE_ARGS', '') # if tmp: From 358fe779f637c36d4b0315a6bd8ad5e734b7c665 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 10 Feb 2023 14:12:30 -0500 Subject: [PATCH 16/20] cmake goop to make windows move gmp/mpfr to correct place --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e91e08d..1cdffc69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,8 +75,15 @@ function(pyigl_include prefix name) RUNTIME_OUTPUT_DIRECTORY "${output_dir}" LIBRARY_OUTPUT_DIRECTORY_RELEASE "${output_dir}" RUNTIME_OUTPUT_DIRECTORY_RELEASE "${output_dir}") + # why do this? target_link_libraries( pyigl INTERFACE ${target_name}) endif() + # https://stackoverflow.com/a/69736197/148668 + if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ $ + COMMAND_EXPAND_LISTS) + endif() endfunction() pyigl_include("copyleft" "cgal") From 4a1aae94ee1c7788e061b401ccd7e5faa8d2e3f8 Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 10 Feb 2023 18:34:39 -0500 Subject: [PATCH 17/20] bump dev version --- igl/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/igl/_version.py b/igl/_version.py index 3daaeb6c..d012cad6 100644 --- a/igl/_version.py +++ b/igl/_version.py @@ -1 +1 @@ -__version__ = "2.5.0dev" +__version__ = "2.5.1dev" From c2c56a2f599415a6be5de9fffaa2d4ce807bd2af Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 10 Feb 2023 21:56:35 -0500 Subject: [PATCH 18/20] bump libigl and version --- igl/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/igl/_version.py b/igl/_version.py index d012cad6..8ef6ae96 100644 --- a/igl/_version.py +++ b/igl/_version.py @@ -1 +1 @@ -__version__ = "2.5.1dev" +__version__ = "2.5.2dev" From 000d0d05e0f4d02d36f3e15de2076596dd243aeb Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Fri, 10 Feb 2023 21:56:45 -0500 Subject: [PATCH 19/20] bump libigl and version --- cmake/PyiglDependencies.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/PyiglDependencies.cmake b/cmake/PyiglDependencies.cmake index 22a62f34..12b5a912 100644 --- a/cmake/PyiglDependencies.cmake +++ b/cmake/PyiglDependencies.cmake @@ -19,7 +19,7 @@ include(FetchContent) FetchContent_Declare( libigl GIT_REPOSITORY https://github.com/libigl/libigl.git - GIT_TAG 4a91b88f81aa094d076ad4f1460ae663295ac518 + GIT_TAG 74f2f0e1e7dd8d9428689304b4a205c70cdb510e ) FetchContent_GetProperties(libigl) FetchContent_MakeAvailable(libigl) From 75626854ca582d8156aedeaf9516a307aee07ded Mon Sep 17 00:00:00 2001 From: Alec Jacobson Date: Sat, 11 Feb 2023 01:37:16 -0500 Subject: [PATCH 20/20] libigl version on main [ci skip] --- cmake/PyiglDependencies.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/PyiglDependencies.cmake b/cmake/PyiglDependencies.cmake index 12b5a912..d01f663f 100644 --- a/cmake/PyiglDependencies.cmake +++ b/cmake/PyiglDependencies.cmake @@ -19,7 +19,7 @@ include(FetchContent) FetchContent_Declare( libigl GIT_REPOSITORY https://github.com/libigl/libigl.git - GIT_TAG 74f2f0e1e7dd8d9428689304b4a205c70cdb510e + GIT_TAG 78015d4da1c6799dfe15659ed35adfb3a5f23ffa ) FetchContent_GetProperties(libigl) FetchContent_MakeAvailable(libigl)