diff --git a/libsrc/core/array.hpp b/libsrc/core/array.hpp index 0dbc463c..2a613b21 100644 --- a/libsrc/core/array.hpp +++ b/libsrc/core/array.hpp @@ -9,27 +9,14 @@ #include "archive.hpp" +#include "exception.hpp" #include "localheap.hpp" #include "utils.hpp" -#ifdef DEBUG -#define CHECK_RANGE -#endif - namespace ngcore { using std::ostream; - /** - Exception thrown by array range check. - Only thrown when compiled with RANGE_CHECK - */ - class ArrayRangeException : public Exception - { - public: - ArrayRangeException () : Exception("ArrayRangeException\n") { ; } - }; - template class Tuple { public: @@ -392,7 +379,7 @@ namespace ngcore Array represented by size and data-pointer. No memory allocation and deallocation, must be provided by user. Helper functions for printing. - Optional range check by macro CHECK_RANGE + Optional range check by macro NETGEN_CHECK_RANGE */ template class FlatArray : public BaseArrayObject > @@ -485,13 +472,10 @@ namespace ngcore return *this; } - /// Access array. range check by macro CHECK_RANGE + /// Access array. range check by macro NETGEN_CHECK_RANGE NETGEN_INLINE T & operator[] (size_t i) const { -#ifdef CHECK_RANGE - if (i < 0 || i >= size) - throw RangeException ("FlatArray::operator[]", i, 0, size-1); -#endif + NETGEN_CHECK_RANGE(i,0,size); return data[i]; } @@ -509,13 +493,10 @@ namespace ngcore // { return CArray (data+pos); } NETGEN_INLINE T * operator+ (size_t pos) const { return data+pos; } - /// access last element. check by macro CHECK_RANGE + /// access last element. check by macro NETGEN_CHECK_RANGE T & Last () const { -#ifdef CHECK_RANGE - if (!size) - throw Exception ("Array should not be empty"); -#endif + NETGEN_CHECK_RANGE(size-1,0,size); return data[size-1]; } @@ -857,10 +838,7 @@ namespace ngcore /// Delete element i. Move last element to position i. NETGEN_INLINE void DeleteElement (size_t i) { -#ifdef CHECK_RANGE - // RangeCheck (i); -#endif - + NETGEN_CHECK_RANGE(i,0,size); data[i] = std::move(data[size-1]); size--; } @@ -878,9 +856,7 @@ namespace ngcore /// Delete last element. NETGEN_INLINE void DeleteLast () { -#ifdef CHECK_RANGE - // CheckNonEmpty(); -#endif + NETGEN_CHECK_RANGE(size-1,0,size); size--; } diff --git a/libsrc/core/exception.hpp b/libsrc/core/exception.hpp index 35359e65..68e7c073 100644 --- a/libsrc/core/exception.hpp +++ b/libsrc/core/exception.hpp @@ -55,7 +55,7 @@ namespace ngcore int ind, int imin, int imax) : Exception("") { std::stringstream str; - str << where << ": index " << ind << " out of range [" << imin << "," << imax << "]\n"; + str << where << ": index " << ind << " out of range [" << imin << "," << imax << ")\n"; Append (str.str()); } @@ -80,9 +80,9 @@ namespace ngcore #define NG_EXCEPTION(s) ngcore::Exception(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t"+std::string(s)) #ifdef NETGEN_ENABLE_CHECK_RANGE -#define NETGEN_CHECK_RANGE(value, min, max) \ - { if ((value)<(min) || (value)>=(max)) \ - throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max)); } +#define NETGEN_CHECK_RANGE(value, min, max_plus_one) \ + { if ((value)<(min) || (value)>=(max_plus_one)) \ + throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max_plus_one)); } #else // NETGEN_ENABLE_CHECK_RANGE #define NETGEN_CHECK_RANGE(value, min, max) #endif // NETGEN_ENABLE_CHECK_RANGE diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index e52d9840..107c86ad 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -1246,7 +1246,7 @@ namespace netgen /// if non-zero, baseelement must have baseelnp points int baseelnp = 0; /// quality tolerances are handled less careful - bool sloppy = true; + int sloppy = 1; /// limit for max element angle (150-180) double badellimit = 175; diff --git a/libsrc/meshing/python_mesh.hpp b/libsrc/meshing/python_mesh.hpp index cbcda74e..2a808509 100644 --- a/libsrc/meshing/python_mesh.hpp +++ b/libsrc/meshing/python_mesh.hpp @@ -143,7 +143,7 @@ inline void CreateMPfromKwargs(MeshingParameters& mp, py::kwargs kwargs, bool th if(kwargs.contains("baseelnp")) mp.baseelnp = py::cast(kwargs.attr("pop")("baseelnp")); if(kwargs.contains("sloppy")) - mp.sloppy = py::cast(kwargs.attr("pop")("sloppy")); + mp.sloppy = py::cast(kwargs.attr("pop")("sloppy")); if(kwargs.contains("badellimit")) mp.badellimit = py::cast(kwargs.attr("pop")("badellimit")); if(kwargs.contains("check_impossible")) diff --git a/ng/menustat.tcl b/ng/menustat.tcl index 79ae9f99..930a8602 100644 --- a/ng/menustat.tcl +++ b/ng/menustat.tcl @@ -244,6 +244,8 @@ loadmeshinifile; } +set meshexportformats [Ng_GetExportFormats] + .ngmenu.file add command -label "Export Mesh..." \ -command { @@ -261,8 +263,11 @@ loadmeshinifile; } elseif { $exportfiletype == "OpenFOAM 1.5+ Compressed"} { set file [file nativename [tk_chooseDirectory -title "OpenFOAM 1.5+ Mesh Export - Select Case Directory"]] } else { -# set file [tk_getSaveFile -filetypes "{ \"$exportfiletype\" {$extension} }" ] - set file [tk_getSaveFile -filetypes "{ \"$exportfiletype\" {*}}" ] + # set file [tk_getSaveFile -filetypes "{ \"$exportfiletype\" {$extension} }" ] + # set file [tk_getSaveFile -filetypes "{ \"$exportfiletype\" {*}}" ] + set file [tk_getSaveFile -filetypes $meshexportformats -typevariable exportfiletype] + puts "type = $exportfiletype" + puts "filename = $file" } if {$file != ""} { @@ -271,9 +276,12 @@ loadmeshinifile; } .ngmenu.file add cascade -label "Export Filetype" -menu .ngmenu.file.filetype - menu .ngmenu.file.filetype +foreach exportformat $meshexportformats { + .ngmenu.file.filetype add radio -label [lindex $exportformat 0] -variable exportfiletype -command { .ngmenu.file invoke "Export Mesh..." } +} + .ngmenu.file add separator diff --git a/ng/ngappinit.cpp b/ng/ngappinit.cpp index 17aca99f..82dcb75d 100644 --- a/ng/ngappinit.cpp +++ b/ng/ngappinit.cpp @@ -250,7 +250,7 @@ int main(int argc, char ** argv) exit (1); } - + /* // lookup user file formats and insert into format list: NgArray userformats; NgArray extensions; @@ -262,13 +262,13 @@ int main(int argc, char ** argv) for (int i = 1; i <= userformats.Size(); i++) { fstr << ".ngmenu.file.filetype add radio -label \"" - << userformats.Get(i) << "\" -variable exportfiletype\n"; + << userformats.Get(i) << "\" -variable exportfiletype -command { .ngmenu.file invoke \"Export Mesh...\" } \n"; fstr << "lappend meshexportformats { {" << userformats.Get(i) << "} {" << extensions.Get(i) << "} }\n"; } - Tcl_Eval (myinterp, (char*)fstr.str().c_str()); + Tcl_Eval (myinterp, (char*)fstr.str().c_str()); Tcl_SetVar (myinterp, "exportfiletype", exportft, 0); - + */ #ifdef SOCKETS Ng_ServerSocketManagerRun(); diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp index cc48d234..d5a9f533 100644 --- a/ng/ngpkg.cpp +++ b/ng/ngpkg.cpp @@ -346,7 +346,21 @@ namespace netgen } - + int Ng_GetExportFormats (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + NgArray userformats; + NgArray extensions; + RegisterUserFormats (userformats, extensions); + + ostringstream fstr; + for (int i = 1; i <= userformats.Size(); i++) + fstr << "{ {" << userformats.Get(i) << "} {" << extensions.Get(i) << "} }\n"; + + Tcl_SetResult (interp, const_cast(fstr.str().c_str()), TCL_VOLATILE); + return TCL_OK; + } int Ng_ExportMesh (ClientData clientData, @@ -1249,6 +1263,28 @@ namespace netgen + int Ng_SetCommandLineParameter (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc != 2) + { + Tcl_SetResult (interp, (char*)"Ng_SetCommandLineParameter needs 1 parameter", + TCL_STATIC); + return TCL_ERROR; + } + + if (argv[1][0] == '-') + parameters.SetCommandLineFlag (argv[1]); + else + { + if (strstr(argv[1], ".py")) + parameters.SetFlag ("py", argv[1]); + else + parameters.SetFlag ("geofile", argv[1]); + } + return TCL_OK; + } int Ng_GetCommandLineParameter (ClientData clientData, @@ -2815,6 +2851,10 @@ void PlayAnimFile(const char* name, int speed, int maxcnt) (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand (interp, "Ng_GetExportFormats", Ng_GetExportFormats, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand (interp, "Ng_ExportMesh", Ng_ExportMesh, (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); @@ -3014,6 +3054,11 @@ void PlayAnimFile(const char* name, int speed, int maxcnt) (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand (interp, "Ng_SetCommandLineParameter", + Ng_SetCommandLineParameter, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand (interp, "Ng_GetCommandLineParameter", Ng_GetCommandLineParameter, (ClientData)NULL, diff --git a/ng/onetcl.cpp b/ng/onetcl.cpp index 591af1a0..7e2abd70 100644 --- a/ng/onetcl.cpp +++ b/ng/onetcl.cpp @@ -872,6 +872,7 @@ const char * ngscript[] = {"" ,"Ng_ReadStatus;\n" ,"}\n" ,"}\n" +,"set meshexportformats [Ng_GetExportFormats]\n" ,".ngmenu.file add command -label \"Export Mesh...\" \\\n" ,"-command {\n" ,"foreach exportformat $meshexportformats {\n" @@ -886,7 +887,9 @@ const char * ngscript[] = {"" ,"} elseif { $exportfiletype == \"OpenFOAM 1.5+ Compressed\"} {\n" ,"set file [file nativename [tk_chooseDirectory -title \"OpenFOAM 1.5+ Mesh Export - Select Case Directory\"]]\n" ,"} else {\n" -,"set file [tk_getSaveFile -filetypes \"{ \\\"$exportfiletype\\\" {*}}\" ]\n" +,"set file [tk_getSaveFile -filetypes $meshexportformats -typevariable exportfiletype]\n" +,"puts \"type = $exportfiletype\"\n" +,"puts \"filename = $file\"\n" ,"}\n" ,"if {$file != \"\"} {\n" ,"Ng_ExportMesh $file $exportfiletype\n" @@ -894,6 +897,9 @@ const char * ngscript[] = {"" ,"}\n" ,".ngmenu.file add cascade -label \"Export Filetype\" -menu .ngmenu.file.filetype\n" ,"menu .ngmenu.file.filetype\n" +,"foreach exportformat $meshexportformats {\n" +,".ngmenu.file.filetype add radio -label [lindex $exportformat 0] -variable exportfiletype -command { .ngmenu.file invoke \"Export Mesh...\" }\n" +,"}\n" ,".ngmenu.file add separator\n" ,".ngmenu.file add command -label \"Save Solution...\" \\\n" ,"-command {\n" diff --git a/tests/catch/array.cpp b/tests/catch/array.cpp new file mode 100644 index 00000000..471806c0 --- /dev/null +++ b/tests/catch/array.cpp @@ -0,0 +1,37 @@ + +#include "catch.hpp" +#include +using namespace ngcore; +using namespace std; + + +TEST_CASE("Array") +{ + Array array; +#ifdef DEBUG + CHECK_THROWS_AS(array[0], RangeException); + CHECK_THROWS_AS(array.DeleteLast(), RangeException); + CHECK_THROWS_AS(array.Last(), RangeException); +#endif // DEBUG + Array a_initlst = { 1., 2., 3.}; + CHECK(a_initlst[1] == 2.); + CHECK(a_initlst.size() == 3); + FlatArray fa_a = a_initlst; + CHECK(typeid(fa_a) == typeid(FlatArray)); + CHECK(fa_a.size() == 3); + CHECK(a.Last() == 3.); + a.DeleteLast(); + CHECK(a.Last() == 2. && a.Size() == 2); +#ifdef DEBUG + CHECK_THROWS_AS(fa_a[5], RangeException); +#endif // DEBUG + Array b = Array(4); + b = 2; + int count = 0; + for(auto val : b) + { + count++; + CHECK(val == 2); + } + CHECK(count == 4); +}