⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmgxdr.cpp

📁 算断裂的
💻 CPP
字号:
// ------------------------------------------------------------------
// qmgxdr.cpp
//
// This file contains routines for reading and writing breps and
// and meshes to/from files in XDR format.
// ------------------------------------------------------------------
// Copyright (c) 1998 by Cornell University.  All rights reserved.
// 
// See the accompanying file 'Copyright' for authorship information,
// the terms of the license governing this software, and disclaimers
// concerning this software.
// ------------------------------------------------------------------
// This file is part of the QMG software.  
// Version 2.0 of QMG, release date RELDATE
// ------------------------------------------------------------------


#include "cptc_geomsh_utils.h"
#include <stdio.h>
#include "tcl.h"
#include "qbrep.h"
#include "qsimpcomp.h"

namespace QMG {
  namespace FrontEnd {
    using namespace QMG;
    extern Tcl_Obj* new_brep_obj(Cptc_GeomDesc* geo);
    extern Brep_From_FrontEnd get_brep_from_obj(Tcl_Interp* interp, Tcl_Obj* obj, int& returncode);
    extern Tcl_Obj* new_simpcomp_obj(Cptc_MshDesc* msh);
    extern SimpComplex_From_FrontEnd 
      get_simpcomp_from_obj(Tcl_Interp* interp, Tcl_Obj* obj, int& returncode);
    Object_Type_Code get_obj_type(Tcl_Interp*, Tcl_Obj* obj);
  }
}
extern "C" bool_t xdr_Cptc_GeomDesc(XDR* xdrs, Cptc_GeomDesc** geop);
extern "C" bool_t xdr_Cptc_MshDesc(XDR* xdrs, Cptc_MshDesc** mshp);
extern "C" void xdrstdio_create(XDR* xdrs, FILE* file, enum xdr_op op);

namespace {
  using namespace QMG;
  class Brep_With_Pointer_Release : public QMG::Brep {
  public:
    explicit Brep_With_Pointer_Release(const QMG::Brep& b) : Brep(b) { }
    Cptc_GeomDesc* geomdesc() {return geo_;}
  };
  class SimpComplex_With_Pointer_Release : public QMG::SimpComplex {
  public:
    explicit SimpComplex_With_Pointer_Release(const QMG::SimpComplex& s) : 
    SimpComplex(s) { }
    Cptc_MshDesc* meshdesc() {return mesh_;}
  };

  class Auto_file {
  private:
    FILE* chan_;
  public:
    Auto_file(const char* fname, const char* openmode) : chan_(fopen(fname, openmode)) { }
    ~Auto_file() {
      if (chan_) fclose(chan_);
    }
    FILE* get_fp() {
      return chan_;
    }
  };
  void* malloc1(size_t sz) {
    void* p = malloc(sz);
    if (p == 0) throw_error("Out of memory");
    return p;
  }
}


