From 099acc9fa108275a2505c6d2e055cdde08816a6e Mon Sep 17 00:00:00 2001 From: Christopher Lackner Date: Fri, 14 Dec 2018 12:01:58 +0100 Subject: [PATCH] pickling for all geometry types --- libsrc/csg/csgeom.cpp | 2 +- libsrc/csg/csgeom.hpp | 10 +- libsrc/geom2d/geometry2d.cpp | 3 +- libsrc/geom2d/geometry2d.hpp | 6 +- libsrc/geom2d/python_geom2d.cpp | 33 +++-- libsrc/gprim/splinegeometry.cpp | 2 + libsrc/gprim/splinegeometry.hpp | 10 +- libsrc/meshing/basegeom.cpp | 1 + libsrc/meshing/basegeom.hpp | 3 + libsrc/meshing/curvedelems.hpp | 5 + libsrc/meshing/meshclass.cpp | 23 +--- libsrc/meshing/python_mesh.cpp | 4 +- libsrc/occ/occgeom.cpp | 210 ++++++++++++++++++-------------- libsrc/occ/occgeom.hpp | 1 + libsrc/occ/python_occ.cpp | 17 +++ libsrc/stlgeom/python_stl.cpp | 17 +++ libsrc/stlgeom/stlgeom.cpp | 2 +- libsrc/stlgeom/stlgeom.hpp | 4 + libsrc/stlgeom/stltopology.cpp | 2 +- libsrc/stlgeom/stltopology.hpp | 18 +++ tests/pytest/test_pickling.py | 48 +++++++- 21 files changed, 281 insertions(+), 140 deletions(-) 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..72a2df09 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,51 @@ 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(): + import netgen.NgOCC as 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()