gm_obj2list.cpp
来自「算断裂的」· C++ 代码 · 共 409 行
CPP
409 行
// ------------------------------------------------------------------// gm_obj2list.cpp//// This file contains the driver function and work routines for// converting a brep or mesh to a Tcl/Tk list.// ------------------------------------------------------------------// Author: Stephen A. Vavasis// Copyright (c) 1999 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 September 3, 1999.// ------------------------------------------------------------------extern "C" {#include "tcl.h"}#include "qbrep.h"#include "qsimpcomp.h"#include "qerr.h"namespace QMG { // ------------------------------------------------------------------ // see brepstream.cpp namespace FrontEnd { extern Object_Type_Code get_obj_type(Tcl_Interp* interp, Tcl_Obj* obj); extern Brep_From_FrontEnd get_brep_from_obj(Tcl_Interp* interp, Tcl_Obj* obj, int& returncode); extern SimpComplex_From_FrontEnd get_simpcomp_from_obj(Tcl_Interp* interp, Tcl_Obj* obj, int& returncode); }}namespace { using namespace QMG; class AutoTclObjList { private: Tcl_Obj** data_; int sz_; AutoTclObjList(const AutoTclObjList&) { } void operator=(const AutoTclObjList&) { } public: AutoTclObjList(int sz) : data_(new Tcl_Obj*[sz]), sz_(sz) { } ~AutoTclObjList() {delete[] data_;} Tcl_Obj* make_list() { return Tcl_NewListObj(sz_, data_); } Tcl_Obj*& operator[](int i) {#ifdef RANGECHECK if (i < 0 || i >= sz_) throw_error("Range error");#endif return data_[i]; } }; // ------------------------------------------------------------------ // convert_brep2list // convert a brep to a list. Return a pointer to the new list. Tcl_Obj* convert_brep2list(const Brep& g) { int gdim = g.gdim(); if (gdim < -1 || gdim > 3) throw_error("Gdim out of range in convert_brep2list"); int di = g.embedded_dim(); // A brep is a list with gdim+6 elements. AutoTclObjList elems(gdim + 6); // element 0: header code elems[0] = Tcl_NewStringObj(const_cast<char*>(Brep::io_header_code()), -1); // element 1: gdim elems[1] = Tcl_NewIntObj(gdim); // element 2: embedded_dim elems[2] = Tcl_NewIntObj(di); { int bpvlength = 0; for (Brep::Loop_over_propvals_of_brep bpvloop0(g); bpvloop0.notdone(); ++bpvloop0) { bpvlength += 2; } AutoTclObjList bpvlist(bpvlength); int bpos = 0; for (Brep::Loop_over_propvals_of_brep bpvloop(g); bpvloop.notdone(); ++bpvloop) { bpvlist[bpos++] = Tcl_NewStringObj(const_cast<char*>(bpvloop.prop().c_str()), -1); bpvlist[bpos++] = Tcl_NewStringObj(const_cast<char*>(bpvloop.val().c_str()), -1); } // element 3: property-values of the entire brep. elems[3] = bpvlist.make_list(); } // element 4: control point coordinates. { int cplength = g.num_control_points() * di; AutoTclObjList cplist(cplength); for (int j1 = 0; j1 < g.num_control_points(); ++j1) { for (int d = 0; d < di; ++d) { cplist[j1 * di + d] = Tcl_NewDoubleObj(g.control_point(j1,d)); } } elems[4] = cplist.make_list(); } // Output topological faces // elements 5 to 5+gdim: the topological faces arranged by dimension. for (int dim = 0; dim <= g.gdim(); ++dim) { int levlth = g.level_size(dim) * 5; AutoTclObjList flist(levlth); int flistpos = 0; for (Brep::Face_Spec_Loop_Over_Faces_Of_Dim fspec(g, dim); fspec.notdone(); ++fspec) { // Each face is composed of 5 elements. // element 0: face name flist[flistpos++] = Tcl_NewStringObj(const_cast<char*>(g.face_name(fspec).c_str()), -1); // element 1: prop-vals of the face int pvlength = 0; for (Brep::Loop_over_propvals_of_face pvloop0(g, fspec); pvloop0.notdone(); ++pvloop0) { pvlength += 2; } AutoTclObjList pvlist(pvlength); int pos = 0; for (Brep::Loop_over_propvals_of_face pvloop(g, fspec); pvloop.notdone(); ++pvloop) { pvlist[pos++] = Tcl_NewStringObj(const_cast<char*>(pvloop.prop().c_str()), -1); pvlist[pos++] = Tcl_NewStringObj(const_cast<char*>(pvloop.val().c_str()), -1); } flist[flistpos++] = pvlist.make_list(); // elements 2 & 3 children and internal boundaries int chlength = 0; int iblength = 0; for (Brep::Face_Spec_Loop_Over_Face_Subfaces subfspec0(g, fspec); subfspec0.notdone(); ++subfspec0) { if (subfspec0.is_internal_boundary()) ++iblength; else ++chlength; } AutoTclObjList chlist(chlength); AutoTclObjList iblist(iblength); int chpos = 0; int ibpos = 0; for (Brep::Face_Spec_Loop_Over_Face_Subfaces subfspec(g, fspec); subfspec.notdone(); ++subfspec) { if (subfspec.is_internal_boundary()) { iblist[ibpos++] = Tcl_NewStringObj(const_cast<char*>(g.face_name(subfspec).c_str()), -1); } else { ostringstream ostr; if (subfspec.orientation() == 0) ostr << '+'; else if (subfspec.orientation() == 1) ostr << '-'; ostr << g.face_name(subfspec); chlist[chpos++] = Tcl_NewStringObj(const_cast<char*>(ostr.str().c_str()), -1); } } flist[flistpos++] = chlist.make_list(); flist[flistpos++] = iblist.make_list(); // element 4: patches int bzlength = 0; for (Brep::Loop_over_patches_of_face patch0(g, fspec); patch0.notdone(); ++patch0) { ++bzlength; } AutoTclObjList bzlist(bzlength); int bzpos = 0; for (Brep::Loop_over_patches_of_face patch(g, fspec); patch.notdone(); ++patch) { if (fspec.fdim() == 0) { AutoTclObjList vtlist(2); vtlist[0] = Tcl_NewStringObj("vertex", -1); vtlist[1] = Tcl_NewIntObj(patch.control_point(0)); bzlist[bzpos++] = vtlist.make_list(); } else if (fspec.fdim() == 1) { int llength = patch.degree1() + 3; AutoTclObjList vtlist(llength); vtlist[0] = Tcl_NewStringObj("bezier_curve", -1); vtlist[1] = Tcl_NewIntObj(patch.degree1()); for (int j = 0; j < patch.degree1() + 1; ++j) { vtlist[j + 2] = Tcl_NewIntObj(patch.control_point(j)); } bzlist[bzpos++] = vtlist.make_list(); } else if (fspec.fdim() == 2) { if (patch.ptype() == BEZIER_QUAD) { int ncp = (patch.degree1() + 1) * (patch.degree2() + 1); int llength = ncp + 3; AutoTclObjList vtlist(llength); vtlist[0] = Tcl_NewStringObj("bezier_quad", -1); vtlist[1] = Tcl_NewIntObj(patch.degree1()); vtlist[2] = Tcl_NewIntObj(patch.degree2()); for (int j = 0; j < ncp; ++j) { vtlist[j + 3] = Tcl_NewIntObj(patch.control_point(j)); } bzlist[bzpos++] = vtlist.make_list(); } else { int ncp = (patch.degree1() + 1) * (patch.degree1() + 2) / 2 ; int llength = ncp + 2; AutoTclObjList vtlist(llength); vtlist[0] = Tcl_NewStringObj("bezier_triangle", -1); vtlist[1] = Tcl_NewIntObj(patch.degree1()); for (int j = 0; j < ncp; ++j) { vtlist[j + 2] = Tcl_NewIntObj(patch.control_point(j)); } bzlist[bzpos++] = vtlist.make_list(); } } } flist[flistpos++] = bzlist.make_list(); } elems[dim + 5] = flist.make_list(); } Tcl_Obj* brepl = elems.make_list(); return brepl; } // ------------------------------------------------------------------ // convert_simpcomp2list // Convert a simplicial complex to a Tcl list. Tcl_Obj* convert_simpcomp2list(const SimpComplex& s) { int gdim = s.gdim(); int di = s.embedded_dim(); AutoTclObjList elems(gdim + 6); elems[0] = Tcl_NewStringObj(const_cast<char*>(SimpComplex::io_header_code()), -1); elems[1] = Tcl_NewIntObj(gdim); elems[2] = Tcl_NewIntObj(di); { int npv = s.num_prop_val(); AutoTclObjList pvlist(2 * npv); for (int pvi = 0; pvi < npv; ++pvi) { pvlist[pvi * 2] = Tcl_NewStringObj(const_cast<char*>(s.prop(pvi).c_str()), -1); pvlist[pvi * 2 + 1] = Tcl_NewStringObj(const_cast<char*>(s.val(pvi).c_str()), -1); } elems[3] = pvlist.make_list(); } // Convert node list. { int nnode = s.num_nodes(); AutoTclObjList cplist(nnode * (di + 1)); for (SimpComplex::VertexOrdinalIndex vnumo = 0; vnumo < nnode; ++vnumo) { SimpComplex::VertexGlobalIndex vnum = s.ordinal_to_global(vnumo); cplist[vnumo * (di + 1)] = Tcl_NewIntObj(vnum); for (int j = 0; j < di; ++j) { cplist[vnumo * (di + 1) + j + 1] = Tcl_NewDoubleObj(s.real_coord_o(vnumo, j)); } } elems[4] = cplist.make_list(); } // Convert simplices for (int fdim = 0; fdim <= gdim; ++fdim) { int levsize = s.brep_levelsize(fdim); AutoTclObjList facelist(2 * levsize); for (Brep::FaceIndex faceind = 0; faceind < levsize; ++faceind) { Brep::Face_Spec fspec(fdim, faceind); int nnf = s.num_node_on_face(fspec); int nlsize = (fdim == 0)? 1 : 2 + fdim; AutoTclObjList node_on_face(nnf * nlsize); for (int seqno = 0; seqno < nnf; ++seqno) { node_on_face[seqno * nlsize] = Tcl_NewIntObj(s.node_on_face(fspec, seqno)); if (fdim > 0) node_on_face[seqno * nlsize + 1] = Tcl_NewIntObj(s.patchind_on_face(fspec, seqno)); for (int k = 0; k < fdim; ++k) { node_on_face[seqno * nlsize + 2 + k] = Tcl_NewDoubleObj(s.param_coord_on_face(fspec, seqno, k)); } } facelist[faceind * 2] = node_on_face.make_list(); int nmf = (fdim == 0)? 0 : s.num_meshface_on_face(fspec); AutoTclObjList simp_on_face(nmf * (fdim + 1)); for (int seqno2 = 0; seqno2 < nmf; ++seqno2) { for (int k = 0; k < fdim + 1; ++k) { simp_on_face[seqno2 * (fdim + 1) + k] = Tcl_NewIntObj(s.node_of_meshface_on_face(fspec, seqno2, k)); } } facelist[faceind * 2 + 1] = simp_on_face.make_list(); } elems[5 + fdim] = facelist.make_list(); } Tcl_Obj* newobj = elems.make_list(); return newobj; }}extern "C" { // Driver routine. No need for the worker/driver split since // this one is Tcl only.int gm_obj2list(ClientData clientdata, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { using namespace QMG::FrontEnd; QMG::Error_Message::init_error_message_list(); QMG::Error_Task::init_error_task_list(); if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "object"); return TCL_ERROR; } Object_Type_Code code = get_obj_type(interp, objv[1]); if (code == UNKNOWN) { Tcl_AppendResult(interp, "Argument to gm_obj2list neither a brep nor simpcomplex", 0); return TCL_ERROR; } Tcl_Obj* newobj; int returncode; if (code == BREP) { Brep_From_FrontEnd b = get_brep_from_obj(interp, objv[1], returncode); if (returncode != TCL_OK) { Tcl_AppendResult(interp, "Conversion to brep of argument 0 in gm_obj2list failed",0); return TCL_ERROR; } try { newobj = convert_brep2list(b); } catch(QMG::Error e) { Tcl_AppendResult(interp, e.get_error_messages(), 0); Tcl_AppendResult(interp, "gm_obj2list terminated because of exception.", 0); return TCL_ERROR; } catch(...) { Tcl_AppendResult(interp, "gm_obj2list terminated because of unknown exception", 0); return TCL_ERROR; } } else { SimpComplex_From_FrontEnd s = get_simpcomp_from_obj(interp, objv[1], returncode); if (returncode != TCL_OK) { Tcl_AppendResult(interp, "Conversion to simpcomp of argument 0 in gm_obj2list failed",0); return TCL_ERROR; } try { newobj = convert_simpcomp2list(s); } catch(QMG::Error e) { Tcl_AppendResult(interp, e.get_error_messages(), 0); Tcl_AppendResult(interp, "gm_obj2list terminated because of exception.", 0); return TCL_ERROR; } catch(...) { Tcl_AppendResult(interp, "gm_obj2list terminated because of unknown exception", 0); return TCL_ERROR; } } Tcl_SetObjResult(interp, newobj); return TCL_OK;}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?