diff --git a/CMakeLists.txt b/CMakeLists.txt index 0303a8f..8c6e10f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,11 +24,17 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_LIBDIR}) # Dynamic vs Static Linking -option(DYNAMIC_SOLID "Set to ON to build SOLID for dynamic linking. Use OFF for static." ON) +option(BUILD_SHARED_LIBS "Set to ON to build SOLID for dynamic linking. Use OFF for static." ON) -if(NOT DYNAMIC_SOLID) +if(NOT BUILD_SHARED_LIBS) add_definitions(-DSOLID_STATIC) -endif(NOT DYNAMIC_SOLID) +endif() + +option(USE_EXTERNAL_QHULL "Use external Qhull library." OFF) + +if(USE_EXTERNAL_QHULL) + find_package(Qhull REQUIRED) +endif() option(USE_DOUBLES "Use double-precision floating-point numbers." OFF) @@ -89,10 +95,10 @@ endif(MSVC) if(UNIX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -ffast-math -msse2 -mfpmath=sse") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -Wall -ffast-math -msse2 -mfpmath=sse") - if (DYNAMIC_SOLID) + if (BUILD_SHARED_LIBS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - endif(DYNAMIC_SOLID) + endif() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lrt") endif(UNIX) diff --git a/CMakeModules/FindQhull.cmake b/CMakeModules/FindQhull.cmake new file mode 100644 index 0000000..493c691 --- /dev/null +++ b/CMakeModules/FindQhull.cmake @@ -0,0 +1,46 @@ +include(FindPackageHandleStandardArgs) +include(SelectLibraryConfigurations) + +find_path(Qhull_REENTRANT_INCLUDE_DIRS NAMES libqhull_r/qhull_ra.h qhull_r/qhull_ra.h) + +mark_as_advanced(Qhull_REENTRANT_INCLUDE_DIRS) + +if(BUILD_SHARED_LIBS) + find_library(Qhull_REENTRANT_LIBRARY_DEBUG NAMES qhull_rd) + find_library(Qhull_REENTRANT_LIBRARY_RELEASE NAMES qhull_r) +else() + find_library(Qhull_REENTRANT_LIBRARY_DEBUG NAMES qhullstatic_rd) + find_library(Qhull_REENTRANT_LIBRARY_RELEASE NAMES qhullstatic_r) +endif() + +select_library_configurations(Qhull_REENTRANT) + +find_path(Qhull_NON_REENTRANT_INCLUDE_DIRS NAMES libqhull/qhull_a.h qhull/qhull_a.h) + +mark_as_advanced(Qhull_NON_REENTRANT_INCLUDE_DIRS) + +if(BUILD_SHARED_LIBS) + find_library(Qhull_NON_REENTRANT_LIBRARY_DEBUG NAMES qhull_d) + find_library(Qhull_NON_REENTRANT_LIBRARY_RELEASE NAMES qhull) +else() + find_library(Qhull_NON_REENTRANT_LIBRARY_DEBUG NAMES qhullstatic_d) + find_library(Qhull_NON_REENTRANT_LIBRARY_RELEASE NAMES qhullstatic) +endif() + +select_library_configurations(Qhull_NON_REENTRANT) + +if(Qhull_REENTRANT_INCLUDE_DIRS AND Qhull_REENTRANT_LIBRARIES) + set(Qhull_INCLUDE_DIRS ${Qhull_REENTRANT_INCLUDE_DIRS}) + set(Qhull_LIBRARIES ${Qhull_REENTRANT_LIBRARIES}) + set(QHull_REENTRANT_FOUND TRUE) +elseif(Qhull_NON_REENTRANT_INCLUDE_DIRS AND Qhull_NON_REENTRANT_LIBRARIES) + set(Qhull_INCLUDE_DIRS ${Qhull_NON_REENTRANT_INCLUDE_DIRS}) + set(Qhull_LIBRARIES ${Qhull_NON_REENTRANT_LIBRARIES}) + set(QHull_NON_REENTRANT_FOUND TRUE) +endif() + +find_package_handle_standard_args( + Qhull + FOUND_VAR Qhull_FOUND + REQUIRED_VARS Qhull_INCLUDE_DIRS Qhull_LIBRARIES +) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a4173c..355e1d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,16 @@ -add_subdirectory(qhull) +include(CheckIncludeFile) +include(CMakePushCheckState) -if(DYNAMIC_SOLID) - set(LIBRARY_TYPE "SHARED") +if(NOT USE_EXTERNAL_QHULL) + add_subdirectory(qhull) + set(QHULL_TARGET_OBJECTS $) +endif() + +if(BUILD_SHARED_LIBS) add_definitions(-DSOLID_DLL_EXPORT) -else(DYNAMIC_SOLID) - set(LIBRARY_TYPE "STATIC") +else() add_definitions(-DSOLID_STATIC) -endif(DYNAMIC_SOLID) +endif() include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/src/broad) @@ -19,7 +23,7 @@ set(SOLID_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/SOLID_types.h ) -add_library(solid3 ${LIBRARY_TYPE} +add_library(solid3 ${SOLID_PUBLIC_HEADERS} broad/BP_C-api.cpp broad/BP_Endpoint.h @@ -80,12 +84,34 @@ add_library(solid3 ${LIBRARY_TYPE} DT_RespTable.h DT_Scene.cpp DT_Scene.h - $ + ${QHULL_TARGET_OBJECTS} ) target_include_directories(solid3 INTERFACE $/${CMAKE_INSTALL_INCLUDEDIR}>) set_target_properties(solid3 PROPERTIES VERSION ${VERSION}) +if(USE_EXTERNAL_QHULL) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_INCLUDES ${Qhull_INCLUDE_DIRS}) + check_include_file(libqhull_r/qhull_ra.h HAVE_LIBQHULL_R_QHULL_RA_H) + if(HAVE_LIBQHULL_R_QHULL_RA_H) + add_definitions(-DHAVE_LIBQHULL_R_QHULL_RA_H) + else() + check_include_file(qhull_r/qhull_ra.h HAVE_QHULL_R_QHULL_RA_H) + if(HAVE_QHULL_R_QHULL_RA_H) + add_definitions(-DHAVE_QHULL_R_QHULL_RA_H) + else() + check_include_file(libqhull/qhull_a.h HAVE_LIBQHULL_QHULL_A_H) + if(HAVE_LIBQHULL_QHULL_A_H) + add_definitions(-DHAVE_LIBQHULL_QHULL_A_H) + endif() + endif() + endif() + cmake_pop_check_state() + target_include_directories(solid3 PRIVATE ${Qhull_INCLUDE_DIRS}) + target_link_libraries(solid3 PRIVATE ${Qhull_LIBRARIES}) +endif() + if(NOT CMAKE_VERSION VERSION_LESS 3.12) install( TARGETS solid3 @@ -102,7 +128,7 @@ else() LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime NAMELINK_SKIP RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime ) - if(DYNAMIC_SOLID) + if(BUILD_SHARED_LIBS) install( TARGETS solid3 EXPORT solid3 @@ -116,6 +142,6 @@ install( COMPONENT development ) -if(MSVC AND DYNAMIC_SOLID AND ${CMAKE_MAJOR_VERSION} GREATER 2 AND ${CMAKE_MINOR_VERSION} GREATER 0) +if(MSVC AND BUILD_SHARED_LIBS AND ${CMAKE_MAJOR_VERSION} GREATER 2 AND ${CMAKE_MINOR_VERSION} GREATER 0) install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS Debug RelWithDebInfo COMPONENT debug) endif() diff --git a/src/convex/DT_Polyhedron.cpp b/src/convex/DT_Polyhedron.cpp index 8bf8e8e..13ff633 100644 --- a/src/convex/DT_Polyhedron.cpp +++ b/src/convex/DT_Polyhedron.cpp @@ -26,7 +26,15 @@ #ifdef QHULL extern "C" { +#if HAVE_LIBQHULL_R_QHULL_RA_H +#include +#elif HAVE_QHULL_R_QHULL_RA_H +#include +#elif HAVE_LIBQHULL_QHULL_A_H +#include +#else #include +#endif } #include @@ -60,26 +68,49 @@ T_IndexBuf *adjacency_graph(DT_Count count, const MT_Point3 *verts, const char * } } - qh_init_A(stdin, stdout, stderr, 0, NULL); +#if defined(QHULL_LIB_TYPE) && QHULL_LIB_TYPE == QHULL_REENTRANT + qhT qh_qh; + qhT* qh = &qh_qh; + qh_init_A(qh, stdin, stdout, stderr, 0, NULL); + if ((exitcode = setjmp(qh->errexit))) +#else + qh_init_A(stdin, stdout, stderr, 0, NULL); if ((exitcode = setjmp(qh errexit))) +#endif { exit(exitcode); } +#if defined(QHULL_LIB_TYPE) && QHULL_LIB_TYPE == QHULL_REENTRANT + qh->NOerrexit = False; + qh_initflags(qh, options); + qh_init_B(qh, array[0], array.size(), 3, False); + qh_qhull(qh); + qh_check_output(qh); +#else qh_initflags(options); qh_init_B(array[0], array.size(), 3, False); qh_qhull(); qh_check_output(); +#endif T_IndexBuf *indexBuf = new T_IndexBuf[count]; FORALLfacets { +#if defined(QHULL_LIB_TYPE) && QHULL_LIB_TYPE == QHULL_REENTRANT + setT *vertices = qh_facet3vertex(qh, facet); +#else setT *vertices = qh_facet3vertex(facet); +#endif T_IndexBuf facetIndices; FOREACHvertex_(vertices) { +#if defined(QHULL_LIB_TYPE) && QHULL_LIB_TYPE == QHULL_REENTRANT + facetIndices.push_back(index[qh_pointid(qh, vertex->point)]); +#else facetIndices.push_back(index[qh_pointid(vertex->point)]); +#endif } int i, j; for (i = 0, j = facetIndices.size()-1; i < (int)facetIndices.size(); j = i++) @@ -89,9 +120,15 @@ T_IndexBuf *adjacency_graph(DT_Count count, const MT_Point3 *verts, const char * } +#if defined(QHULL_LIB_TYPE) && QHULL_LIB_TYPE == QHULL_REENTRANT + qh->NOerrexit = True; + qh_freeqhull(qh, !qh_ALL); + qh_memfreeshort(qh, &curlong, &totlong); +#else qh NOerrexit = True; qh_freeqhull(!qh_ALL); qh_memfreeshort(&curlong, &totlong); +#endif return indexBuf; }