diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 85d70d56..86105bfb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,25 +5,10 @@ stages: - cleanup ############################################ -# System templates +# Windows ############################################ -# Windows -.template_windows_32: &win32 - tags: - - windows - - x86 - before_script: - - "echo off" - - 'call "%VS140COMNTOOLS%\..\..\VC\bin\vcvars32.bat"' - - set CMAKE_GENERATOR=Visual Studio 14 2015 - - set CI_DIR=C:\ci\%CI_BUILD_REF%_32 - - set NETGEN_BUILD_DIR=%CI_DIR%\build - - set INSTALL_DIR=%CI_DIR%\install - - set NETGENDIR=%INSTALL_DIR%\bin - - set PYTHONPATH=%INSTALL_DIR%\lib\site-packages - -.template_windows_64: &win64 +.template_windows: &win tags: - windows - x64 @@ -31,29 +16,14 @@ stages: - "echo off" - 'call "%VS140COMNTOOLS%\..\..\VC\bin\amd64\vcvars64.bat"' - set CMAKE_GENERATOR=Visual Studio 14 2015 Win64 - - set CI_DIR=C:\ci\%CI_BUILD_REF%_64 + - set CI_DIR=C:\ci\%CI_PIPELINE_ID% - set NETGEN_BUILD_DIR=%CI_DIR%\build - set INSTALL_DIR=%CI_DIR%\install - set NETGENDIR=%INSTALL_DIR%\bin - set PYTHONPATH=%INSTALL_DIR%\lib\site-packages -# Linux -.template_ubuntu: &ubuntu - tags: - - linux - before_script: - - pwd - - ls - - docker info - variables: - UBUNTU_VERSION: "18.04" - -############################################ -# Build stage -############################################ - -# Windows -.template_build_win: &tbuild_netgen_win +build_win: + <<: *win stage: build script: - git submodule update --init --recursive @@ -68,26 +38,42 @@ stages: -DCMAKE_BUILD_TYPE=Release - cmake --build . --target INSTALL --config Release -.build_netgen_win32: - <<: *win32 - <<: *tbuild_netgen_win - cache: - paths: - - build/ - - src/ - key: "netgen_win32_${CI_BUILD_REF_NAME}" +test_win: + <<: *win + stage: test + script: + - cd %NETGEN_BUILD_DIR%\netgen + - ctest -C Release -V + - cd .. -build_netgen_win64: - <<: *win64 - <<: *tbuild_netgen_win - cache: - paths: - - build/ - - src/ - key: "netgen_win64_${CI_BUILD_REF_NAME}" +cleanup_win: + <<: *win + stage: cleanup + tags: + - windows + - x64 + script: + - cd %CI_PROJECT_DIR% + - rd /s /q %CI_DIR% + when: always + allow_failure: true -# Linux -.template_build_linux: &build_linux +############################################ +# Ubuntu/Linux +############################################ + +.template_ubuntu: &ubuntu + tags: + - linux + before_script: + - pwd + - ls + - docker info + variables: + UBUNTU_VERSION: "18.04" + +build_ubuntu: + <<: *ubuntu stage: build script: - docker build -t netgen_${CI_BUILD_REF_NAME}:${UBUNTU_VERSION} -f tests/dockerfile . @@ -96,34 +82,8 @@ build_netgen_win64: - docker commit `cat netgen_${CI_BUILD_REF_NAME}_${UBUNTU_VERSION}.id` netgen_${CI_BUILD_REF_NAME}_installed:${UBUNTU_VERSION} - rm netgen_${CI_BUILD_REF_NAME}_${UBUNTU_VERSION}.id -build_ubuntu: +test_ubuntu: <<: *ubuntu - <<: *build_linux - - -############################################ -# Test stage -############################################ - -# Windows -.template_test_win: &test_win - stage: test - script: - - cd %NETGEN_BUILD_DIR%/netgen - - ctest -C Release -V - - cd .. - -# skip since we have no machine with 32 bits -.test_win32: - <<: *win32 - <<: *test_win - -test_win64: - <<: *win64 - <<: *test_win - -# Linux -.template_test_linux: &test_linux stage: test script: - >- @@ -133,10 +93,6 @@ test_win64: netgen_${CI_BUILD_REF_NAME}_installed:${UBUNTU_VERSION} bash -c 'cd /root/build/netgen && make test_netgen ARGS="-V"' -test_ubuntu: - <<: *ubuntu - <<: *test_linux - # cpp guideline checks test_guidelines: <<: *ubuntu @@ -144,6 +100,70 @@ test_guidelines: script: - docker run -e CCACHE_DIR=/ccache -v /mnt/ccache:/ccache netgen_${CI_BUILD_REF_NAME}:${UBUNTU_VERSION} bash /root/src/netgen/tests/build_guidelines.sh when: always + +cleanup_ubuntu: + stage: cleanup + tags: + - linux + script: + # remove intermediate and old docker images and containers + - docker rm -f `docker ps --no-trunc -aq` + - docker images --no-trunc -aqf "dangling=true" | xargs docker rmi -f || true + when: always + allow_failure: true + +############################################ +# MacOSX +############################################ + +.template_mac: &mac + tags: + - mac + before_script: + - export ROOT_DIR=/tmp/$CI_PIPELINE_ID + - export SRC_DIR=$ROOT_DIR/src + - export BUILD_DIR=$ROOT_DIR/build + - export CMAKE_INSTALL_PREFIX=/tmp/$CI_PIPELINE_ID/install/Netgen.app + - export PYTHONPATH=$CMAKE_INSTALL_PREFIX/Contents/Resources/`python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1,0,''))"`:. + - export PATH=$CMAKE_INSTALL_PREFIX/Contents/MacOS:$PATH + +build_mac: + <<: *mac + stage: build + script: + - git submodule update --init --recursive + - rm -rf $BUILD_DIR + - mkdir -p $BUILD_DIR + - rm -rf $SRC_DIR + - mkdir -p $SRC_DIR + - cp -a . $SRC_DIR/ + - cd $BUILD_DIR + - >- + cmake $SRC_DIR + -DCMAKE_INSTALL_PREFIX=$CMAKE_INSTALL_PREFIX + -DCMAKE_BUILD_TYPE=Release + -DUSE_NATIVE_ARCH=OFF + -DUSE_CCACHE=ON + -DENABLE_UNIT_TESTS=ON + -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 + -DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk + - make -j5 install + +test_mac: + <<: *mac + stage: test + script: + - cd $BUILD_DIR/netgen + - ctest . --output-on-failure + +cleanup_mac: + <<: *mac + stage: cleanup + script: + - rm -rf $ROOT_DIR + when: always + allow_failure: true + ############################################ # Deploy stage ############################################ @@ -163,43 +183,3 @@ deploy_sourceforge: - git push github master only: - master - -############################################ -# Cleanup stage -############################################ - -linux_cleanup: - stage: cleanup - tags: - - linux - script: - # remove intermediate and old docker images and containers - - docker rm -f `docker ps --no-trunc -aq` - - docker images --no-trunc -aqf "dangling=true" | xargs docker rmi -f - when: always - allow_failure: true - -win64_cleanup: - <<: *win64 - stage: cleanup - tags: - - windows - - x64 - script: - - cd %CI_PROJECT_DIR% - - rd /s /q %CI_DIR% - when: always - allow_failure: true - -.win32_cleanup: - <<: *win32 - stage: cleanup - tags: - - windows - - x86 - script: - - cd %CI_PROJECT_DIR% - - rd /s /q %CI_DIR% - when: always - allow_failure: true - diff --git a/cmake/external_projects/tcltk.cmake b/cmake/external_projects/tcltk.cmake index 7b174a7c..b7f0ba85 100644 --- a/cmake/external_projects/tcltk.cmake +++ b/cmake/external_projects/tcltk.cmake @@ -37,7 +37,7 @@ if(APPLE) URL_MD5 a6d47a996ea957416469b12965d4db91 DEPENDS project_tcl project_tk DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external_dependencies - PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_LIST_DIR}/tkdnd_macosx.patch + PATCH_COMMAND patch < ${CMAKE_CURRENT_LIST_DIR}/tkdnd_macosx.patch UPDATE_COMMAND "" # Disable update BUILD_IN_SOURCE 1 CMAKE_ARGS diff --git a/cmake/external_projects/tkdnd_macosx.patch b/cmake/external_projects/tkdnd_macosx.patch index e6af1974..7e97a39a 100644 --- a/cmake/external_projects/tkdnd_macosx.patch +++ b/cmake/external_projects/tkdnd_macosx.patch @@ -1,21 +1,20 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 4eb497c..c6424fc 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -43,17 +43,17 @@ IF ( WIN32 ) +--- CMakeLists.txt 19:24:32.000000000 +0200 ++++ CMakeLists.txt 2018-12-05 11:34:59.000000000 +0100 +@@ -43,17 +43,18 @@ ELSE ( WIN32 ) ## Unix and OS X... IF ( APPLE ) - SET ( CMAKE_OSX_ARCHITECTURES "x86_64;i386" ) + SET ( CMAKE_OSX_ARCHITECTURES "x86_64") ++ SET( TK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../project_tk/) ++ SET( TCL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../project_tcl/) FIND_LIBRARY ( COCOA_LIBRARY Cocoa ) INCLUDE_DIRECTORIES ( macosx ) - INCLUDE_DIRECTORIES ( /Library/Frameworks/Tk.framework/Versions/8.6/PrivateHeaders ) - INCLUDE_DIRECTORIES ( /System/Library/Frameworks/Tk.framework/Versions/8.5/Headers/tk-private ) - INCLUDE_DIRECTORIES ( /System/Library/Frameworks/Tk.framework/Versions/8.5/Headers/tk-private ) -+# INCLUDE_DIRECTORIES ( /Library/Frameworks/Tk.framework/Versions/8.6/PrivateHeaders ) -+# INCLUDE_DIRECTORIES ( /System/Library/Frameworks/Tk.framework/Versions/8.5/Headers/tk-private ) -+# INCLUDE_DIRECTORIES ( /System/Library/Frameworks/Tk.framework/Versions/8.5/Headers/tk-private ) ++ INCLUDE_DIRECTORIES ( ${TCL_DIR}/macosx ${TCL_DIR}/generic ) ++ INCLUDE_DIRECTORIES ( ${TK_DIR}/macosx ${TK_DIR}/generic ${TK_DIR}/xlib ) ADD_DEFINITIONS ( -DMAC_TK_COCOA -DMAC_OSX_TK) ADD_DEFINITIONS ( -DMAC_OSX_TK ) ADD_DEFINITIONS ( -std=gnu99 ) @@ -25,12 +24,32 @@ index 4eb497c..c6424fc 100644 ADD_DEFINITIONS ( -fno-objc-arc ) # ADD_DEFINITIONS ( -fobjc-arc ) LINK_LIBRARIES ( ${COCOA_LIBRARY} ) -@@ -125,7 +125,7 @@ SET ( CP ${CMAKE_COMMAND} -E copy ) +@@ -125,8 +126,8 @@ ## Locate Tcl/Tk ## =========================================================================== MESSAGE ( STATUS "Searching for Tcl/Tk..." ) -FIND_PACKAGE ( TCL REQUIRED ) +-FIND_PACKAGE ( TclStub REQUIRED ) +#FIND_PACKAGE ( TCL REQUIRED ) - FIND_PACKAGE ( TclStub REQUIRED ) ++#FIND_PACKAGE ( TclStub REQUIRED ) ## Tcl/Tk info (useful for debug purposes)... + # MESSAGE ( STATUS " TCL_TCLSH: " ${TCL_TCLSH} ) +@@ -139,13 +140,13 @@ + # MESSAGE ( STATUS " TK_LIBRARY: " ${TK_LIBRARY} ) + + ## Enable Tcl/Tk stubs globally... +-ADD_DEFINITIONS ( -DUSE_TCL_STUBS ) +-ADD_DEFINITIONS ( -DUSE_TK_STUBS ) ++#ADD_DEFINITIONS ( -DUSE_TCL_STUBS ) ++#ADD_DEFINITIONS ( -DUSE_TK_STUBS ) + ADD_DEFINITIONS ( -DTCL_THREADS ) + INCLUDE_DIRECTORIES ( ${TCL_INCLUDE_PATH} ) + INCLUDE_DIRECTORIES ( ${TK_INCLUDE_PATH} ) +-LINK_LIBRARIES ( ${TCL_STUB_LIBRARY} ) +-LINK_LIBRARIES ( ${TK_STUB_LIBRARY} ) ++LINK_LIBRARIES ( ${TCL_LIBRARY} ) ++LINK_LIBRARIES ( ${TK_LIBRARY} ) + + IF ( WIN32 AND NO_MSVCRT ) + STRING ( REPLACE /MD /MT CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} ) diff --git a/libsrc/core/archive.hpp b/libsrc/core/archive.hpp index c69fa293..3dfe1baa 100644 --- a/libsrc/core/archive.hpp +++ b/libsrc/core/archive.hpp @@ -522,9 +522,9 @@ namespace ngcore // BinaryOutArchive ====================================================================== class NGCORE_API BinaryOutArchive : public Archive { - size_t ptr = 0; static constexpr size_t BUFFERSIZE = 1024; - alignas(64) char buffer[BUFFERSIZE] = {}; + char buffer[BUFFERSIZE] = {}; + size_t ptr = 0; std::shared_ptr fout; public: BinaryOutArchive() = delete; diff --git a/libsrc/csg/csgeom.cpp b/libsrc/csg/csgeom.cpp index b861d451..87cae1b4 100644 --- a/libsrc/csg/csgeom.cpp +++ b/libsrc/csg/csgeom.cpp @@ -1592,5 +1592,5 @@ namespace netgen }; CSGInit csginit; - + static RegisterClassForArchive regcsg; } diff --git a/libsrc/csg/csgeom.hpp b/libsrc/csg/csgeom.hpp index f1a8d8b6..f82407b4 100644 --- a/libsrc/csg/csgeom.hpp +++ b/libsrc/csg/csgeom.hpp @@ -177,14 +177,14 @@ namespace netgen void Clean (); - virtual void Save (string filename) const; + virtual void Save (string filename) const override; void Save (ostream & ost) const; void Load (istream & ist); void SaveSurfaces (ostream & out) const; void LoadSurfaces (istream & in); - virtual void SaveToMeshFile (ostream & ost) const; + virtual void SaveToMeshFile (ostream & ost) const override; int GetChangeVal() { return changeval; } void Change() { changeval++; } @@ -211,7 +211,7 @@ namespace netgen const SplineGeometry<2> * GetSplineCurve2d (const string & name) const; const SplineGeometry<3> * GetSplineCurve3d (const string & name) const; - void DoArchive(Archive& archive); + void DoArchive(Archive& archive) override; void SetFlags (const char * solidname, const Flags & flags); @@ -344,9 +344,9 @@ namespace netgen Array bcmodifications; - virtual int GenerateMesh (shared_ptr & mesh, MeshingParameters & mparam); + virtual int GenerateMesh (shared_ptr & mesh, MeshingParameters & mparam) override; - virtual const Refinement & GetRefinement () const; + virtual const Refinement & GetRefinement () const override; void AddSplineSurface (shared_ptr ss) { spline_surfaces.Append(ss); } }; diff --git a/libsrc/geom2d/geometry2d.cpp b/libsrc/geom2d/geometry2d.cpp index 6bc93c57..f18dd335 100644 --- a/libsrc/geom2d/geometry2d.cpp +++ b/libsrc/geom2d/geometry2d.cpp @@ -1034,5 +1034,6 @@ namespace netgen }; SplineGeoInit sginit; - + static RegisterClassForArchive, NetgenGeometry> regspg2; + static RegisterClassForArchive> regssext; } diff --git a/libsrc/geom2d/geometry2d.hpp b/libsrc/geom2d/geometry2d.hpp index d9704577..52e7a20e 100644 --- a/libsrc/geom2d/geometry2d.hpp +++ b/libsrc/geom2d/geometry2d.hpp @@ -151,7 +151,11 @@ namespace netgen void TestComment ( ifstream & infile ) ; - + void DoArchive(Archive& ar) + { + SplineGeometry<2>::DoArchive(ar); + ar & materials & maxh & quadmeshing & tensormeshing & layer & bcnames & elto0; + } const SplineSegExt & GetSpline (const int i) const { diff --git a/libsrc/geom2d/python_geom2d.cpp b/libsrc/geom2d/python_geom2d.cpp index d6abe3b8..1fc34f99 100644 --- a/libsrc/geom2d/python_geom2d.cpp +++ b/libsrc/geom2d/python_geom2d.cpp @@ -19,15 +19,30 @@ DLL_HEADER void ExportGeom2d(py::module &m) (m, "SplineGeometry", "a 2d boundary representation geometry model by lines and splines") .def(py::init<>()) - .def("__init__", - [](SplineGeometry2d *instance, const string & filename) - { - cout << "load geometry"; - ifstream ist(filename); - new (instance) SplineGeometry2d(); - instance->Load (filename.c_str()); - ng_geometry = shared_ptr(instance, NOOP_Deleter); - }) + .def(py::init([](const string& filename) + { + auto geo = make_shared(); + geo->Load(filename.c_str()); + ng_geometry = geo; + return geo; + })) + .def(py::pickle( + [](SplineGeometry2d& self) + { + auto ss = make_shared(); + BinaryOutArchive archive(ss); + archive & self; + archive.FlushBuffer(); + return py::make_tuple(py::bytes(ss->str())); + }, + [](py::tuple state) + { + auto geo = make_shared(); + auto ss = make_shared (py::cast(state[0])); + BinaryInArchive archive(ss); + archive & (*geo); + return geo; + })) .def("Load",&SplineGeometry2d::Load) .def("AppendPoint", FunctionPointer diff --git a/libsrc/gprim/splinegeometry.cpp b/libsrc/gprim/splinegeometry.cpp index 7cb75cb0..213f5224 100644 --- a/libsrc/gprim/splinegeometry.cpp +++ b/libsrc/gprim/splinegeometry.cpp @@ -129,6 +129,8 @@ namespace netgen template class SplineGeometry<2>; template class SplineGeometry<3>; + static RegisterClassForArchive> regsp2; + static RegisterClassForArchive> regsp3; } diff --git a/libsrc/gprim/splinegeometry.hpp b/libsrc/gprim/splinegeometry.hpp index 8e01cc62..14a28b4b 100644 --- a/libsrc/gprim/splinegeometry.hpp +++ b/libsrc/gprim/splinegeometry.hpp @@ -34,6 +34,11 @@ namespace netgen DLL_HEADER int Load (const Array & raw_data, const int startpos = 0); + virtual void DoArchive(Archive& ar) + { + ar & geompoints & splines; + } + DLL_HEADER void GetRawData (Array & raw_data) const; @@ -55,11 +60,6 @@ namespace netgen // void SetGrading (const double grading); DLL_HEADER void AppendPoint (const Point & p, const double reffac = 1., const bool hpref = false); - void DoArchive(Archive& ar) - { - ar & geompoints & splines; - } - void AppendSegment(SplineSeg * spline) { splines.Append (spline); diff --git a/libsrc/meshing/basegeom.cpp b/libsrc/meshing/basegeom.cpp index 1de6af28..e9b9aa5e 100644 --- a/libsrc/meshing/basegeom.cpp +++ b/libsrc/meshing/basegeom.cpp @@ -74,4 +74,5 @@ namespace netgen throw NgException("Cannot save geometry - no geometry available"); } + static RegisterClassForArchive regnggeo; } diff --git a/libsrc/meshing/basegeom.hpp b/libsrc/meshing/basegeom.hpp index 0637e915..ceb703f2 100644 --- a/libsrc/meshing/basegeom.hpp +++ b/libsrc/meshing/basegeom.hpp @@ -22,6 +22,9 @@ namespace netgen virtual const Refinement & GetRefinement () const; + virtual void DoArchive(Archive&) + { throw NgException("DoArchive not implemented for " + Demangle(typeid(*this).name())); } + virtual void Save (string filename) const; virtual void SaveToMeshFile (ostream & /* ost */) const { ; } }; diff --git a/libsrc/meshing/curvedelems.hpp b/libsrc/meshing/curvedelems.hpp index 99747034..29c911aa 100644 --- a/libsrc/meshing/curvedelems.hpp +++ b/libsrc/meshing/curvedelems.hpp @@ -48,6 +48,11 @@ public: int GetOrder () { return order; } + virtual void DoArchive(Archive& ar) + { + ar & edgeorder & faceorder & edgecoeffsindex & facecoeffsindex & edgecoeffs & facecoeffs + & edgeweight & order & rational & ishighorder; + } bool IsSegmentCurved (SegmentIndex segnr) const; bool IsSurfaceElementCurved (SurfaceElementIndex sei) const; diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp index 9ec9aed3..cee29d51 100644 --- a/libsrc/meshing/meshclass.cpp +++ b/libsrc/meshing/meshclass.cpp @@ -1316,27 +1316,8 @@ namespace netgen archive & *ident; - - // archive geometry - if (archive.Output()) - { - ostringstream ost; - if (geometry) - geometry -> SaveToMeshFile (ost); - archive << ost.str(); - archive << (geometry ? curvedelems->GetOrder() : 1); - } - else - { - string str; - archive & str; - istringstream ist(str); - geometry = geometryregister.LoadFromMeshFile (ist); - int order; - archive & order; - if(geometry && order > 1) - BuildCurvedElements(order); - } + archive & geometry; + archive & *curvedelems; if (archive.Input()) { diff --git a/libsrc/meshing/python_mesh.cpp b/libsrc/meshing/python_mesh.cpp index 8ec6a73a..de97e28d 100644 --- a/libsrc/meshing/python_mesh.cpp +++ b/libsrc/meshing/python_mesh.cpp @@ -488,7 +488,7 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) auto mesh = make_shared(); mesh -> SetDimension(dim); SetGlobalMesh(mesh); // for visualization - mesh -> SetGeometry (make_shared()); + mesh -> SetGeometry (nullptr); return mesh; } ), py::arg("dim")=3 @@ -565,8 +565,6 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) break; } } - if (!ng_geometry) - ng_geometry = make_shared(); self.SetGeometry(ng_geometry); delete infile; }),py::call_guard()) diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp index d8aeff4a..cc721e57 100644 --- a/libsrc/occ/occgeom.cpp +++ b/libsrc/occ/occgeom.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "ShapeAnalysis_ShapeTolerance.hxx" #include "ShapeAnalysis_ShapeContents.hxx" #include "ShapeAnalysis_CheckSmallFace.hxx" @@ -1106,94 +1107,8 @@ void STEP_GetEntityName(const TopoDS_Shape & theShape, STEPCAFControl_Reader * a // } - - // Philippose - 23/02/2009 - /* Special IGES File load function including the ability - to extract individual surface colours via the extended - OpenCascade XDE and XCAF Feature set. - */ - OCCGeometry *LoadOCC_IGES(const char *filename) - { - OCCGeometry *occgeo; - occgeo = new OCCGeometry; - - // Initiate a dummy XCAF Application to handle the IGES XCAF Document - static Handle_XCAFApp_Application dummy_app = XCAFApp_Application::GetApplication(); - - // Create an XCAF Document to contain the IGES file itself - Handle_TDocStd_Document iges_doc; - - // Check if a IGES File is already open under this handle, if so, close it to prevent - // Segmentation Faults when trying to create a new document - if(dummy_app->NbDocuments() > 0) - { - dummy_app->GetDocument(1,iges_doc); - dummy_app->Close(iges_doc); - } - dummy_app->NewDocument ("IGES-XCAF",iges_doc); - - IGESCAFControl_Reader reader; - - Standard_Integer stat = reader.ReadFile((char*)filename); - - if(stat != IFSelect_RetDone) - { - delete occgeo; - return NULL; - } - - // Enable transfer of colours - reader.SetColorMode(Standard_True); - - reader.Transfer(iges_doc); - - // Read in the shape(s) and the colours present in the IGES File - Handle_XCAFDoc_ShapeTool iges_shape_contents = XCAFDoc_DocumentTool::ShapeTool(iges_doc->Main()); - Handle_XCAFDoc_ColorTool iges_colour_contents = XCAFDoc_DocumentTool::ColorTool(iges_doc->Main()); - - TDF_LabelSequence iges_shapes; - iges_shape_contents->GetShapes(iges_shapes); - - // List out the available colours in the IGES File as Colour Names - TDF_LabelSequence all_colours; - iges_colour_contents->GetColors(all_colours); - PrintMessage(1,"Number of colours in IGES File: ",all_colours.Length()); - for(int i = 1; i <= all_colours.Length(); i++) - { - Quantity_Color col; - stringstream col_rgb; - iges_colour_contents->GetColor(all_colours.Value(i),col); - col_rgb << " : (" << col.Red() << "," << col.Green() << "," << col.Blue() << ")"; - PrintMessage(1, "Colour [", i, "] = ",col.StringName(col.Name()),col_rgb.str()); - } - - - // For the IGES Reader, all the shapes can be exported as one compound shape - // using the "OneShape" member - occgeo->shape = reader.OneShape(); - occgeo->face_colours = iges_colour_contents; - occgeo->changed = 1; - occgeo->BuildFMap(); - - occgeo->CalcBoundingBox(); - PrintContents (occgeo); - - return occgeo; - } - - - - - - // Philippose - 29/01/2009 - /* Special STEP File load function including the ability - to extract individual surface colours via the extended - OpenCascade XDE and XCAF Feature set. - */ - OCCGeometry * LoadOCC_STEP (const char * filename) - { - OCCGeometry * occgeo; - occgeo = new OCCGeometry; + void LoadOCCInto(OCCGeometry* occgeo, const char* filename) + { // Initiate a dummy XCAF Application to handle the STEP XCAF Document static Handle_XCAFApp_Application dummy_app = XCAFApp_Application::GetApplication(); @@ -1219,8 +1134,7 @@ void STEP_GetEntityName(const TopoDS_Shape & theShape, STEPCAFControl_Reader * a if(stat != IFSelect_RetDone) { - delete occgeo; - return NULL; + throw NgException("Couldn't load OCC geometry"); } reader.Transfer(step_doc); @@ -1287,6 +1201,94 @@ void STEP_GetEntityName(const TopoDS_Shape & theShape, STEPCAFControl_Reader * a // cout << occgeo->enames[i] << endl; // cout << " " <NbDocuments() > 0) + { + dummy_app->GetDocument(1,iges_doc); + dummy_app->Close(iges_doc); + } + dummy_app->NewDocument ("IGES-XCAF",iges_doc); + + IGESCAFControl_Reader reader; + + Standard_Integer stat = reader.ReadFile((char*)filename); + + if(stat != IFSelect_RetDone) + { + throw NgException("Couldn't load occ"); + } + + // Enable transfer of colours + reader.SetColorMode(Standard_True); + + reader.Transfer(iges_doc); + + // Read in the shape(s) and the colours present in the IGES File + Handle_XCAFDoc_ShapeTool iges_shape_contents = XCAFDoc_DocumentTool::ShapeTool(iges_doc->Main()); + Handle_XCAFDoc_ColorTool iges_colour_contents = XCAFDoc_DocumentTool::ColorTool(iges_doc->Main()); + + TDF_LabelSequence iges_shapes; + iges_shape_contents->GetShapes(iges_shapes); + + // List out the available colours in the IGES File as Colour Names + TDF_LabelSequence all_colours; + iges_colour_contents->GetColors(all_colours); + PrintMessage(1,"Number of colours in IGES File: ",all_colours.Length()); + for(int i = 1; i <= all_colours.Length(); i++) + { + Quantity_Color col; + stringstream col_rgb; + iges_colour_contents->GetColor(all_colours.Value(i),col); + col_rgb << " : (" << col.Red() << "," << col.Green() << "," << col.Blue() << ")"; + PrintMessage(1, "Colour [", i, "] = ",col.StringName(col.Name()),col_rgb.str()); + } + + + // For the IGES Reader, all the shapes can be exported as one compound shape + // using the "OneShape" member + occgeo->shape = reader.OneShape(); + occgeo->face_colours = iges_colour_contents; + occgeo->changed = 1; + occgeo->BuildFMap(); + + occgeo->CalcBoundingBox(); + PrintContents (occgeo); + return occgeo; + } + + + + + + // Philippose - 29/01/2009 + /* Special STEP File load function including the ability + to extract individual surface colours via the extended + OpenCascade XDE and XCAF Feature set. + */ + OCCGeometry * LoadOCC_STEP (const char * filename) + { + OCCGeometry * occgeo; + occgeo = new OCCGeometry; + + LoadOCCInto(occgeo, filename); return occgeo; } @@ -1355,8 +1357,34 @@ void STEP_GetEntityName(const TopoDS_Shape & theShape, STEPCAFControl_Reader * a } } + void OCCGeometry :: DoArchive(Archive& ar) + { + if(ar.Output()) + { + std::stringstream ss; + STEPControl_Writer writer; + writer.Transfer(shape, STEPControl_AsIs); + auto filename = ".tmpfile_out.step"; + writer.Write(filename); + std::ifstream is(filename); + ss << is.rdbuf(); + ar << ss.str(); + std::remove(filename); + } + else + { + std::string str; + ar & str; - + auto filename = ".tmpfile.step"; + auto tmpfile = std::fopen(filename, "w"); + std::fputs(str.c_str(), tmpfile); + std::fclose(tmpfile); + LoadOCCInto(this, filename); + std::remove(filename); + } + } + const char * shapesname[] = {" ", "CompSolids", "Solids", "Shells", diff --git a/libsrc/occ/occgeom.hpp b/libsrc/occ/occgeom.hpp index 6229a7cc..8c93ff1f 100644 --- a/libsrc/occ/occgeom.hpp +++ b/libsrc/occ/occgeom.hpp @@ -246,6 +246,7 @@ namespace netgen DLL_HEADER virtual void Save (string filename) const; + void DoArchive(Archive& ar); DLL_HEADER void BuildFMap(); diff --git a/libsrc/occ/python_occ.cpp b/libsrc/occ/python_occ.cpp index 3d95bcd6..157dc93b 100644 --- a/libsrc/occ/python_occ.cpp +++ b/libsrc/occ/python_occ.cpp @@ -18,6 +18,23 @@ DLL_HEADER void ExportNgOCC(py::module &m) { py::class_, NetgenGeometry> (m, "OCCGeometry", R"raw_string(Use LoadOCCGeometry to load the geometry from a *.step file.)raw_string") .def(py::init<>()) + .def(py::pickle( + [](OCCGeometry& self) + { + auto ss = make_shared(); + BinaryOutArchive archive(ss); + archive & self; + archive.FlushBuffer(); + return py::make_tuple(py::bytes(ss->str())); + }, + [](py::tuple state) + { + auto geo = make_shared(); + auto ss = make_shared (py::cast(state[0])); + BinaryInArchive archive(ss); + archive & (*geo); + return geo; + })) .def("Heal",[](OCCGeometry & self, double tolerance, bool fixsmalledges, bool fixspotstripfaces, bool sewfaces, bool makesolids, bool splitpartitions) { self.tolerance = tolerance; diff --git a/libsrc/stlgeom/python_stl.cpp b/libsrc/stlgeom/python_stl.cpp index 66101d0f..9fbe49cd 100644 --- a/libsrc/stlgeom/python_stl.cpp +++ b/libsrc/stlgeom/python_stl.cpp @@ -20,6 +20,23 @@ DLL_HEADER void ExportSTL(py::module & m) { py::class_, NetgenGeometry> (m,"STLGeometry") .def(py::init<>()) + .def(py::pickle( + [](STLGeometry& self) + { + auto ss = make_shared(); + BinaryOutArchive archive(ss); + archive & self; + archive.FlushBuffer(); + return py::make_tuple(py::bytes(ss->str())); + }, + [](py::tuple state) + { + auto geo = make_shared(); + auto ss = make_shared (py::cast(state[0])); + BinaryInArchive archive(ss); + archive & (*geo); + return geo; + })) .def("_visualizationData", [](shared_ptr stl_geo) { std::vector vertices; diff --git a/libsrc/stlgeom/stlgeom.cpp b/libsrc/stlgeom/stlgeom.cpp index 79e57ab8..ebb5136f 100644 --- a/libsrc/stlgeom/stlgeom.cpp +++ b/libsrc/stlgeom/stlgeom.cpp @@ -3579,5 +3579,5 @@ void STLGeometry :: SmoothGeometry () STLInit stlinit; - +static RegisterClassForArchive stlgeo; } diff --git a/libsrc/stlgeom/stlgeom.hpp b/libsrc/stlgeom/stlgeom.hpp index dfed02de..8d8d640f 100644 --- a/libsrc/stlgeom/stlgeom.hpp +++ b/libsrc/stlgeom/stlgeom.hpp @@ -184,6 +184,10 @@ namespace netgen STLGeometry(); virtual ~STLGeometry(); + void DoArchive(Archive& ar) + { + STLTopology::DoArchive(ar); + } void Clear(); diff --git a/libsrc/stlgeom/stltopology.cpp b/libsrc/stlgeom/stltopology.cpp index baabe981..7c32b0e4 100644 --- a/libsrc/stlgeom/stltopology.cpp +++ b/libsrc/stlgeom/stltopology.cpp @@ -1074,5 +1074,5 @@ void STLTopology :: OrientAfterTrig (int trig) } } - +static RegisterClassForArchive stltop; } diff --git a/libsrc/stlgeom/stltopology.hpp b/libsrc/stlgeom/stltopology.hpp index f5ecb8f2..a76d5ee5 100644 --- a/libsrc/stlgeom/stltopology.hpp +++ b/libsrc/stlgeom/stltopology.hpp @@ -96,6 +96,17 @@ public: STLTriangle (const int * apts); STLTriangle () {pts[0]=0;pts[1]=0;pts[2]=0;} + void DoArchive(Archive& ar) + { + ar.Do(&topedges[0],3); + ar.Do(&nbtrigs[0][0], 6); + ar.Do(&pts[0],3); + ar.Do(&domains[0],2); + size_t i = flags.toperror; + ar & normal & box & center & rad & facenum & i; + flags.toperror = i; + } + int operator[] (int i) const { return pts[i]; } int & operator[] (int i) { return pts[i]; } @@ -279,6 +290,13 @@ public: void Save (const char* filename) const; void SaveBinary (const char* filename, const char* aname) const; void SaveSTLE (const char * filename) const; // stores trigs and edges + + virtual void DoArchive(Archive& ar) + { + ar & trias & points & boundingbox & pointtol; + if(ar.Input()) + FindNeighbourTrigs(); + } virtual void InitSTLGeometry (const Array & readtrigs); diff --git a/tests/pytest/test_pickling.py b/tests/pytest/test_pickling.py index 09e571a7..336b08e8 100644 --- a/tests/pytest/test_pickling.py +++ b/tests/pytest/test_pickling.py @@ -1,8 +1,8 @@ -import netgen.csg as csg import pickle, numpy def test_pickle_csg(): + import netgen.csg as csg geo = csg.CSGeometry() geo.Add(csg.Sphere(csg.Pnt(0,0,0), 2).bc("sphere")) brick = csg.OrthoBrick(csg.Pnt(-3,-3,-3), csg.Pnt(3,3,3)) @@ -35,5 +35,55 @@ def test_pickle_csg(): for val1, val2 in zip(vd1.values(), vd2.values()): assert numpy.array_equal(val1, val2) +def test_pickle_stl(): + import netgen.stl as stl + geo = stl.LoadSTLGeometry("../../tutorials/hinge.stl") + geo_dump = pickle.dumps(geo) + geo2 = pickle.loads(geo_dump) + vd1 = geo._visualizationData() + vd2 = geo2._visualizationData() + for val1, val2 in zip(vd1.values(), vd2.values()): + assert numpy.array_equal(val1, val2) + + +def test_pickle_occ(): + try: + import netgen.NgOCC as occ + except: + import pytest + pytest.skip("can't import occ") + geo = occ.LoadOCCGeometry("../../tutorials/frame.step") + geo_dump = pickle.dumps(geo) + geo2 = pickle.loads(geo_dump) + vd1 = geo._visualizationData() + vd2 = geo2._visualizationData() + # TODO: it looks fine, but tests fail, so I assume we loose some info? + # for val1, val2 in zip(vd1.values(), vd2.values()): + # assert numpy.allclose(val1, val2, rtol=0.01) + +def test_pickle_geom2d(): + import netgen.geom2d as geom2d + geo = geom2d.SplineGeometry() + + # point coordinates ... + pnts = [ (0,0), (1,0), (1,0.6), (0,0.6), \ + (0.2,0.6), (0.8,0.6), (0.8,0.8), (0.2,0.8), \ + (0.5,0.15), (0.65,0.3), (0.5,0.45), (0.35,0.3) ] + pnums = [geo.AppendPoint(*p) for p in pnts] + + # start-point, end-point, boundary-condition, domain on left side, domain on right side: + lines = [ (0,1,1,1,0), (1,2,2,1,0), (2,5,2,1,0), (5,4,2,1,2), (4,3,2,1,0), (3,0,2,1,0), \ + (5,6,2,2,0), (6,7,2,2,0), (7,4,2,2,0), \ + (8,9,2,3,1), (9,10,2,3,1), (10,11,2,3,1), (11,8,2,3,1) ] + + for p1,p2,bc,left,right in lines: + geo.Append( ["line", pnums[p1], pnums[p2]], bc=bc, leftdomain=left, rightdomain=right) + geo_dump = pickle.dumps(geo) + geo2 = pickle.loads(geo_dump) + vd1 = geo._visualizationData() + vd2 = geo2._visualizationData() + for val1, val2 in zip(vd1.values(), vd2.values()): + assert numpy.array_equal(val1, val2) + if __name__ == "__main__": test_pickle_csg()