From 92db3a4e72d822bc3786f8868b21ce86229de4e8 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Thu, 8 Dec 2011 11:35:11 +0000 Subject: [PATCH] First pass at Java wrappers (thanks to Benjamin Ruard <ruard@artenum.com>). ENABLE_SWIG has been replaced by ENABLE_WRAP_PYHTON and ENABLE_WRAP_JAVA. --- CMakeLists.txt | 108 +++++++++++++++++++++++++++++++++++------- Common/ListUtils.cpp | 5 ++ Common/ListUtils.h | 1 + Geo/GEdge.h | 3 +- Geo/GEntity.h | 6 +++ Geo/GFace.h | 3 +- Geo/MElement.cpp | 12 ++--- Geo/MElement.h | 2 +- Geo/MElementCut.h | 10 ++-- Geo/MTetrahedron.h | 2 +- gmshpy/CMakeLists.txt | 49 +++++++++++-------- 11 files changed, 144 insertions(+), 57 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51e82388f1..db807ff4e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,10 +53,11 @@ option(ENABLE_RBF "Enable RBF project" OFF) option(ENABLE_SALOME "Enable Salome routines for CAD healing" ON) option(ENABLE_SLEPC "Enable SLEPc eigensolvers" ON) option(ENABLE_SOLVER "Enable solver components" ON) -option(ENABLE_SWIG "Build Swig wrappers" ON) option(ENABLE_TAUCS "Enable Taucs linear algebra solver" ON) option(ENABLE_TETGEN "Enable Tetgen mesh generator" ON) option(ENABLE_TETGEN_NEW "Enable experimental version of Tetgen" OFF) +option(ENABLE_WRAP_JAVA "Build Java wrappers" OFF) +option(ENABLE_WRAP_PYTHON "Build Python wrappers" ON) set(GMSH_MAJOR_VERSION 2) set(GMSH_MINOR_VERSION 5) @@ -803,20 +804,6 @@ if(ENABLE_OSMESA) endif(OSMESA_LIB) endif(ENABLE_OSMESA) -if(ENABLE_SWIG) - find_package(SWIG) - find_package(PythonLibs) - if(SWIG_FOUND AND PYTHONLIBS_FOUND) - message(STATUS "Found SWIG version " ${SWIG_VERSION}) - string(SUBSTRING ${SWIG_VERSION} 0 1 SWIG_MAJOR_VERSION) - if(SWIG_MAJOR_VERSION EQUAL 1) - message("WARNING: Python bindings require SWIG >= 2: disabling Python") - else(SWIG_MAJOR_VERSION EQUAL 1) - set_config_option(HAVE_SWIG "Swig") - endif(SWIG_MAJOR_VERSION EQUAL 1) - endif(SWIG_FOUND AND PYTHONLIBS_FOUND) -endif(ENABLE_SWIG) - check_function_exists(vsnprintf HAVE_VSNPRINTF) if(NOT HAVE_VSNPRINTF) set_config_option(HAVE_NO_VSNPRINTF "NoVsnprintf") @@ -982,8 +969,6 @@ elseif(MSVC) set_target_properties(gmsh PROPERTIES LINK_FLAGS "/STACK:16777216") endif(WIN32 AND NOT MSVC OR CYGWIN) -add_subdirectory(gmshpy) - find_program(BISON bison) find_program(FLEX flex) if(BISON AND FLEX) @@ -1190,6 +1175,95 @@ else(APPLE AND ENABLE_APP_BUNDLE) set(CPACK_GENERATOR TGZ) endif(APPLE AND ENABLE_APP_BUNDLE) +if(ENABLE_WRAP_PYTHON) + find_package(SWIG) + find_package(PythonLibs) + if(SWIG_FOUND AND PYTHONLIBS_FOUND) + message(STATUS "Found SWIG version " ${SWIG_VERSION}) + string(SUBSTRING ${SWIG_VERSION} 0 1 SWIG_MAJOR_VERSION) + if(SWIG_MAJOR_VERSION EQUAL 1) + message("WARNING: Python bindings require SWIG >= 2: disabling Python") + else(SWIG_MAJOR_VERSION EQUAL 1) + add_subdirectory(gmshpy) + endif(SWIG_MAJOR_VERSION EQUAL 1) + endif(SWIG_FOUND AND PYTHONLIBS_FOUND) +endif(ENABLE_WRAP_PYTHON) + +if(ENABLE_WRAP_JAVA) + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/WrappingJava/src/main/java/org/geuz/gmsh/utils) + # flag used to compilation during Java wrapping + set(CMAKE_CXX_FLAGS "-fno-strict-aliasing") + # find SWIG and include the swig file + find_package(SWIG REQUIRED) + include(${SWIG_USE_FILE}) + # find Java and JNI and include files required + find_package(Java REQUIRED) + find_package(JNI REQUIRED) + include_directories(${JNI_INCLUDE_DIRS}) + include_directories(${JAVA_INCLUDE_PATH}) + include_directories(${JAVA_INCLUDE_PATH2}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + # define where the interface file (used by SWIG) are + set(SWIG_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WrapGmsh.i) + # let swig know that example.i is c++ + set_source_files_properties(${SWIG_SOURCES} PROPERTIES CPLUSPLUS ON) + # define where the Java files generated by SWIG will be stored + set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/org/geuz/gmsh/generated/) + # defines the packaging of Java files generated by SWIG + set(JAVAPACKAGENAME "org.geuz.gmsh.generated") + set(CMAKE_SWIG_FLAGS -package ${JAVAPACKAGENAME}) + # create the swig module called WrapGmsh + # using the SWIG_SOURCE flag defined previously + # swig will be used to create WrapGmshJAVA_wrap.cxx from SWIG_SOURCE + swig_add_module(WrapGmsh java ${SWIG_SOURCES}) + # link dynamic library called libWrapGmsh with the help of "shared" library + swig_link_libraries(WrapGmsh shared) + # define a good name for the dynamic libraty which depends on the OS + if(WIN32) + set_target_properties(WrapGmsh PROPERTIES PREFIX "") + endif(WIN32) + if(UNIX) + set_target_properties(WrapGmsh PROPERTIES PREFIX "lib") + endif(UNIX) + add_custom_command(TARGET gmsh + POST_BUILD # do the rest of the command after the build period + # write on the output consol + COMMAND cmake -E echo "Compiling Java files..." + #compilation of Java files generated by SWIG + COMMAND ${JAVA_COMPILE} + ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/org/geuz/gmsh/generated/*.java + -classpath ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + -d ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + # compilation of Java files used by wrapping + COMMAND ${JAVA_COMPILE} + ${CMAKE_CURRENT_SOURCE_DIR}/WrappingJava/src/main/java/org/geuz/gmsh/utils/*.java + -classpath ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + -d ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + # compilation of Java files used as demonstration + COMMAND ${JAVA_COMPILE} + ${CMAKE_CURRENT_SOURCE_DIR}/WrappingJava/src/main/java/com/artenum/sample/*.java + -classpath ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + -d ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + # create a jar file which contains the files with a .class extension + COMMAND cmake -E echo "Creating jar file..." + COMMAND ${JAVA_ARCHIVE} cvf ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/WrapGmsh.jar + -C ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ org + COMMAND ${JAVA_ARCHIVE} cvf ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/Sample.jar + -C ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ com + # create a jar from Sample + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/WrappingJava/src/main/java/t5.geo + ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/ + # copy the build.xml file to run the ant script + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/WrappingJava/build.xml + ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/) + install(TARGETS WrapGmsh shared DESTINATION lib OPTIONAL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/WrappingJava/WrapGmsh.jar + DESTINATION lib) +endif(ENABLE_WRAP_JAVA) + include(CPack) message("") diff --git a/Common/ListUtils.cpp b/Common/ListUtils.cpp index f9ef056c18..050ac635f3 100644 --- a/Common/ListUtils.cpp +++ b/Common/ListUtils.cpp @@ -98,6 +98,11 @@ void List_Add(List_T * liste, void *data) memcpy(&liste->array[(liste->n - 1) * liste->size], data, liste->size); } +void List_Add(List_T *liste, int data) +{ + List_Add(liste, &data); +} + int List_Nbr(List_T * liste) { return (liste) ? liste->n : 0; diff --git a/Common/ListUtils.h b/Common/ListUtils.h index af4f69102d..38cb00a0be 100644 --- a/Common/ListUtils.h +++ b/Common/ListUtils.h @@ -20,6 +20,7 @@ List_T *List_Create(int n, int incr, int size); void List_Delete(List_T *liste); void List_Realloc(List_T *liste,int n); void List_Add(List_T *liste, void *data); +void List_Add(List_T *liste, int data); int List_Nbr(List_T *liste); void List_Read(List_T *liste, int index, void *data); void List_Write(List_T *liste, int index, void *data); diff --git a/Geo/GEdge.h b/Geo/GEdge.h index 7f98689c58..77caffbccf 100644 --- a/Geo/GEdge.h +++ b/Geo/GEdge.h @@ -202,9 +202,8 @@ class GEdge : public GEntity { ExtrudeParams *extrude; } meshAttributes ; - typedef enum {PENDING, DONE, FAILED} meshGenerationStatus; struct { - mutable meshGenerationStatus status; + mutable GEntity::MeshGenerationStatus status; } meshStatistics; std::vector<MLine*> lines; diff --git a/Geo/GEntity.h b/Geo/GEntity.h index ff0f3ee981..004c1bdea4 100644 --- a/Geo/GEntity.h +++ b/Geo/GEntity.h @@ -110,6 +110,12 @@ class GEntity { PartitionSurface }; + enum MeshGenerationStatus { + PENDING, + DONE, + FAILED + }; + // return a string describing the entity type virtual std::string getTypeString() { diff --git a/Geo/GFace.h b/Geo/GFace.h index 35700f9068..6bd6561dff 100644 --- a/Geo/GFace.h +++ b/Geo/GFace.h @@ -290,9 +290,8 @@ class GFace : public GEntity // edge loops } meshAttributes ; - typedef enum {PENDING, DONE, FAILED} meshGenerationStatus; struct { - mutable meshGenerationStatus status; + mutable GEntity::MeshGenerationStatus status; double worst_element_shape, best_element_shape, average_element_shape; double smallest_edge_length, longest_edge_length, efficiency_index; int nbEdge, nbTriangle; diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index e5f2fed785..f63625cadd 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -690,7 +690,8 @@ void MElement::writeMSH(FILE *fp, double version, bool binary, int num, if(physical < 0) revert(); - int *verts = getVerticesIdForMSH(); + std::vector<int> verts; + getVerticesIdForMSH(verts); if(!binary){ for(int i = 0; i < n; i++) @@ -698,12 +699,10 @@ void MElement::writeMSH(FILE *fp, double version, bool binary, int num, fprintf(fp, "\n"); } else{ - fwrite(verts, sizeof(int), n, fp); + fwrite(&verts[0], sizeof(int), n, fp); } if(physical < 0) revert(); - - delete [] verts; } void MElement::writePOS(FILE *fp, bool printElementary, bool printElementNumber, @@ -1072,13 +1071,12 @@ int MElement::getInfoMSH(const int typeMSH, const char **const name) } } -int *MElement::getVerticesIdForMSH() +void MElement::getVerticesIdForMSH(std::vector<int> &verts) { int n = getNumVerticesForMSH(); - int *verts = new int[n]; + verts.resize(n); for(int i = 0; i < n; i++) verts[i] = getVertex(i)->getIndex(); - return verts; } MElement *MElement::copy(std::map<int, MVertex*> &vertexMap, diff --git a/Geo/MElement.h b/Geo/MElement.h index 63b58ccc74..d19e1e6a5f 100644 --- a/Geo/MElement.h +++ b/Geo/MElement.h @@ -334,7 +334,7 @@ class MElement // 'name' != 0 static int getInfoMSH(const int typeMSH, const char **const name=0); virtual int getNumVerticesForMSH() { return getNumVertices(); } - virtual int *getVerticesIdForMSH(); + virtual void getVerticesIdForMSH(std::vector<int> &verts); // copy element and parent if any, vertexMap contains the new vertices virtual MElement *copy(std::map<int, MVertex*> &vertexMap, diff --git a/Geo/MElementCut.h b/Geo/MElementCut.h index ae33a5ef76..4cda79f64e 100644 --- a/Geo/MElementCut.h +++ b/Geo/MElementCut.h @@ -159,14 +159,13 @@ class MPolyhedron : public MElement { virtual MElement *getChild(int i) const { return _parts[i]; } virtual bool ownsParent() const { return _owner; } virtual int getNumVerticesForMSH() {return _parts.size() * 4;} - virtual int *getVerticesIdForMSH() + virtual void getVerticesIdForMSH(std::vector<int> &verts) { int n = getNumVerticesForMSH(); - int *verts = new int [n]; + verts.resize(n); for(unsigned int i = 0; i < _parts.size(); i++) for(int j = 0; j < 4; j++) verts[i * 4 + j] = _parts[i]->getVertex(j)->getIndex(); - return verts; } }; @@ -296,14 +295,13 @@ class MPolygon : public MElement { virtual bool isInside(double u, double v, double w); virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts); virtual int getNumVerticesForMSH() {return _parts.size() * 3;} - virtual int *getVerticesIdForMSH() + virtual void getVerticesIdForMSH(std::vector<int> &verts) { int n = getNumVerticesForMSH(); - int *verts = new int[n]; + verts.resize(n); for(unsigned int i = 0; i < _parts.size(); i++) for(int j = 0; j < 3; j++) verts[i * 3 + j] = _parts[i]->getVertex(j)->getIndex(); - return verts; } }; diff --git a/Geo/MTetrahedron.h b/Geo/MTetrahedron.h index 28ff1cd892..017addbae3 100644 --- a/Geo/MTetrahedron.h +++ b/Geo/MTetrahedron.h @@ -306,7 +306,7 @@ class MTetrahedron10 : public MTetrahedron { */ class MTetrahedronN : public MTetrahedron { - const static std::vector<int> &_getReverseIndices(int order); + static const std::vector<int> &_getReverseIndices(int order); protected: std::vector<MVertex *> _vs; const char _order; diff --git a/gmshpy/CMakeLists.txt b/gmshpy/CMakeLists.txt index 3bf96b4627..70a220b16b 100644 --- a/gmshpy/CMakeLists.txt +++ b/gmshpy/CMakeLists.txt @@ -1,4 +1,9 @@ -set (SWIG_MODULES +# Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle +# +# See the LICENSE.txt file for license information. Please report all +# bugs and problems to <gmsh@geuz.org>. + +set(SWIG_MODULES gmshCommon gmshGeo gmshNumeric @@ -15,7 +20,6 @@ MACRO(SWIG_GET_WRAPPER_DEPENDENCIES swigFile genWrapper language DEST_VARIABLE) IF("${swig_getdeps_extra_flags}" STREQUAL "NOTFOUND") SET(swig_getdeps_extra_flags "") ENDIF("${swig_getdeps_extra_flags}" STREQUAL "NOTFOUND") - IF(NOT swig_getdeps_outdir) SET(swig_getdeps_outdir ${CMAKE_CURRENT_BINARY_DIR}) ENDIF(NOT swig_getdeps_outdir) @@ -58,28 +62,31 @@ ENDMACRO(SWIG_GET_WRAPPER_DEPENDENCIES) option(ENABLE_PYTHON_LIB_API "Export all C header files needed to build the python library" OFF) if(ENABLE_PYTHON_LIB_API) - set(GMSH_API ${GMSH_API} Geo/Curvature.h Mesh/Generator.h Mesh/highOrderTools.h Mesh/meshGFaceLloyd.h Numeric/DivideAndConquer.h Post/PViewFactory.h Solver/linearSystemPETSc.h Fltk/FlGui.h Solver/functionSpace.h Solver/STensor43.h Solver/sparsityPattern.h Solver/SElement.h Solver/groupOfElements.h PARENT_SCOPE) + set(GMSH_API ${GMSH_API} Geo/Curvature.h Mesh/Generator.h Mesh/highOrderTools.h + Mesh/meshGFaceLloyd.h Numeric/DivideAndConquer.h Post/PViewFactory.h + Solver/linearSystemPETSc.h Fltk/FlGui.h Solver/functionSpace.h + Solver/STensor43.h Solver/sparsityPattern.h Solver/SElement.h + Solver/groupOfElements.h PARENT_SCOPE) endif(ENABLE_PYTHON_LIB_API) -if(HAVE_SWIG) - include(${SWIG_USE_FILE}) - include_directories(${PYTHON_INCLUDE_DIR}) +include(${SWIG_USE_FILE}) +include_directories(${PYTHON_INCLUDE_DIR}) - foreach(module ${SWIG_MODULES}) - set_source_files_properties(${module}.i PROPERTIES CPLUSPLUS ON) +foreach(module ${SWIG_MODULES}) + set_source_files_properties(${module}.i PROPERTIES CPLUSPLUS ON) - # code backported from CMake git version, see CMake bug 4147 - SWIG_GET_WRAPPER_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/\${module}.i ${CMAKE_CURRENT_BINARY_DIR}/${module}PYTHON_wrap.cxx python swig_extra_dependencies) - LIST(APPEND SWIG_MODULE_${module}_EXTRA_DEPS ${swig_extra_dependencies}) + # code backported from CMake git version, see CMake bug 4147 + swig_get_wrapper_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/\${module}.i + ${CMAKE_CURRENT_BINARY_DIR}/${module}PYTHON_wrap.cxx python swig_extra_dependencies) + list(APPEND SWIG_MODULE_${module}_EXTRA_DEPS ${swig_extra_dependencies}) + swig_add_module(${module} python ${module}.i) + swig_link_libraries(${module} ${PYTHON_LIBRARIES} shared) + set(GMSH_PYTHON_MODULES_INCLUDE_CODE + "${GMSH_PYTHON_MODULES_INCLUDE_CODE}from ${module} import *\n") + list(APPEND GMSHPY_DEPENDS "_${module}") +endforeach(module) - swig_add_module(${module} python ${module}.i) - swig_link_libraries(${module} ${PYTHON_LIBRARIES} shared) - SET(GMSH_PYTHON_MODULES_INCLUDE_CODE - "${GMSH_PYTHON_MODULES_INCLUDE_CODE}from ${module} import *\n") - list(APPEND GMSHPY_DEPENDS "_${module}") - endforeach(module) - add_custom_target("_gmshpy" DEPENDS ${GMSHPY_DEPENDS}) +add_custom_target("_gmshpy" DEPENDS ${GMSHPY_DEPENDS}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in - ${CMAKE_CURRENT_BINARY_DIR}/__init__.py) -endif(HAVE_SWIG) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in + ${CMAKE_CURRENT_BINARY_DIR}/__init__.py) -- GitLab