getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] (no subject)


From: Konstantinos Poulios
Subject: [Getfem-commits] (no subject)
Date: Mon, 7 Aug 2017 09:16:01 -0400 (EDT)

branch: devel-logari81
commit 2061fb8d3c04095790fbff8997fdbdeac6eff200
Author: Konstantinos Poulios <address@hidden>
Date:   Mon Aug 7 15:15:16 2017 +0200

    fix import of ANSYS cdb files with NBLOCK missing a total nodes number 
entry and avoid use of sscanf
---
 src/getfem_import.cc | 177 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 98 insertions(+), 79 deletions(-)

diff --git a/src/getfem_import.cc b/src/getfem_import.cc
index 4894a85..c413deb 100644
--- a/src/getfem_import.cc
+++ b/src/getfem_import.cc
@@ -750,31 +750,31 @@ namespace getfem {
     std::vector<size_type> elt_cnt;
     std::vector<dal::bit_vector> regions;
 
-    size_type pos;
+    size_type pos, pos2;
     std::string line;
     while (true) {
       std::getline(f,line);
       pos = line.find_first_not_of(" ");
       if (bgeot::casecmp(line.substr(pos,2),"ET") == 0) {
         size_type itype;
-        char type_name[32] = "";
-        pos = line.find_first_of(",");
-        sscanf(line.substr(pos+1).c_str(), "%lu,%s", &itype, type_name);
-
-        bool only_digits=true;
-        for (size_type i=strlen(type_name); i != 0; --i)
-          if (!isdigit(type_name[i-1])) {
-            type_name[i-1] = char(toupper(type_name[i-1]));
-            only_digits = false;
-          }
+        std::string type_name;
+        pos = line.find_first_of(",")+1;
+        pos2 = line.find_first_of(",", pos);
+        itype = std::stol(line.substr(pos, pos2-pos));
+        pos = line.find_first_not_of(" ,\n\r\t", pos2);
+        pos2 = line.find_first_of(" ,\n\r\t", pos);
+        type_name = line.substr(pos, pos2-pos);
+        bool only_digits
+          = (type_name.find_first_not_of("0123456789") == std::string::npos);
+        const std::locale loc;
+        for (auto&& c : type_name) c = std::toupper(c, loc);
 
         if (elt_types.size() < itype+1)
           elt_types.resize(itype+1);
 
         elt_types[itype] = "";
         if (only_digits) {
-          size_type type_num;
-          sscanf(type_name, "%lu", &type_num);
+          size_type type_num = std::stol(type_name);
           if (type_num == 42 || type_num == 82 ||
               type_num == 182 || type_num == 183)
             elt_types[itype] = "PLANE";
@@ -790,8 +790,13 @@ namespace getfem {
       }
       else if (bgeot::casecmp(line.substr(pos,5),"KEYOP") == 0) {
         size_type itype, knum, keyval;
-        pos = line.find_first_of(",");
-        sscanf(line.substr(pos+1).c_str(), "%lu,%lu,%lu", &itype, &knum, 
&keyval);
+        pos = line.find_first_of(",")+1;
+        pos2 = line.find_first_of(",", pos);
+        itype = std::stol(line.substr(pos, pos2-pos));
+        pos = pos2+1;
+        pos2 = line.find_first_of(",", pos);
+        knum = std::stol(line.substr(pos+1, pos2-pos));
+        keyval = std::stol(line.substr(pos2+1));
         if (knum == 1 && itype < elt_types.size() &&
             elt_types[itype].size() == 7 &&
             bgeot::casecmp(elt_types[itype].substr(0,7),"MESH200") == 0) {
@@ -807,39 +812,41 @@ namespace getfem {
     }
     elt_cnt.resize(elt_types.size());
 
-    // NBLOCK, NUMFIELD, SOLKEY, NDMAX, NDSEL
-    //NBLOCK,6,SOLID,     45876,     45876
-    size_type nodes2read;
-    pos = line.find_last_of(",");
-    sscanf(line.substr(pos+1).c_str(), "%lu", &nodes2read);
-
     //(3i8,6e20.13)
     size_type fields1, fieldwidth1, fields2, fieldwidth2; // 3,8,6,20
-    std::string node_info_fmt;
     { // "%8lu%*8u%*8u%20lf%20lf%20lf"
-      std::string fortran_fmt;
+      std::string fortran_fmt; // "(%lu%*[i]%lu,%lu%*[e,E]%lu.%*u)"
       std::getline(f,fortran_fmt);
-      sscanf(fortran_fmt.c_str(), "(%lu%*[i]%lu,%lu%*[e,E]%lu.%*u)",
-             &fields1, &fieldwidth1, &fields2, &fieldwidth2);
+      pos = fortran_fmt.find_first_of("(")+1;
+      pos2 = fortran_fmt.find_first_of("iI", pos);
+      fields1 = std::stol(fortran_fmt.substr(pos, pos2-pos));
+      pos = pos2+1;
+      pos2 = fortran_fmt.find_first_of(",", pos);
+      fieldwidth1 = std::stol(fortran_fmt.substr(pos, pos2-pos));
+      pos = pos2+1;
+      pos2 = fortran_fmt.find_first_of("eE", pos);
+      fields2 = std::stol(fortran_fmt.substr(pos, pos2-pos));
+      pos = pos2+1;
+      pos2 = fortran_fmt.find_first_of(".", pos);
+      fieldwidth2 = std::stol(fortran_fmt.substr(pos, pos2-pos));
       GMM_ASSERT1(fields1 >= 1 && fields2 >= 3 ,
                   "Ansys mesh import routine requires NBLOCK entries with at 
least "
                   "1 integer field and 3 float number fields");
-      std::stringstream ss;
-      ss << "%" << fieldwidth1 << "lu";
-      for (size_type i=1; i < fields1; ++i)
-        ss << "%*" << fieldwidth1 << "lu";
-      for (size_type i=0; i < 3; ++i)
-        ss << "%" << fieldwidth2 << "lf";
-      node_info_fmt = ss.str();
     }
 
     base_node pt(3);
-    for (size_type i=0; i < nodes2read; ++i) {
+    for (size_type i=0; i < size_type(-1); ++i) {
       size_type nodeid;
       std::getline(f,line);
+      if (line.compare(0,1,"N") == 0)
+        break;
       //       1       0       0-3.0000000000000E+00 2.0000000000000E+00 
1.0000000000000E+00
-      sscanf(line.c_str(), node_info_fmt.c_str(), &nodeid, &pt[0], &pt[1], 
&pt[2]);
-      cdb_node_2_getfem_node[nodeid] = m.add_point(pt);
+      nodeid = std::stol(line.substr(0, fieldwidth1));
+      pos = fields1*fieldwidth1;
+      for (size_type j=0; j < 3; ++j, pos += fieldwidth2)
+        pt[j] = std::stod(line.substr(pos, fieldwidth2));
+
+      cdb_node_2_getfem_node[nodeid] = m.add_point(pt, 0., false);
     }
 
     while (bgeot::casecmp(line.substr(0,6),"EBLOCK") != 0) {
@@ -851,47 +858,66 @@ namespace getfem {
 
     //(19i8)
     size_type fieldsno, fieldwidth; // 19,8
-    std::string elt_info_fmt, imat_fmt;
     { // "%8lu%8lu%8lu%8lu%8lu%8lu%8lu%8lu"
       std::string fortran_fmt;
       std::getline(f,fortran_fmt);
-      sscanf(fortran_fmt.c_str(),"(%lu%*[i]%lu)", &fieldsno, &fieldwidth);
-      GMM_ASSERT1(fieldsno == 19, "Ansys mesh import routine requires EBLOCK 
entries "
-                                  "with 19 fields");
-      std::stringstream ss0, ss;
-      ss0 << "%" << fieldwidth << "li";
-      imat_fmt = ss0.str();
-      for (size_type i=0; i < 10; ++i)
-        ss << "%" << fieldwidth << "lu";
-      elt_info_fmt = ss.str();
+
+      pos = fortran_fmt.find_first_of("(")+1;
+      pos2 = fortran_fmt.find_first_of("iI", pos);
+      fieldsno = std::stol(fortran_fmt.substr(pos, pos2-pos));
+      pos = pos2+1;
+      pos2 = fortran_fmt.find_first_of(")\n", pos);
+      fieldwidth = std::stol(fortran_fmt.substr(pos, pos2-pos));
+      GMM_ASSERT1(fieldsno == 19, "Ansys mesh import routine requires EBLOCK "
+                                  "entries with 19 fields");
     }
 
     size_type II,JJ,KK,LL,MM,NN,OO,PP,QQ,RR,SS,TT,UU,VV,WW,XX,YY,ZZ,AA,BB;
-    while (true) {
+    for (size_type i=0; i < size_type(-1); ++i) {
       GMM_ASSERT1(!f.eof(), "File ended before all elements could be read");
-      size_type imat, itype, realconst, isection, coordsys, deathflag,
-                modelref, shapeflag, nodesno, notused, eltid;
+      size_type imat, itype, nodesno(0);
       std::getline(f,line);
       {
-        long int ii;
-        sscanf(line.substr(0,fieldwidth).c_str(), imat_fmt.c_str(),
-               &ii);
+        long int ii = std::stol(line.substr(0,fieldwidth));
         if (ii < 0)
           break;
         else
           imat = size_type(ii);
-
-        if (imat_filt != size_type(-1) && imat != imat_filt) { // skip current 
element
-          if (nodesno > 8)
-            std::getline(f,line);
-          continue;
-        }
       }
-      sscanf(line.substr(fieldwidth,11*fieldwidth).c_str(), 
elt_info_fmt.c_str(),
-             &itype, &realconst, &isection, &coordsys, &deathflag,
-             &modelref, &shapeflag, &nodesno, &notused, &eltid);
+      itype = std::stol(line.substr(fieldwidth,fieldwidth));
+      nodesno = std::stol(line.substr(8*fieldwidth,fieldwidth));
       line = line.substr(11*fieldwidth);
 
+      if (imat_filt != size_type(-1) && imat != imat_filt) { // skip current 
element
+        if (nodesno > 8)
+          std::getline(f,line);
+        continue;
+      }
+
+      if (nodesno >= 1) II = std::stol(line.substr(0,fieldwidth));
+      if (nodesno >= 2) JJ = std::stol(line.substr(1*fieldwidth,fieldwidth));
+      if (nodesno >= 3) KK = std::stol(line.substr(2*fieldwidth,fieldwidth));
+      if (nodesno >= 4) LL = std::stol(line.substr(3*fieldwidth,fieldwidth));
+      if (nodesno >= 5) MM = std::stol(line.substr(4*fieldwidth,fieldwidth));
+      if (nodesno >= 6) NN = std::stol(line.substr(5*fieldwidth,fieldwidth));
+      if (nodesno >= 7) OO = std::stol(line.substr(6*fieldwidth,fieldwidth));
+      if (nodesno >= 8) PP = std::stol(line.substr(7*fieldwidth,fieldwidth));
+      if (nodesno >= 9) {
+        std::getline(f,line);
+        if (nodesno >= 9) QQ = std::stol(line.substr(0,fieldwidth));
+        if (nodesno >= 10) RR = 
std::stol(line.substr(1*fieldwidth,fieldwidth));
+        if (nodesno >= 11) SS = 
std::stol(line.substr(2*fieldwidth,fieldwidth));
+        if (nodesno >= 12) TT = 
std::stol(line.substr(3*fieldwidth,fieldwidth));
+        if (nodesno >= 13) UU = 
std::stol(line.substr(4*fieldwidth,fieldwidth));
+        if (nodesno >= 14) VV = 
std::stol(line.substr(5*fieldwidth,fieldwidth));
+        if (nodesno >= 15) WW = 
std::stol(line.substr(6*fieldwidth,fieldwidth));
+        if (nodesno >= 16) XX = 
std::stol(line.substr(7*fieldwidth,fieldwidth));
+        if (nodesno >= 17) YY = 
std::stol(line.substr(8*fieldwidth,fieldwidth));
+        if (nodesno >= 18) ZZ = 
std::stol(line.substr(9*fieldwidth,fieldwidth));
+        if (nodesno >= 19) AA = 
std::stol(line.substr(10*fieldwidth,fieldwidth));
+        if (nodesno >= 20) BB = 
std::stol(line.substr(11*fieldwidth,fieldwidth));
+      }
+
       if (imat+1 > regions.size())
         regions.resize(imat+1);
 
@@ -900,9 +926,6 @@ namespace getfem {
       }
       else if (nodesno == 4) {
 
-        sscanf(line.c_str(), elt_info_fmt.c_str(),
-               &II, &JJ, &KK, &LL);
-
         // assume MESH200_6 (4-node quadrilateral)
         std::string eltname("MESH200_6");
         if (elt_types.size() > itype && elt_types[itype].size() > 0)
@@ -939,9 +962,6 @@ namespace getfem {
       }
       else if (nodesno == 8) {
 
-        sscanf(line.c_str(), elt_info_fmt.c_str(),
-               &II, &JJ, &KK, &LL, &MM, &NN, &OO, &PP);
-
         // assume MESH200_10
         std::string eltname("MESH200_10");
         if (elt_types.size() > itype && elt_types[itype].size() > 0)
@@ -1008,11 +1028,6 @@ namespace getfem {
       }
       else if (nodesno == 10) {
 
-        sscanf(line.c_str(), elt_info_fmt.c_str(),
-               &II, &JJ, &KK, &LL, &MM, &NN, &OO, &PP);
-        std::getline(f,line);
-        sscanf(line.c_str(), elt_info_fmt.c_str(), &QQ, &RR);
-
         // assume MESH200_9 (10-node tetrahedral)
         std::string eltname("MESH200_9");
         if (elt_types.size() > itype && elt_types[itype].size() > 0)
@@ -1042,12 +1057,6 @@ namespace getfem {
       }
       else if (nodesno == 20) { //  # assume SOLID186/SOLID95
 
-        sscanf(line.c_str(), elt_info_fmt.c_str(),
-               &II, &JJ, &KK, &LL, &MM, &NN, &OO, &PP);
-        std::getline(f,line);
-        sscanf(line.c_str(), elt_info_fmt.c_str(),
-               &QQ, &RR, &SS, &TT, &UU, &VV, &WW, &XX, &YY, &ZZ, &AA, &BB);
-
         // assume MESH200_11 (20-node hexahedral)
         std::string eltname("MESH200_11");
         if (elt_types.size() > itype && elt_types[itype].size() > 0)
@@ -1410,8 +1419,18 @@ namespace getfem {
     else if (bgeot::casecmp(format,"cdb")==0)
       import_cdb_mesh_file(f,m);
     else if (bgeot::casecmp(format.substr(0,4),"cdb:")==0) {
-      size_type imat;
-      if (sscanf(format.substr(4).c_str(), "%lu", &imat))
+      size_type imat(-1);
+      bool success(true);
+      try {
+        size_t sz;
+        imat = std::stol(format.substr(4), &sz);
+        success = (sz == format.substr(4).size() && imat != size_type(-1));
+      } catch (const std::invalid_argument&) {
+        success = false;
+      } catch (const std::out_of_range&) {
+        success = false;
+      }
+      if (success)
         import_cdb_mesh_file(f,m,imat);
       else GMM_ASSERT1(false, "cannot import "
                        << format << " mesh type : wrong cdb mesh type input");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]