objectstream.cpp

来自「算断裂的」· C++ 代码 · 共 944 行 · 第 1/2 页

CPP
944
字号
          os << "vertex " << patch.control_point(0) << " ";        }        else if (fspec.fdim() == 1) {          os << "bezier_curve " << patch.degree1() << " ";          for (int j = 0; j < patch.degree1() + 1; ++j) {            os << patch.control_point(j) << " ";          }        }        else if (fspec.fdim() == 2) {          if (patch.ptype() == BEZIER_QUAD) {            os << "bezier_quad " << patch.degree1() << " " << patch.degree2() << " ";            int k = 0;            for (int j = 0; j < patch.degree2() + 1; ++j) {              for (int i = 0; i < patch.degree1() + 1; ++i) {                os << patch.control_point(k++) << " ";              }            }          }          else {            os << "bezier_triangle " << patch.degree1() << " ";            int ncp = (patch.degree1() + 1) * (patch.degree1() + 2) / 2;            for (int j = 0; j < ncp; ++j) {              os << patch.control_point(j) << " ";            }          }        }        os << ")";      }       os << " )\n";    }    os << nobreak_begin << " ) # end topological " << facetype << "\n" << nobreak_end;  }  return ostr;}// ------------------------------------------------------------------// operator<< for meshes.// This routine outputs a mesh to a stream in Ascii form.QMG::ostream& operator<<(QMG::ostream& os, const QMG::SimpComplex& sc) {  int di = sc.embedded_dim();  int gdim = sc.gdim();  os << sc.io_header_code() << " " << gdim << " " << di << "\n(";  int npv = sc.num_prop_val();  for (int pvi = 0; pvi < npv; ++pvi) {    os << sc.prop(pvi) << " " << sc.val(pvi);  }  os << ")\n( # begin list of mesh nodes\n";  for (SimpComplex::VertexOrdinalIndex vnumo = 0; vnumo < sc.num_nodes(); ++vnumo) {    os <<  sc.ordinal_to_global(vnumo) << " ";    for (int ii = 0; ii < di; ++ii)  {      os <<  std::setprecision(17) << sc.real_coord_o(vnumo, ii) << " ";    }    os << '\n';  }  os << ") # end list of mesh nodes\n";  for (int fdim = 0; fdim <= gdim; ++fdim) {    os << "\n( # begin mesh info for topological entities of dimension " << fdim << '\n';    for (Brep::FaceIndex faceind = 0; faceind < sc.brep_levelsize(fdim); ++faceind) {      Brep::Face_Spec fspec(fdim, faceind);      os << "(";      if (fdim > 0 && fdim < di)        os << " # mesh vertices lying on top. entity " << fspec << '\n';      int nnf = sc.num_node_on_face(fspec);      for (int seqno1 = 0; seqno1 < nnf; ++seqno1) {        os << sc.node_on_face(fspec, seqno1) << " ";        if (fdim > 0) {          os << sc.patchind_on_face(fspec, seqno1) << " ";          for (int l = 0; l < fdim; ++l) {            os << std::setprecision(17) << sc.param_coord_on_face(fspec, seqno1, l)              << " ";          }          os << '\n';        }      }      os << ") (";      if (fdim > 0) {        os << " # mesh entities lying on top. entity " << fspec << '\n';        int nmf = sc.num_meshface_on_face(fspec);        for (int seqno2 = 0; seqno2 < nmf; ++seqno2) {          for (int l = 0; l < fdim + 1; ++l) {            os << sc.node_of_meshface_on_face(fspec, seqno2, l) << " ";          }          os << '\n';        }      }      os << ") # " << fspec << '\n';    }    os << ") # end mesh info for topological entities of dimension " << fdim << '\n';  }  return os;}   // ------------------------------------------------------------------// Read a brep from an istream.// Second argument is true if the header code has already been read// by another reader.  Third argument indicates the number of lines of// the file already read.QMG::Brep_Under_ConstructionQMG::Brep_Under_Construction::read_from_istream(istream& istr,                                            bool code_already_read,                                           int& line_count) {  // current_op keeps track of the current operation of the parser;  // used for issuing intelligent error messages.    Error_Message errinfo;  errinfo.set_string("Error occurred while reading header info");  Istream_skip_comments is(istr, line_count);  if (!code_already_read) {    string code;    is.get_string(code);    if (compare_nocase(code, Brep::io_header_code()))      throw_error("File begins with incorrect code");  }  int gdim, embedded_dim;  if (!is.get_int(gdim)) throw_error("Misplaced right paren");  if (!is.get_int(embedded_dim)) throw_error("Misplaced right paren");  errinfo.set_string("Error occurred while brep's prop-val pairs");    Brep_Under_Construction newbrep(gdim, embedded_dim);  Propval_inserter pvi(newbrep);  is.get_left_paren();  for (;;) {    string prop, val;    if (!is.get_string(prop)) break;    bool s2 = is.get_string(val);    if (!s2)       throw_error("Unmatched property (property-values must come in pairs)");    pvi.insert_propval(prop,val);  }    errinfo.set_string("Error occurred while reading control points");  is.get_left_paren();  Control_point_inserter cpi(newbrep);  vector<Real> coord(embedded_dim, 0.0);  for (;;) {    bool double_read;    for (int j = 0; j < embedded_dim; ++j) {      double_read = is.get_double(coord[j]);      if (!double_read) {        if (j > 0) {          string errmsg = "number of doubles in control point list";          errmsg += " must be divisible by embedded_dim";          throw_error(errmsg);        }        break;      }    }    if (!double_read) break;    cpi.insert_control_point(coord);  }  // This map is the associative map FaceName -> Fspec since  // the ascii format refers to topological faces via their  // symbolic names.    Face_lookup_map_type facename_lookup;   for (int dim = 0; dim <= gdim; ++dim) {    const char* facetype = "unknown";    if (dim == 0)      facetype = "vertex";    else if (dim == 1)      facetype = "edge";    else if (dim == 2)      facetype = "surfaces";    else if (dim == 3)      facetype = "region";    {      ostringstream ost1;      ost1 << "Error occurred while reading " << facetype << " list";      errinfo.set_string(ost1.str());    }    Top_face_inserter tfi(newbrep, dim);    is.get_left_paren();    for (;;) {      string facename;      if (!is.get_string(facename)) break;      Brep::Face_Spec fspec = tfi.insert_top_face(facename);      facename_lookup.insert(facename, fspec);      {        ostringstream ost1;        ost1 << "Error occurred while reading property-value list of topological " <<          facetype << " \"" << facename << "\"";        errinfo.set_string(ost1.str());      }            // Insert property value pairs.            Top_face_propval_inserter tpvi(newbrep, fspec);      is.get_left_paren();      for (;;) {        string prop, val;        if (!is.get_string(prop)) break;        bool s2 = is.get_string(val);        if (!s2)           throw_error("Unmatched property (property-values must come in pairs)");        tpvi.insert_propval(prop,val);      }            // Insert bounding faces.  Note: bounding faces may be prefixed      // by + or - to indicate orientation.            {        ostringstream ost1;        ost1 << "Error occurred while reading boundaries of topological " <<          facetype << " \"" << facename << "\"";        errinfo.set_string(ost1.str());      }      Top_face_bound_inserter tbi(newbrep, fspec);      is.get_left_paren();      for (;;) {        string subfacename;        if (!is.get_string(subfacename)) break;        int ori = 2;        if (subfacename[0] == '+') {          ori = 0;          subfacename = subfacename.substr(1, subfacename.length() - 1);        }        else if (subfacename[0] == '-') {          ori = 1;          subfacename = subfacename.substr(1, subfacename.length() - 1);        }                Brep::Face_Spec subfspec = facename_lookup.find(subfacename);        tbi.insert_boundary(subfspec, ori);      }                  // Insert internal bounding faces.      {        ostringstream ost1;        ost1 << "Error occurred while reading internal boundaries of topological "          << facetype << " \"" << facename << "\"";        errinfo.set_string(ost1.str());      }      Top_face_ib_inserter ibi(newbrep, fspec);      is.get_left_paren();      for (;;) {        string subfacename;        if (!is.get_string(subfacename)) break;        Brep::Face_Spec subspec = facename_lookup.find(subfacename);        if (subspec.fdim() == dim - 1) {          tbi.insert_boundary(subspec, 2);          tbi.insert_boundary(subspec, 2);        }        else {          ibi.insert_ib(subspec);        }      }      // Insert patches      {        ostringstream ost1;        ost1 << "Error occurred while reading patches of topological " << facetype          << " \"" << facename << "\"";        errinfo.set_string(ost1.str());      }      Top_face_patch_inserter pti(newbrep, fspec);      is.get_left_paren();      vector<Brep::ControlPointIndex> cp;      int patchcount = 0;      for (;;) {        string patchstr;        if (!is.get_string(patchstr)) break;        ++patchcount;        istringstream is2a(patchstr);        Istream_skip_comments is2(is2a);        is2.get_left_paren();        string patchcode;        bool string_read2 = is2.get_string(patchcode);        if (!string_read2)          throw_error("Missing patch type name");        PatchType ptype = BEZIER_TRIANGLE;        if (dim == 0) {          if (compare_nocase(patchcode, "vertex") != 0)            throw_error("Patch type must be 'vertex' for topological vertices");        }        else if (dim == 1) {          if (compare_nocase(patchcode, "bezier_curve") != 0)            throw_error("Patch type must be 'bezier_curve' for topological edges");        }        else if (dim == 2) {          if (compare_nocase(patchcode, "bezier_quad") == 0)            ptype = BEZIER_QUAD;          else if (compare_nocase(patchcode, "bezier_triangle") == 0)            ptype = BEZIER_TRIANGLE;          else            throw_error("Patch type must be either bezier_quad or bezier_triangle\n"            "for topological surface");        }        else {          throw_error("No patches allowed here");        }        int degree1, degree2;        if (dim >= 1) {          bool int_read = is2.get_int(degree1);          if (!int_read) throw_error("Order (integer) missing");        }        if (dim == 2 && ptype == BEZIER_QUAD) {          bool int_read = is2.get_int(degree2);          if (!int_read) throw_error("Order (integer) missing (2)");        }        cp.resize(0);        for (;;) {          Brep::ControlPointIndex cpi;          if (!is2.get_int(cpi)) break;          cp.push_back(cpi);        }        pti.insert_patch(degree1, degree2, ptype, cp);      }      if (dim == 0 && patchcount != 1) {        throw_error("Topological vertex must have exactly one patch");      }    }  }  line_count = is.linecount();  return newbrep;}// ------------------------------------------------------------------// Read a mesh from an istream.// Second argument is true if the header code has already been read// by another reader.  Third argument indicates the number of lines of// the file already read.QMG::SimpComplex_Under_ConstructionQMG::SimpComplex_Under_Construction::read_from_istream(istream& istr,                   bool code_already_read,                  int& line_count) {  // errinfo keeps track of the current operation of the parser;  // used for issuing intelligent error messages.    Error_Message errinfo;  errinfo.set_string("Error occurred while reading header info");  Istream_skip_comments is(istr, line_count);  if (!code_already_read) {    string code;    is.get_string(code);    if (compare_nocase(code, SimpComplex::io_header_code()))      throw_error("File begins with incorrect code");  }  int gdim, embedded_dim;  if (!is.get_int(gdim)) throw_error("Misplaced right paren");  if (!is.get_int(embedded_dim)) throw_error("Misplaced right paren");  errinfo.set_string("Error occurred while mesh's prop-val pairs");  vector<int> levsize(gdim + 1, 0);    SimpComplex_Under_Construction newsc(gdim, embedded_dim, levsize);  is.get_left_paren();  for (;;) {    string prop, val;    if (!is.get_string(prop)) break;    bool s2 = is.get_string(val);    if (!s2)       throw_error("Unmatched property (property-values must come in pairs)");    newsc.add_prop_val(prop,val);  }  errinfo.set_string("Error occurred while reading node coordinates");  is.get_left_paren();  int vnum = 0;  vector<Real> realcoord(embedded_dim);  for (;;) {    SimpComplex::VertexGlobalIndex vnum;    if (!is.get_int(vnum))      break;    for (int j = 0; j < embedded_dim; ++j) {      if (!is.get_double(realcoord[j]))        throw_error("Missing or unbalanced number of doubles (real node coords)");    }    newsc.add_vertex(realcoord,vnum);      }  vector<Real> paramcoord;  vector<SimpComplex::VertexGlobalIndex> vlist;  for (int fdim = 0; fdim <= gdim; ++fdim) {    is.get_left_paren();    Brep::FaceIndex faceind = 0;    paramcoord.resize(fdim);    vlist.resize(fdim + 1);    for (;;) {      Brep::Face_Spec fspec(fdim,faceind);      {        ostringstream ost1;        ost1 << "Error occurred while reading nodes incident on top. entity" << fspec;            errinfo.set_string(ost1.str());      }      if (!is.get_left_paren2()) break;      newsc.add_fspec(fspec);      for (;;) {        SimpComplex::VertexGlobalIndex vnum;        if (!is.get_int(vnum))          break;        Brep::PatchIndex patchind = 0;        if (fdim > 0) {          if (!is.get_int(patchind))            throw_error("Missing integer (curve/patch index)");        }        for (int j = 0; j < fdim; ++j) {          if (!is.get_double(paramcoord[j]))            throw_error("Missing double (param coord of node on top. entity)");        }        newsc.add_vertex_bdryinc(vnum, fspec, patchind, paramcoord);      }      {        ostringstream ost1;        ost1 << "Error occurred while reading mesh entities lying on top. entity" << fspec;            errinfo.set_string(ost1.str());      }      is.get_left_paren();      for (;;) {        bool done = false;        for (int j = 0; j < fdim + 1; ++j) {          if (!is.get_int(vlist[j])) {            if (j == 0) {              done = true;              break;            }            else {              throw_error("Wrong number of integers in list of mesh entities");            }          }        }        if (done) break;        newsc.add_simplex_face(vlist, fspec);      }      ++faceind;    }  }  line_count = is.linecount();  return newsc;}// Reads just the header code from an istream, and determines whether// the file contains a mesh or a brep.  It keeps track of the number// of lines read (for the purpose of useful error messages).QMG::Object_Type_CodeQMG::read_header_from_istream(istream& istr, int& line_count) {    Error_Message errinfo;  errinfo.set_string("Error occurred while reading file type");  Istream_skip_comments is(istr, line_count);   string code;  is.get_string(code);  line_count = is.linecount();  if (compare_nocase(code, Brep::io_header_code()) == 0)    return BREP;  else if (compare_nocase(code, SimpComplex::io_header_code()) == 0)    return SIMPCOMPLEX;  else    return UNKNOWN;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?