From 218bd4c5d2e669ae7e92d5c1dc1e80a37ac01394 Mon Sep 17 00:00:00 2001 From: Christopher Lackner Date: Fri, 2 Aug 2019 16:22:53 +0200 Subject: [PATCH] start work on stlparam from python, strange bad any cast exception --- libsrc/include/mystdlib.h | 1 + libsrc/meshing/meshtype.hpp | 2 + libsrc/meshing/python_mesh.cpp | 9 +- libsrc/meshing/python_mesh.hpp | 84 +++++++++--------- libsrc/stlgeom/meshstlsurface.cpp | 24 +++--- libsrc/stlgeom/python_stl.cpp | 137 +++++++++++++++++++++++++++++- libsrc/stlgeom/stlgeom.cpp | 52 +++++++----- libsrc/stlgeom/stlgeom.hpp | 24 +++--- libsrc/stlgeom/stlgeomchart.cpp | 6 +- libsrc/stlgeom/stlgeommesh.cpp | 4 +- libsrc/stlgeom/stlpkg.cpp | 12 +-- libsrc/stlgeom/stltool.cpp | 2 +- libsrc/stlgeom/stltool.hpp | 46 +++++----- nglib/nglib.cpp | 4 +- python/meshing.py | 78 +++++++++++++---- 15 files changed, 338 insertions(+), 147 deletions(-) diff --git a/libsrc/include/mystdlib.h b/libsrc/include/mystdlib.h index b55ba3da..a58f93f0 100644 --- a/libsrc/include/mystdlib.h +++ b/libsrc/include/mystdlib.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index bbc5b527..63e0515b 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -1269,6 +1269,8 @@ namespace netgen bool inverttrigs = false; /// bool autozrefine = false; + + any geometrySpecificParameters; /// MeshingParameters (); /// diff --git a/libsrc/meshing/python_mesh.cpp b/libsrc/meshing/python_mesh.cpp index a58faa70..1428a9cf 100644 --- a/libsrc/meshing/python_mesh.cpp +++ b/libsrc/meshing/python_mesh.cpp @@ -1019,17 +1019,14 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) typedef MeshingParameters MP; auto mp = py::class_ (m, "MeshingParameters") .def(py::init<>()) - .def(py::init([](py::kwargs kwargs) + .def(py::init([](MeshingParameters* other, py::kwargs kwargs) { MeshingParameters mp; + if(other) mp = *other; CreateMPfromKwargs(mp, kwargs); return mp; - }), meshingparameter_description.c_str()) + }), py::arg("mp")=nullptr, meshingparameter_description.c_str()) .def("__str__", &ToString) - .def_property("maxh", [](const MP & mp ) { return mp.maxh; }, - [](MP & mp, double maxh) { return mp.maxh = maxh; }) - .def_property("grading", [](const MP & mp ) { return mp.grading; }, - [](MP & mp, double grading) { return mp.grading = grading; }) .def("RestrictH", FunctionPointer ([](MP & mp, double x, double y, double z, double h) { diff --git a/libsrc/meshing/python_mesh.hpp b/libsrc/meshing/python_mesh.hpp index bbe75a97..45a2b9aa 100644 --- a/libsrc/meshing/python_mesh.hpp +++ b/libsrc/meshing/python_mesh.hpp @@ -83,86 +83,88 @@ elsizeweight: float = 0.2 inline void CreateMPfromKwargs(MeshingParameters& mp, py::kwargs kwargs) { if(kwargs.contains("optimize3d")) - mp.optimize3d = py::cast(kwargs["optimize3d"]); + mp.optimize3d = py::cast(kwargs.attr("pop")("optimize3d")); if(kwargs.contains("optsteps3d")) - mp.optsteps3d = py::cast(kwargs["optsteps3d"]); + mp.optsteps3d = py::cast(kwargs.attr("pop")("optsteps3d")); if(kwargs.contains("optimize2d")) - mp.optimize2d = py::cast(kwargs["optimize2d"]); + mp.optimize2d = py::cast(kwargs.attr("pop")("optimize2d")); if(kwargs.contains("optsteps2d")) - mp.optsteps2d = py::cast(kwargs["optsteps2d"]); + mp.optsteps2d = py::cast(kwargs.attr("pop")("optsteps2d")); if(kwargs.contains("opterrpow")) - mp.opterrpow = py::cast(kwargs["opterrpow"]); + mp.opterrpow = py::cast(kwargs.attr("pop")("opterrpow")); if(kwargs.contains("blockfill")) - mp.blockfill = py::cast(kwargs["blockfill"]); + mp.blockfill = py::cast(kwargs.attr("pop")("blockfill")); if(kwargs.contains("filldist")) - mp.filldist = py::cast(kwargs["filldist"]); + mp.filldist = py::cast(kwargs.attr("pop")("filldist")); if(kwargs.contains("safety")) - mp.safety = py::cast(kwargs["safety"]); + mp.safety = py::cast(kwargs.attr("pop")("safety")); if(kwargs.contains("relinnersafety")) - mp.relinnersafety = py::cast(kwargs["relinnersafety"]); + mp.relinnersafety = py::cast(kwargs.attr("pop")("relinnersafety")); if(kwargs.contains("uselocalh")) - mp.uselocalh = py::cast(kwargs["uselocalh"]); + mp.uselocalh = py::cast(kwargs.attr("pop")("uselocalh")); if(kwargs.contains("grading")) - mp.grading = py::cast(kwargs["grading"]); + mp.grading = py::cast(kwargs.attr("pop")("grading")); if(kwargs.contains("delaunay")) - mp.delaunay = py::cast(kwargs["delaunay"]); + mp.delaunay = py::cast(kwargs.attr("pop")("delaunay")); if(kwargs.contains("maxh")) - mp.maxh = py::cast(kwargs["maxh"]); + mp.maxh = py::cast(kwargs.attr("pop")("maxh")); if(kwargs.contains("minh")) - mp.minh = py::cast(kwargs["minh"]); + mp.minh = py::cast(kwargs.attr("pop")("minh")); if(kwargs.contains("meshsizefilename")) - mp.meshsizefilename = py::cast(kwargs["meshsizefilename"]); + mp.meshsizefilename = py::cast(kwargs.attr("pop")("meshsizefilename")); if(kwargs.contains("startinsurface")) - mp.startinsurface = py::cast(kwargs["startinsurface"]); + mp.startinsurface = py::cast(kwargs.attr("pop")("startinsurface")); if(kwargs.contains("checkoverlap")) - mp.checkoverlap = py::cast(kwargs["checkoverlap"]); + mp.checkoverlap = py::cast(kwargs.attr("pop")("checkoverlap")); if(kwargs.contains("checkoverlappingboundary")) - mp.checkoverlappingboundary = py::cast(kwargs["checkoverlappingboundary"]); + mp.checkoverlappingboundary = py::cast(kwargs.attr("pop")("checkoverlappingboundary")); if(kwargs.contains("checkchartboundary")) - mp.checkchartboundary = py::cast(kwargs["checkchartboundary"]); + mp.checkchartboundary = py::cast(kwargs.attr("pop")("checkchartboundary")); if(kwargs.contains("curvaturesafety")) - mp.curvaturesafety = py::cast(kwargs["curvaturesafety"]); + mp.curvaturesafety = py::cast(kwargs.attr("pop")("curvaturesafety")); if(kwargs.contains("segmentsperedge")) - mp.segmentsperedge = py::cast(kwargs["segmentsperedge"]); + mp.segmentsperedge = py::cast(kwargs.attr("pop")("segmentsperedge")); if(kwargs.contains("parthread")) - mp.parthread = py::cast(kwargs["parthread"]); + mp.parthread = py::cast(kwargs.attr("pop")("parthread")); if(kwargs.contains("elsizeweight")) - mp.elsizeweight = py::cast(kwargs["elsizeweight"]); + mp.elsizeweight = py::cast(kwargs.attr("pop")("elsizeweight")); if(kwargs.contains("perfstepsstart")) - mp.perfstepsstart = py::cast(kwargs["perfstepsstart"]); + mp.perfstepsstart = py::cast(kwargs.attr("pop")("perfstepsstart")); if(kwargs.contains("perfstepsend")) - mp.perfstepsend = py::cast(kwargs["perfstepsend"]); + mp.perfstepsend = py::cast(kwargs.attr("pop")("perfstepsend")); if(kwargs.contains("giveuptol2d")) - mp.giveuptol2d = py::cast(kwargs["giveuptol2d"]); + mp.giveuptol2d = py::cast(kwargs.attr("pop")("giveuptol2d")); if(kwargs.contains("giveuptol")) - mp.giveuptol = py::cast(kwargs["giveuptol"]); + mp.giveuptol = py::cast(kwargs.attr("pop")("giveuptol")); if(kwargs.contains("maxoutersteps")) - mp.maxoutersteps = py::cast(kwargs["maxoutersteps"]); + mp.maxoutersteps = py::cast(kwargs.attr("pop")("maxoutersteps")); if(kwargs.contains("starshapeclass")) - mp.starshapeclass = py::cast(kwargs["starshapeclass"]); + mp.starshapeclass = py::cast(kwargs.attr("pop")("starshapeclass")); if(kwargs.contains("baseelnp")) - mp.baseelnp = py::cast(kwargs["baseelnp"]); + mp.baseelnp = py::cast(kwargs.attr("pop")("baseelnp")); if(kwargs.contains("sloppy")) - mp.sloppy = py::cast(kwargs["sloppy"]); + mp.sloppy = py::cast(kwargs.attr("pop")("sloppy")); if(kwargs.contains("badellimit")) - mp.badellimit = py::cast(kwargs["badellimit"]); + mp.badellimit = py::cast(kwargs.attr("pop")("badellimit")); if(kwargs.contains("check_impossible")) - mp.check_impossible = py::cast(kwargs["check_impossible"]); + mp.check_impossible = py::cast(kwargs.attr("pop")("check_impossible")); if(kwargs.contains("only3D_domain_nr")) - mp.only3D_domain_nr = py::cast(kwargs["only3D_domain_nr"]); + mp.only3D_domain_nr = py::cast(kwargs.attr("pop")("only3D_domain_nr")); if(kwargs.contains("secondorder")) - mp.secondorder = py::cast(kwargs["secondorder"]); + mp.secondorder = py::cast(kwargs.attr("pop")("secondorder")); if(kwargs.contains("elementorder")) - mp.elementorder = py::cast(kwargs["elementorder"]); + mp.elementorder = py::cast(kwargs.attr("pop")("elementorder")); if(kwargs.contains("quad")) - mp.quad = py::cast(kwargs["quad"]); + mp.quad = py::cast(kwargs.attr("pop")("quad")); if(kwargs.contains("try_hexes")) - mp.try_hexes = py::cast(kwargs["try_hexes"]); + mp.try_hexes = py::cast(kwargs.attr("pop")("try_hexes")); if(kwargs.contains("inverttets")) - mp.inverttets = py::cast(kwargs["inverttets"]); + mp.inverttets = py::cast(kwargs.attr("pop")("inverttets")); if(kwargs.contains("inverttrigs")) - mp.inverttrigs = py::cast(kwargs["inverttrigs"]); + mp.inverttrigs = py::cast(kwargs.attr("pop")("inverttrigs")); if(kwargs.contains("autozrefine")) - mp.autozrefine = py::cast(kwargs["autozrefine"]); + mp.autozrefine = py::cast(kwargs.attr("pop")("autozrefine")); + if(kwargs.size()) + mp.geometrySpecificParameters = make_any(std::move(kwargs)); } } // namespace netgen diff --git a/libsrc/stlgeom/meshstlsurface.cpp b/libsrc/stlgeom/meshstlsurface.cpp index 4c1d940d..f6bfc411 100644 --- a/libsrc/stlgeom/meshstlsurface.cpp +++ b/libsrc/stlgeom/meshstlsurface.cpp @@ -14,7 +14,8 @@ namespace netgen { static void STLFindEdges (STLGeometry & geom, - class Mesh & mesh) + class Mesh & mesh, + MeshingParameters& mparam) { double h = mparam.maxh; @@ -229,18 +230,18 @@ static void STLFindEdges (STLGeometry & geom, -void STLSurfaceMeshing1 (STLGeometry & geom, class Mesh & mesh, +void STLSurfaceMeshing1 (STLGeometry & geom, class Mesh & mesh, MeshingParameters& mparam, int retrynr); -int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh) +int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh, MeshingParameters& mparam) { PrintFnStart("Do Surface Meshing"); geom.PrepareSurfaceMeshing(); if (mesh.GetNSeg() == 0) - STLFindEdges (geom, mesh); + STLFindEdges (geom, mesh, mparam); int nopen; int outercnt = 20; @@ -272,7 +273,7 @@ int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh) if (multithread.terminate) { return MESHING3_TERMINATE; } trialcnt++; - STLSurfaceMeshing1 (geom, mesh, trialcnt); + STLSurfaceMeshing1 (geom, mesh, mparam, trialcnt); mesh.FindOpenSegments(); nopen = mesh.GetNOpenSegments(); @@ -527,6 +528,7 @@ int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh) void STLSurfaceMeshing1 (STLGeometry & geom, class Mesh & mesh, + MeshingParameters& mparam, int retrynr) { static int timer1 = NgProfiler::CreateTimer ("STL surface meshing1"); @@ -741,7 +743,7 @@ void STLSurfaceMeshing1 (STLGeometry & geom, void STLSurfaceOptimization (STLGeometry & geom, class Mesh & mesh, - MeshingParameters & meshparam) + MeshingParameters & mparam) { PrintFnStart("optimize STL Surface"); @@ -749,12 +751,12 @@ void STLSurfaceOptimization (STLGeometry & geom, optmesh.SetFaceIndex (0); optmesh.SetImproveEdges (0); - optmesh.SetMetricWeight (meshparam.elsizeweight); + optmesh.SetMetricWeight (mparam.elsizeweight); - PrintMessage(5,"optimize string = ", meshparam.optimize2d, " elsizew = ", meshparam.elsizeweight); + PrintMessage(5,"optimize string = ", mparam.optimize2d, " elsizew = ", mparam.elsizeweight); - for (int i = 1; i <= meshparam.optsteps2d; i++) - for (size_t j = 1; j <= meshparam.optimize2d.length(); j++) + for (int i = 1; i <= mparam.optsteps2d; i++) + for (size_t j = 1; j <= mparam.optimize2d.length(); j++) { if (multithread.terminate) break; @@ -762,7 +764,7 @@ void STLSurfaceOptimization (STLGeometry & geom, //(*testout) << "optimize, before, step = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl; mesh.CalcSurfacesOfNode(); - switch (meshparam.optimize2d[j-1]) + switch (mparam.optimize2d[j-1]) { case 's': { diff --git a/libsrc/stlgeom/python_stl.cpp b/libsrc/stlgeom/python_stl.cpp index 39a52273..e61ec46b 100644 --- a/libsrc/stlgeom/python_stl.cpp +++ b/libsrc/stlgeom/python_stl.cpp @@ -17,6 +17,118 @@ namespace netgen extern shared_ptr ng_geometry; } +static string stlparameter_description = R"delimiter( +STL Specific Meshing Parameters +------------------------------- + +yangle: float = + Angle for edge detection + +contyangle: float = + Edges continue if angle > contyangle + +edgecornerangle: float = + Angle of geometry edge at which the mesher should set a point. + +)delimiter"; + +void CreateSTLParametersFromKwargs(STLParameters& stlparam, py::kwargs kwargs) +{ + if(kwargs.contains("yangle")) + stlparam.yangle = py::cast(kwargs.attr("pop")("yangle")); + if(kwargs.contains("contyangle")) + stlparam.contyangle = py::cast(kwargs.attr("pop")("contyangle")); + if(kwargs.contains("edgecornerangle")) + stlparam.edgecornerangle = py::cast(kwargs.attr("pop")("edgecornerangle")); + if(kwargs.contains("chartangle")) + stlparam.chartangle = py::cast(kwargs.attr("pop")("chartangle")); + if(kwargs.contains("outerchartangle")) + stlparam.outerchartangle = py::cast(kwargs.attr("pop")("outerchartangle")); + if(kwargs.contains("usesearchtree")) + stlparam.usesearchtree = py::cast(kwargs.attr("pop")("usesearchtree")); + if(kwargs.contains("resthatlasfac")) + { + auto val = kwargs.attr("pop")("resthatlasfac"); + if(val.is_none()) + stlparam.resthatlasenable = false; + else + { + stlparam.resthatlasenable = true; + stlparam.resthatlasfac = py::cast(val); + } + } + if(kwargs.contains("atlasminh")) + stlparam.atlasminh = py::cast(kwargs.attr("pop")("atlasminh")); + if(kwargs.contains("resthsurfcurvfac")) + { + auto val = kwargs.attr("pop")("resthsurfcurvfac"); + if(val.is_none()) + stlparam.resthsurfcurvenable = false; + else + { + stlparam.resthsurfcurvenable = true; + stlparam.resthsurfcurvfac = py::cast(val); + } + } + if(kwargs.contains("resthchartdistfac")) + { + auto val = kwargs.attr("pop")("resthchartdistfac"); + if(val.is_none()) + stlparam.resthchartdistenable = false; + else + { + stlparam.resthchartdistenable = true; + stlparam.resthchartdistfac = py::cast(val); + } + } + if(kwargs.contains("resthcloseedgefac")) + { + auto val = kwargs.attr("pop")("resthcloseedgefac"); + if(val.is_none()) + stlparam.resthcloseedgeenable = false; + else + { + stlparam.resthcloseedgeenable = true; + stlparam.resthcloseedgefac = py::cast(val); + } + } + if(kwargs.contains("resthedgeanglefac")) + { + auto val = kwargs.attr("pop")("resthedgeanglefac"); + if(val.is_none()) + stlparam.resthedgeangleenable = false; + else + { + stlparam.resthedgeangleenable = true; + stlparam.resthedgeanglefac = py::cast(val); + } + } + if(kwargs.contains("resthsurfmeshcurvfac")) + { + auto val = kwargs.attr("pop")("resthsurfmeshcurvfac"); + if(val.is_none()) + stlparam.resthsurfmeshcurvenable = false; + else + { + stlparam.resthsurfmeshcurvenable = true; + stlparam.resthsurfmeshcurvfac = py::cast(val); + } + } + if(kwargs.contains("resthlinelengthfac")) + { + auto val = kwargs.attr("pop")("resthlinelengthfac"); + if(val.is_none()) + stlparam.resthlinelengthenable = false; + else + { + stlparam.resthlinelengthenable = true; + stlparam.resthlinelengthfac = py::cast(val); + } + } + if(kwargs.contains("recalc_h_opt")) + stlparam.recalc_h_opt = py::cast(kwargs.attr("pop")("recalc_h_opt")); +} + DLL_HEADER void ExportSTL(py::module & m) { @@ -82,10 +194,31 @@ DLL_HEADER void ExportSTL(py::module & m) MeshingParameters* pars, py::kwargs kwargs) { MeshingParameters mp; - if(pars) mp = *pars; { py::gil_scoped_acquire aq; + STLParameters stlparam; + if(pars) + { + if(pars->geometrySpecificParameters.has_value() && + (pars->geometrySpecificParameters.type() == typeid(py::kwargs))) + { + py::gil_scoped_acquire aq; + py::kwargs mp_kwargs = any_cast(pars->geometrySpecificParameters); + py::print("geometry specific kwargs:", mp_kwargs); + CreateSTLParametersFromKwargs(stlparam, mp_kwargs); + pars->geometrySpecificParameters.reset(); + } + mp = *pars; + } CreateMPfromKwargs(mp, kwargs); + CreateSTLParametersFromKwargs(stlparam, kwargs); + if(kwargs.size()) + { + cout << "WARNING: Given meshing arguments that are ignored:"; + for(auto& key : kwargs) + py::print(key); + } + mp.geometrySpecificParameters = stlparam; } auto mesh = make_shared(); SetGlobalMesh(mesh); @@ -95,7 +228,7 @@ DLL_HEADER void ExportSTL(py::module & m) return mesh; }, py::arg("mp") = nullptr, py::call_guard(), - meshingparameter_description.c_str()) + (meshingparameter_description + stlparameter_description).c_str()) ; m.def("LoadSTLGeometry", [] (const string & filename) { diff --git a/libsrc/stlgeom/stlgeom.cpp b/libsrc/stlgeom/stlgeom.cpp index 2ccbf5f3..31c512b3 100644 --- a/libsrc/stlgeom/stlgeom.cpp +++ b/libsrc/stlgeom/stlgeom.cpp @@ -13,15 +13,21 @@ int usechartnormal = 1; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void STLMeshing (STLGeometry & geom, - Mesh & mesh) + Mesh & mesh, + const MeshingParameters& mparam) { geom.Clear(); - geom.BuildEdges(); - geom.MakeAtlas(mesh); + STLParameters stlpar = stlparam; + if(mparam.geometrySpecificParameters.has_value() && mparam.geometrySpecificParameters.type().name() == typeid(STLParameters).name()) + { + stlpar = any_cast(mparam.geometrySpecificParameters); + } + geom.BuildEdges(stlpar); + geom.MakeAtlas(mesh, mparam, stlpar); if (multithread.terminate) { return; } geom.CalcFaceNums(); geom.AddFaceEdges(); - geom.LinkEdges(); + geom.LinkEdges(stlpar); mesh.ClearFaceDescriptors(); for (int i = 1; i <= geom.GetNOFaces(); i++) @@ -132,7 +138,7 @@ void STLGeometry :: STLInfo(double* data) data[7] = cons; } -void STLGeometry :: MarkNonSmoothNormals() +void STLGeometry :: MarkNonSmoothNormals(const STLParameters& stlparam) { PrintFnStart("Mark Non-Smooth Normals"); @@ -169,13 +175,13 @@ void STLGeometry :: MarkNonSmoothNormals() } -void STLGeometry :: SmoothNormals() +void STLGeometry :: SmoothNormals(const STLParameters& stlparam) { multithread.terminate = 0; // UseExternalEdges(); - BuildEdges(); + BuildEdges(stlparam); DenseMatrix m(3), hm(3); @@ -1240,13 +1246,13 @@ void STLGeometry :: ClearEdges() } -void STLGeometry :: STLDoctorBuildEdges() +void STLGeometry :: STLDoctorBuildEdges(const STLParameters& stlparam) { // if (!trigsconverted) {return;} ClearEdges(); meshlines.SetSize(0); - FindEdgesFromAngles(); + FindEdgesFromAngles(stlparam); } void STLGeometry :: DeleteExternalEdgeAtSelected() @@ -1737,7 +1743,7 @@ void STLGeometry :: InitMarkedTrigs() } } -void STLGeometry :: MarkDirtyTrigs() +void STLGeometry :: MarkDirtyTrigs(const STLParameters& stlparam) { PrintFnStart("mark dirty trigs"); int i,j; @@ -1813,12 +1819,12 @@ double STLGeometry :: CalcTrigBadness(int i) } -void STLGeometry :: GeomSmoothRevertedTrigs() +void STLGeometry :: GeomSmoothRevertedTrigs(const STLParameters& stlparam) { //double revertedangle = stldoctor.smoothangle/180.*M_PI; double fact = stldoctor.dirtytrigfact; - MarkRevertedTrigs(); + MarkRevertedTrigs(stlparam); int i, j, k, l, p; @@ -1860,13 +1866,13 @@ void STLGeometry :: GeomSmoothRevertedTrigs() } } } - MarkRevertedTrigs(); + MarkRevertedTrigs(stlparam); } -void STLGeometry :: MarkRevertedTrigs() +void STLGeometry :: MarkRevertedTrigs(const STLParameters& stlparam) { int i,j; - if (edgesperpoint.Size() != GetNP()) {BuildEdges();} + if (edgesperpoint.Size() != GetNP()) {BuildEdges(stlparam);} PrintFnStart("mark reverted trigs"); @@ -1906,11 +1912,11 @@ void STLGeometry :: MarkRevertedTrigs() } -void STLGeometry :: SmoothDirtyTrigs() +void STLGeometry :: SmoothDirtyTrigs(const STLParameters& stlparam) { PrintFnStart("smooth dirty trigs"); - MarkDirtyTrigs(); + MarkDirtyTrigs(stlparam); int i,j; int changed = 1; @@ -1953,7 +1959,7 @@ void STLGeometry :: SmoothDirtyTrigs() calcedgedataanglesnew = 1; - MarkDirtyTrigs(); + MarkDirtyTrigs(stlparam); int cnt = 0; for (i = 1; i <= GetNT(); i++) @@ -2360,12 +2366,12 @@ int STLGeometry :: IsEdgeNum(int ap1, int ap2) } -void STLGeometry :: BuildEdges() +void STLGeometry :: BuildEdges(const STLParameters& stlparam) { //PrintFnStart("build edges"); edges.SetSize(0); meshlines.SetSize(0); - FindEdgesFromAngles(); + FindEdgesFromAngles(stlparam); } void STLGeometry :: UseExternalEdges() @@ -2487,7 +2493,7 @@ void STLGeometry :: CalcEdgeDataAngles() PrintMessage (5,"calc edge data angles ... done"); } -void STLGeometry :: FindEdgesFromAngles() +void STLGeometry :: FindEdgesFromAngles(const STLParameters& stlparam) { // PrintFnStart("find edges from angles"); @@ -2714,7 +2720,7 @@ void STLGeometry :: AddFaceEdges() } -void STLGeometry :: LinkEdges() +void STLGeometry :: LinkEdges(const STLParameters& stlparam) { PushStatusF("Link Edges"); PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); @@ -3131,7 +3137,7 @@ int IsInArray(int n, const NgArray& ia) } */ -void STLGeometry :: AddConeAndSpiralEdges() +void STLGeometry :: AddConeAndSpiralEdges(const STLParameters& stlparam) { PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); diff --git a/libsrc/stlgeom/stlgeom.hpp b/libsrc/stlgeom/stlgeom.hpp index 5d7a5af1..5e1ecc27 100644 --- a/libsrc/stlgeom/stlgeom.hpp +++ b/libsrc/stlgeom/stlgeom.hpp @@ -196,8 +196,8 @@ namespace netgen DLL_HEADER void STLInfo(double* data); //stldoctor: - DLL_HEADER void SmoothNormals(); - DLL_HEADER void MarkNonSmoothNormals(); + DLL_HEADER void SmoothNormals(const STLParameters& stlparam); + DLL_HEADER void MarkNonSmoothNormals(const STLParameters& stlparam); DLL_HEADER void CalcEdgeData(); DLL_HEADER void CalcEdgeDataAngles(); @@ -251,7 +251,7 @@ namespace netgen DLL_HEADER void AddClosedLinesToExternalEdges(); DLL_HEADER void AddLongLinesToExternalEdges(); DLL_HEADER void AddAllNotSingleLinesToExternalEdges(); - DLL_HEADER void STLDoctorBuildEdges(); + DLL_HEADER void STLDoctorBuildEdges(const STLParameters& stlparam); DLL_HEADER void AddExternalEdgesFromGeomLine(); DLL_HEADER void DeleteDirtyExternalEdges(); DLL_HEADER void DeleteExternalEdgeAtSelected(); @@ -292,10 +292,10 @@ namespace netgen DLL_HEADER int Vicinity(int trig) const; DLL_HEADER void InitMarkedTrigs(); - DLL_HEADER void MarkDirtyTrigs(); - DLL_HEADER void SmoothDirtyTrigs(); - DLL_HEADER void GeomSmoothRevertedTrigs(); - DLL_HEADER void MarkRevertedTrigs(); + DLL_HEADER void MarkDirtyTrigs(const STLParameters& stlparam); + DLL_HEADER void SmoothDirtyTrigs(const STLParameters& stlparam); + DLL_HEADER void GeomSmoothRevertedTrigs(const STLParameters& stlparam); + DLL_HEADER void MarkRevertedTrigs(const STLParameters& stlparam); DLL_HEADER double CalcTrigBadness(int i); DLL_HEADER int IsMarkedTrig(int trig) const; DLL_HEADER void SetMarkedTrig(int trig, int num); @@ -353,18 +353,18 @@ namespace netgen ///Build EdgeSegments void ClearEdges(); - void BuildEdges(); + void BuildEdges(const STLParameters& stlparam); void BuildEdgesPerPoint(); void UseExternalEdges(); - void FindEdgesFromAngles(); + void FindEdgesFromAngles(const STLParameters& stlparam); void CalcFaceNums(); int GetNOBodys(); int GetNOFaces() {return facecnt;} - void LinkEdges(); + void LinkEdges(const STLParameters& stlparam); - void AddConeAndSpiralEdges(); + void AddConeAndSpiralEdges(const STLParameters& stlparam); void AddFaceEdges(); //each face should have at least one starting edge (outherwise it won't be meshed) void GetDirtyChartTrigs(int chartnum, STLChart& chart, const NgArray& outercharttrigs, @@ -382,7 +382,7 @@ namespace netgen //make charts with regions of a max. angle - void MakeAtlas(class Mesh & mesh); + void MakeAtlas(class Mesh & mesh, const MeshingParameters& mparam, const STLParameters& stlparam); //outerchartspertrig, sorted! int GetOCPTSize() const {return outerchartspertrig.Size();}; diff --git a/libsrc/stlgeom/stlgeomchart.cpp b/libsrc/stlgeom/stlgeomchart.cpp index 4186265a..07dd4f3b 100644 --- a/libsrc/stlgeom/stlgeomchart.cpp +++ b/libsrc/stlgeom/stlgeomchart.cpp @@ -17,7 +17,7 @@ int chartdebug = 0; -void STLGeometry :: MakeAtlas(Mesh & mesh) +void STLGeometry :: MakeAtlas(Mesh & mesh, const MeshingParameters& mparam, const STLParameters& stlparam) { // int timer1 = NgProfiler::CreateTimer ("makeatlas"); /* @@ -128,7 +128,7 @@ void STLGeometry :: MakeAtlas(Mesh & mesh) SetThreadPercent(100.0 * workedarea / atlasarea); - STLChart * chart = new STLChart(this); + STLChart * chart = new STLChart(this, stlparam); atlas.Append(chart); // *testout << "Chart " << atlas.Size() << endl; @@ -572,7 +572,7 @@ void STLGeometry :: MakeAtlas(Mesh & mesh) mesh.SetMinimalH(mparam.minh); - AddConeAndSpiralEdges(); + AddConeAndSpiralEdges(stlparam); PrintMessage(5,"Make Atlas finished"); diff --git a/libsrc/stlgeom/stlgeommesh.cpp b/libsrc/stlgeom/stlgeommesh.cpp index a5e8cbcf..426f7bac 100644 --- a/libsrc/stlgeom/stlgeommesh.cpp +++ b/libsrc/stlgeom/stlgeommesh.cpp @@ -1372,7 +1372,7 @@ int STLMeshingDummy (STLGeometry* stlgeometry, shared_ptr & mesh, MeshingP //mesh->DeleteMesh(); - STLMeshing (*stlgeometry, *mesh); + STLMeshing (*stlgeometry, *mesh, mparam); stlgeometry->edgesfound = 1; stlgeometry->surfacemeshed = 0; @@ -1399,7 +1399,7 @@ int STLMeshingDummy (STLGeometry* stlgeometry, shared_ptr & mesh, MeshingP } success = 0; - int retval = STLSurfaceMeshing (*stlgeometry, *mesh); + int retval = STLSurfaceMeshing (*stlgeometry, *mesh, mparam); if (retval == MESHING3_OK) { PrintMessage(3,"Success !!!!"); diff --git a/libsrc/stlgeom/stlpkg.cpp b/libsrc/stlgeom/stlpkg.cpp index a016a71b..1372702f 100644 --- a/libsrc/stlgeom/stlpkg.cpp +++ b/libsrc/stlgeom/stlpkg.cpp @@ -243,15 +243,15 @@ namespace netgen } else if (strcmp (argv[1], "markdirtytrigs") == 0) { - stlgeometry->MarkDirtyTrigs(); + stlgeometry->MarkDirtyTrigs(stlparam); } else if (strcmp (argv[1], "smoothdirtytrigs") == 0) { - stlgeometry->SmoothDirtyTrigs(); + stlgeometry->SmoothDirtyTrigs(stlparam); } else if (strcmp (argv[1], "smoothrevertedtrigs") == 0) { - stlgeometry->GeomSmoothRevertedTrigs(); + stlgeometry->GeomSmoothRevertedTrigs(stlparam); } else if (strcmp (argv[1], "invertselectedtrig") == 0) { @@ -306,11 +306,11 @@ namespace netgen } else if (strcmp (argv[1], "smoothnormals") == 0) { - stlgeometry->SmoothNormals(); + stlgeometry->SmoothNormals(stlparam); } else if (strcmp (argv[1], "marknonsmoothnormals") == 0) { - stlgeometry->MarkNonSmoothNormals(); + stlgeometry->MarkNonSmoothNormals(stlparam); } else if (strcmp (argv[1], "addexternaledge") == 0) { @@ -359,7 +359,7 @@ namespace netgen } else if (strcmp (argv[1], "buildedges") == 0) { - stlgeometry->STLDoctorBuildEdges(); + stlgeometry->STLDoctorBuildEdges(stlparam); } else if (strcmp (argv[1], "confirmedge") == 0) { diff --git a/libsrc/stlgeom/stltool.cpp b/libsrc/stlgeom/stltool.cpp index 5a2eb61e..8b5f89ea 100644 --- a/libsrc/stlgeom/stltool.cpp +++ b/libsrc/stlgeom/stltool.cpp @@ -607,7 +607,7 @@ STLTopEdge :: STLTopEdge (int p1, int p2, int trig1, int trig2) //+++++++++++++++++++ STL CHART +++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -STLChart :: STLChart(STLGeometry * ageometry) +STLChart :: STLChart(STLGeometry * ageometry, const STLParameters& stlparam) { // charttrigs = new NgArray (0,0); // outertrigs = new NgArray (0,0); diff --git a/libsrc/stlgeom/stltool.hpp b/libsrc/stlgeom/stltool.hpp index b602ad94..f617d275 100644 --- a/libsrc/stlgeom/stltool.hpp +++ b/libsrc/stlgeom/stltool.hpp @@ -38,6 +38,7 @@ extern void FIOWriteString(ostream& ios, char* str, int len); typedef NgArray * ArrayINTPTR; class STLGeometry; +class STLParameters; class STLChart { @@ -53,7 +54,7 @@ private: public: - STLChart(STLGeometry * ageometry); + STLChart(STLGeometry * ageometry, const STLParameters& stlparam); ~STLChart(); void AddChartTrig(int i); void AddOuterTrig(int i); @@ -227,45 +228,46 @@ DLL_HEADER extern STLDoctorParams stldoctor; +// TODO change enable flag to optional parameters class STLParameters { public: /// angle for edge detection - double yangle; + double yangle = 30.; double contyangle; //edges continued with contyangle /// angle of geometry edge at which the mesher should set a point - double edgecornerangle; + double edgecornerangle = 60.; /// angle inside on chart - double chartangle; + double chartangle = 15.; /// angle for overlapping parts of char - double outerchartangle; + double outerchartangle = 70.; /// 0 .. no, 1 .. local, (2 .. global) int usesearchtree; /// double resthatlasfac; - int resthatlasenable; + bool resthatlasenable; double atlasminh; - double resthsurfcurvfac; - int resthsurfcurvenable; + double resthsurfcurvfac = 1.; + bool resthsurfcurvenable = false; - double resthchartdistfac; - int resthchartdistenable; + double resthchartdistfac = 1.5; + bool resthchartdistenable = true; - double resthcloseedgefac; - int resthcloseedgeenable; + double resthcloseedgefac = 2.; + bool resthcloseedgeenable = true; - double resthedgeanglefac; - int resthedgeangleenable; + double resthedgeanglefac = 1.; + bool resthedgeangleenable = false; - double resthsurfmeshcurvfac; - int resthsurfmeshcurvenable; + double resthsurfmeshcurvfac = 2.; + bool resthsurfmeshcurvenable = false; - double resthlinelengthfac; - int resthlinelengthenable; + double resthlinelengthfac = 0.5; + bool resthlinelengthenable = true; /// - int recalc_h_opt; + bool recalc_h_opt = true; /// STLParameters(); /// @@ -276,11 +278,13 @@ DLL_HEADER extern STLParameters stlparam; void STLMeshing (STLGeometry & geom, - class Mesh & mesh); + class Mesh & mesh, + const MeshingParameters& mparam); int STLSurfaceMeshing (STLGeometry & geom, - class Mesh & mesh); + class Mesh & mesh, + MeshingParameters& mparam); void STLSurfaceOptimization (STLGeometry & geom, class Mesh & mesh, diff --git a/nglib/nglib.cpp b/nglib/nglib.cpp index a177b9bd..e44b58c4 100644 --- a/nglib/nglib.cpp +++ b/nglib/nglib.cpp @@ -667,7 +667,7 @@ namespace nglib } */ - STLMeshing (*stlgeometry, *me); + STLMeshing (*stlgeometry, *me, mparam); stlgeometry->edgesfound = 1; stlgeometry->surfacemeshed = 0; @@ -709,7 +709,7 @@ namespace nglib stlgeometry->surfaceoptimized = 0; stlgeometry->volumemeshed = 0; */ - int retval = STLSurfaceMeshing (*stlgeometry, *me); + int retval = STLSurfaceMeshing (*stlgeometry, *me, mparam); if (retval == MESHING3_OK) { (*mycout) << "Success !!!!" << endl; diff --git a/python/meshing.py b/python/meshing.py index 5fbebdf4..1af409a2 100644 --- a/python/meshing.py +++ b/python/meshing.py @@ -1,22 +1,66 @@ from .libngpy._meshing import * class _MeshsizeObject: - pass + @property + def very_coarse(self): + return MeshingParameters(curvaturesafety=1, + segmentsperedge=0.3, + grading=0.7, + resthsurfcurvfac=0.25, + resthchartdistfac=0.8, + resthlinelengthfac=0.2, + resthcloseedgefac=0.5, + resthminedgelen=0.002, + resthedgeanglefac=0.25, + resthsurfmeshcurvfac=1.) + @property + def coarse(self): + return MeshingParameters(curvaturesafety=1.5, + segmentsperedge=0.5, + grading=0.5, + resthsurfcurvfac=0.5, + resthchartdistfac=1, + resthlinelengthfac=0.35, + resthcloseedgefac=1, + resthminedgelen=0.02, + resthedgeanglefac=0.5, + resthsurfmeshcurvfac=1.5) + @property + def moderate(self): + return MeshingParameters(curvaturesafety=2, + segmentsperedge=1, + grading=0.3, + resthsurfcurvfac=1., + resthchartdistfac=1.5, + resthlinelengthfac=0.5, + resthcloseedgefac=2, + resthminedgelen=0.2, + resthedgeanglefac=1, + resthsurfmeshcurvfac=2.) + @property + def fine(self): + return MeshingParameters(curvaturesafety=3, + segmentsperedge=2, + grading=0.2, + resthsurfcurvfac=1.5, + resthchartdistfac=2, + resthlinelengthfac=1.5, + resthcloseedgefac=3.5, + resthminedgelen=1., + resthedgeanglefac=1.5, + resthsurfmeshcurvfac=3.) + + @property + def very_fine(self): + return MeshingParameters(curvaturesafety=5, + segmentsperedge=3, + grading=0.1, + resthsurfcurvfac=3, + resthchartdistfac=5, + resthlinelengthfac=3, + resthcloseedgefac=5, + resthminedgelen=2., + resthedgeanglefac=3., + resthsurfmeshcurvfac=5.) meshsize = _MeshsizeObject() - -meshsize.very_coarse = MeshingParameters(curvaturesafety=1, - segmentsperedge=0.3, - grading=0.7) -meshsize.coarse = MeshingParameters(curvaturesafety=1.5, - segmentsperedge=0.5, - grading=0.5) -meshsize.moderate = MeshingParameters(curvaturesafety=2, - segmentsperedge=1, - grading=0.3) -meshsize.fine = MeshingParameters(curvaturesafety=3, - segmentsperedge=2, - grading=0.2) -meshsize.very_fine = MeshingParameters(curvaturesafety=5, - segmentsperedge=3, - grading=0.1)