extern "C" {
  

  // ------------------------------------------------------------------
  // gmxdr_read
  // Read a brep or mesh from an xdr-format file.

  int gmxdr_read(ClientData,
    Tcl_Interp* interp,
    int objc,
    Tcl_Obj* const objv[]) {

    using std:: string;

    if (objc != 2) {
      Tcl_WrongNumArgs(interp, 1, objv, "<filename>");
      return TCL_ERROR;
    }

    XDR xdrs[1];

    int filenamelength;
    char* filename = Tcl_GetStringFromObj(objv[1], &filenamelength);
    QMG::string s(filename, filenamelength);

    Auto_file channel(s.c_str(), "rb");
    if (channel.get_fp() == 0) {
      Tcl_AppendResult(interp, "Unable to open file", 0);
      return TCL_ERROR;
    }
    
    xdrstdio_create(xdrs, channel.get_fp(), XDR_DECODE);  
    /*
    if (rcode == FALSE) {
      Tcl_AppendResult(interp, "xdrstdio_create failed", 0);
      return TCL_ERROR;
    }
    */


    char* header;

    bool_t rcode = xdr_Cptc_header(xdrs, &header);
    if (rcode == FALSE) {
      Tcl_AppendResult(interp, 
        "xdr read header failed possibly indicating "
        "that the file is not in XDR format", 0);
      return TCL_ERROR;
    }
    
    string validcode(header, 4);
    string typecode(&header[4], 4);
    free(header);
    if (validcode != "abcd") {
      Tcl_AppendResult(interp,
        "xdr file header lacks correct validation code indicating"
        " that the file is not in XDR format", 0);
      return TCL_ERROR;
    }
    if (typecode == "geo ") {
      Cptc_GeomDesc* geop;
      rcode = xdr_Cptc_GeomDesc(xdrs, &geop);
      if (rcode == FALSE) {
        Tcl_AppendResult(interp, "xdr read GeomDesc failed", 0);
        return TCL_ERROR;
      }    
      Tcl_Obj* returnval = QMG::FrontEnd::new_brep_obj(geop);
      Tcl_SetObjResult(interp, returnval);
      return TCL_OK;
    }
    else if (typecode == "msh2") {  
      Cptc_MshDesc* mshp;
      bool_t rcode = xdr_Cptc_MshDesc(xdrs, &mshp);
      if (rcode == FALSE) {
        Tcl_AppendResult(interp, "xdr read MshDesc failed", 0);
        return TCL_ERROR;
      }      
      Tcl_Obj* returnval = QMG::FrontEnd::new_simpcomp_obj(mshp);
      Tcl_SetObjResult(interp, returnval);
      return TCL_OK;
    }
    Tcl_AppendResult(interp, "Xdr file type ", 
      const_cast<char*>(typecode.c_str()),
      " cannot be read by QMG", 0);
    return TCL_ERROR;
  }

  // ------------------------------------------------------------------
  // gmxdr_write
  // Write a geo or mesh to a file in XDR format.

  int gmxdr_write(ClientData,
    Tcl_Interp* interp,
    int objc,
    Tcl_Obj* const objv[]) {
    if (objc < 3) {

      using std:: string;

      Tcl_WrongNumArgs(interp, 2, objv, "<object> <filename>");
      return TCL_ERROR;
    }
    if (objc > 4) {
      Tcl_WrongNumArgs(interp, 3, objv, "<object> <filename> {<prefix>}");
      return TCL_ERROR;
    }
    string prefix;
    if (objc >= 4) {
      int prefixlen;
      char* prefix1 = Tcl_GetStringFromObj(objv[3], &prefixlen);
      string pref1(prefix1, prefixlen);
      prefix = pref1;
    }


    int returncode;
    
    Object_Type_Code code = QMG::FrontEnd::get_obj_type(interp, objv[1]);
    if (code != BREP && code != SIMPCOMPLEX) {
      Tcl_AppendResult(interp, "Object is neither a brep nor simplicial complex", 0);
      return TCL_ERROR;
    }
    
    XDR xdrs[1];

    int filenamelength;
    char* filename = Tcl_GetStringFromObj(objv[2], &filenamelength);
    QMG::string s(filename, filenamelength);

    Auto_file channel(s.c_str(), "wb");
    if (channel.get_fp() == 0) {
      Tcl_AppendResult(interp, "Unable to open file", 0);
      return TCL_ERROR;
    }
    
    xdrstdio_create(xdrs, channel.get_fp(), XDR_ENCODE);  

    if (code == BREP) {
      Brep_With_Pointer_Release 
        brep(QMG::FrontEnd::get_brep_from_obj(interp, objv[1], returncode));
      if (returncode != TCL_OK)
        return returncode;
      if (brep.gdim() != 3 || brep.embedded_dim() != 3) {
        Tcl_AppendResult(interp, "gmxdr_write valid only for 3-dimensional breps", 0);
        return TCL_ERROR;
      }
      
      bool_t rcode = cptc_xdr_write_header(xdrs, "geo", 
        const_cast<char*>(prefix.c_str()));
      if (rcode == FALSE) {
        Tcl_AppendResult(interp, "unable to write xdr header", 0);
        return TCL_ERROR;
      }
      Cptc_GeomDesc* geop = brep.geomdesc();
      rcode = xdr_Cptc_GeomDesc(xdrs, &geop);
      if (rcode == FALSE) {
        Tcl_AppendResult(interp, "xdr write GeomDesc failed", 0);
        return TCL_ERROR;
      }
      return TCL_OK;
    }
    else {
      SimpComplex_With_Pointer_Release 
        sc(QMG::FrontEnd::get_simpcomp_from_obj(interp, objv[1], returncode));
      if (returncode != TCL_OK)
        return returncode;
      Cptc_MshDesc* msh = sc.meshdesc();
      if (sc.gdim() != 3 || sc.embedded_dim() != 3) {
        Tcl_AppendResult(interp, "gmxdr_write valid only for 3-dimensional meshes", 0);
        return TCL_ERROR;
      }
      
      bool_t rcode = cptc_xdr_write_header(xdrs, "msh2", 
        const_cast<char*>(prefix.c_str()));
      if (rcode == FALSE) {
        Tcl_AppendResult(interp, "unable to write xdr header", 0);
        return TCL_ERROR;
      }
      rcode = xdr_Cptc_MshDesc(xdrs, &msh);
      if (rcode == FALSE) {
        Tcl_AppendResult(interp, "xdr write MshDesc failed", 0);
        return TCL_ERROR;
      }
      return TCL_OK;
    }
  }
}

⌨️ 快捷键说明

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