📄 qbrep.cpp
字号:
// ------------------------------------------------------------------// qbrep.cpp//// This file contains the member functions of the class Brep and its// nested classes (for Matlab scripting).// ------------------------------------------------------------------// 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.// ------------------------------------------------------------------#include "qbrep.h"#include <cmath>#include "string.h"namespace { // This is a function object used for a map whose key is a string. // We want to compare strings disregarding case. using namespace QMG; class Nocase { public: bool operator() (const string& x, const string& y) const { return compare_nocase(x,y) < 0; } }; // ------------------------------------------------------------------ // Class Face_lookup_map_type // This is a map from strings to fspecs. // It generates errors upon duplication, and so on. It is used // for keeping track of face names when a brep is read in. class Face_lookup_map_type { private: typedef map <string, Brep::Face_Spec, Nocase> Actual_Map_type; Actual_Map_type actual_map_; public: Face_lookup_map_type() { } ~Face_lookup_map_type() { } void insert(const string& facename, const Brep::Face_Spec& fspec) { const char* tmp = facename.c_str(); string tmp2 = string(tmp); pair<Actual_Map_type::iterator, bool> rval = actual_map_.insert(pair<string,Brep::Face_Spec>(tmp2, fspec)); if (!rval.second) { string errmsg = string("Duplicate face name ") + facename + " occurs in brep"; throw_error(errmsg); } return; } Brep::Face_Spec find(const string& facename) const { Actual_Map_type::const_iterator it = actual_map_.find(facename); if (it == actual_map_.end()) { string errmsg = string("Face ") + facename + " listed as a subface but is not found"; throw_error(errmsg); } return it -> second; } };}QMG::Brep_From_FrontEnd::Brep_From_FrontEnd(const mxArray* geo) { if (geo == 0 || strcmp(mxGetClassName(geo), "zba") != 0) throw_error("Input array not of class zba"); geo_ = geo; const mxArray* geoentries = mxGetFieldByNumber(geo_,0,0); if (geoentries == 0 || !mxIsCell(geoentries)) throw_error("Input array has no field 0 (not a brep)"); const mxArray* geoentries1 = mxGetFieldByNumber(geo_,0,0); if (geoentries != geoentries1) throw_error("geoentries != geoentries1"); const mxArray* typecode = mxGetCell(geoentries, 0); if (typecode == 0 || !mxIsChar(typecode) || mxIsSparse(typecode) || mxGetM(typecode) != 1) throw_error("Cell 0 (type code) missing or wrong format"); int lth1 = mxGetN(typecode); if (lth1 != strlen(io_header_code())) throw_error("Typecode has wrong size -- object not a brep"); char buf[100]; if (mxGetString(typecode, buf, 100) || compare_nocase(string(buf), string(io_header_code())) != 0) throw_error("Incorrect typecode -- object not a brep"); const mxArray* gdima = mxGetCell(geoentries, 1); if (gdima == 0 || !mxIsDouble(gdima) || mxIsSparse(gdima) || mxGetPi(gdima) || mxGetM(gdima) * mxGetN(gdima) != 1) throw_error("Missing or ill-formatted intrinsic dim field"); c_gdim_ = static_cast<int>(mxGetScalar(gdima)); const mxArray* edima = mxGetCell(geoentries, 2); if (edima == 0 || !mxIsDouble(edima) || mxIsSparse(gdima) || mxGetPi(gdima) || mxGetM(edima) * mxGetN(edima) != 1) throw_error("Missing or ill formatted embedded dim field"); c_embedded_dim_ = static_cast<int>(mxGetScalar(edima)); c_pvlist_ = mxGetCell(geoentries, 3); if (c_pvlist_ == 0 || !mxIsCell(c_pvlist_)) throw_error("Missing pv list"); int numpv1 = mxGetM(c_pvlist_); int numpv2 = mxGetN(c_pvlist_); if (numpv2 > 0 && numpv1 != 2) throw_error("Brep PV list must be 2-by-k cell array"); c_numpv_ = numpv2; const mxArray* controlpoints = mxGetCell(geoentries, 4); if (controlpoints == 0 || !mxIsDouble(controlpoints) || mxIsSparse(controlpoints) || mxGetPi(controlpoints)) throw_error("Missing or illegal control points field"); c_num_control_points_ = mxGetN(controlpoints); int ncp2 = mxGetM(controlpoints); if (c_num_control_points_ > 0 && ncp2 != c_embedded_dim_) throw_error("Number of columns in control point matrix must equal embedded dim"); c_control_points_ = mxGetPr(controlpoints); if (c_control_points_ == 0) throw_error("mxGetPr failed for control points"); if (mxGetM(geoentries) != 6 + c_gdim_ || mxGetN(geoentries) != 1) throw_error("Number of topological entity entries disagrees with intrinsic dimension"); child_lookup_map_ = new ChildLookupMapType; ib_lookup_map_ = new IBLookupMapType; Face_lookup_map_type face_lookup_map; for (int fdim = 0; fdim <= c_gdim_; ++fdim) { mxArray* lev = mxGetCell(geoentries, 5 + fdim); c_top_faces_[fdim] = lev; int levsize = mxGetN(c_top_faces_[fdim]); c_num_top_faces_[fdim] = levsize; if (c_num_top_faces_[fdim] > 0 && mxGetM(c_top_faces_[fdim]) != 5) throw_error("Topological entity arrays should be 5-by-k"); for (int faceind = 0; faceind < levsize; ++faceind) { Brep::Face_Spec fspec(fdim, faceind); mxArray* fname = mxGetCell(lev, faceind * 5); if (fname == 0 || !mxIsChar(fname) || mxGetM(fname) != 1 || mxIsSparse(fname)) throw_error("Face name missing or wrong format"); int len = mxGetN(fname); char* buf1 = new char[len + 2]; mxGetString(fname, buf1, len + 1); face_lookup_map.insert(string(buf1), fspec); delete[] buf1; mxArray* childlist = mxGetCell(lev, faceind * 5 + 2); if (childlist == 0 || !mxIsCell(childlist) || (mxGetN(childlist) > 0 && mxGetM(childlist) != 1)) throw_error("Child list should be 1-by-k cell array"); int nc = mxGetN(childlist); vector<Face_Rec1>& v1 = (*child_lookup_map_)[fspec]; for (int j = 0; j < nc; ++j) { mxArray* child = mxGetCell(childlist, j); if (child == 0 || !mxIsChar(child) || mxIsSparse(child) || mxGetM(child) != 1) throw_error("Child list entry not a string"); int len2 = mxGetN(child); char* buf2 = new char[len2 + 2]; mxGetString(child, buf2, len2 + 1); int ori = 2; int startp1 = 0; if (buf2[0] == '+') { ori = 0; startp1 = 1; } if (buf2[0] == '-') { ori = 1; startp1 = 1; } Face_Spec child_fspec = face_lookup_map.find(string(&buf2[startp1])); delete[] buf2; if (child_fspec.fdim() != fdim - 1) throw_error("Listed child is of the wrong dimension"); Face_Rec1 rec1; rec1.faceind = child_fspec.faceind(); rec1.ori = ori; v1.push_back(rec1); } vector<Face_Spec>& v2 = (*ib_lookup_map_)[fspec]; mxArray* iblist = mxGetCell(lev, faceind * 5 + 3); if (iblist == 0 || !mxIsCell(iblist) || (mxGetN(iblist) > 0 && mxGetM(iblist) != 1)) throw_error("ib list should be k-by-1 cell array"); int nib = mxGetN(iblist); for (int j2 = 0; j2 < nib; ++j2) { mxArray* ib = mxGetCell(iblist, j2); if (ib == 0 || !mxIsChar(ib) || mxIsSparse(ib) || mxGetM(ib) != 1) throw_error("ib list entry not a string"); int len2 = mxGetN(ib); char* buf2 = new char[len2 + 2]; mxGetString(ib, buf2, len2 + 1); Face_Spec ib_fspec = face_lookup_map.find(string(buf2)); delete[] buf2; if (ib_fspec.fdim() >= fdim) throw_error("Listed ib is of the wrong dimension"); if (ib_fspec.fdim() == fdim - 1) { Face_Rec1 rec1; rec1.faceind = ib_fspec.faceind(); rec1.ori = 2; v1.push_back(rec1); v1.push_back(rec1); } else { v2.push_back(ib_fspec); } } } }}QMG::Brep_From_FrontEnd::~Brep_From_FrontEnd() { delete child_lookup_map_; delete ib_lookup_map_;}QMG::Brep_From_FrontEnd::Brep_From_FrontEnd(Brep_From_FrontEnd& other): Brep(other) { other.child_lookup_map_ = 0; other.ib_lookup_map_ = 0;}QMG::Brep_From_FrontEnd::Brep_From_FrontEnd(const Brep_From_FrontEnd_Returnval& bucr) : Brep(bucr.sref_) { bucr.sref_.child_lookup_map_ = 0; bucr.sref_.ib_lookup_map_ = 0;} QMG::Brep::Brep(const Brep& other) : geo_(other.geo_), child_lookup_map_(other.child_lookup_map_), ib_lookup_map_(other.ib_lookup_map_), c_gdim_(other.c_gdim_), c_embedded_dim_(other.c_embedded_dim_), c_numpv_(other.c_numpv_), c_pvlist_(other.c_pvlist_), c_num_control_points_(other.c_num_control_points_), c_control_points_(other.c_control_points_){ for (int fdim = 0; fdim <= c_embedded_dim_; ++fdim) { c_num_top_faces_[fdim] = other.c_num_top_faces_[fdim]; c_top_faces_[fdim] = other.c_top_faces_[fdim]; }}int QMG::Brep::level_size(int d) const { if (d < 0 || d > c_gdim_) { throw_error("Dimension out of range in level size"); } return c_num_top_faces_[d];}QMG::Brep::Face_Spec_Loop_Over_Face_Subfaces::Face_Spec_Loop_Over_Face_Subfaces(const Brep& g, const Face_Spec& f) : brep_(g), child_list_((*g.child_lookup_map_)[f]), ib_list_((*g.ib_lookup_map_)[f]){ int fdim = f.fdim(); int faceind = f.faceind(); // mexPrintf("Loop over children begun for %d:%d\n", fdim, faceind);#ifdef DEBUGGING if (fdim < 0 || fdim > g.c_gdim_ || faceind < 0 || faceind >= g.c_num_top_faces_[fdim]) throw_error("Faceind out of range in loop_over_face_subfaces");#endif count_ = 0; parent_ = f; parentfdim_ = fdim; num_child_ = child_list_.size(); num_ib_ = ib_list_.size(); set_this_();}voidQMG::Brep::Face_Spec_Loop_Over_Face_Subfaces::set_this_() { // mexPrintf("Set this entry\n"); if (count_ < num_child_) { fdim_ = parentfdim_ - 1; faceind_ = child_list_[count_].faceind; orientation_ = child_list_[count_].ori; } else if (count_ < num_child_ + num_ib_) { fdim_ = ib_list_[count_ - num_child_].fdim(); faceind_ = ib_list_[count_ - num_child_].faceind(); orientation_ = 2; } else { fdim_ = -1; faceind_ = -1; } // mexPrintf("count_ = %d num_child_ = %d num_ib_ = %d Set this return %d:%d\n", // count_, num_child_, num_ib_, fdim_, faceind_);}QMG::Real QMG::Brep::PatchMath_for_Brep::control_point_coord_(int cpnum, int d) const { return controlpoints_[static_cast<int>(controlpointindices_[cpnum]) * di_ +d];}QMG::Brep::Patchinfo_QMG::Brep::get_patch_(const Face_Spec& fspec, int patchind) const { int fdim = fspec.fdim(); int faceind = fspec.faceind();#ifdef DEBUGGING if (fdim < 0 || fdim > c_gdim_ || faceind < 0 || faceind >= c_num_top_faces_[fdim]) throw_error("Faceind out of range in get_patch_");#endif const mxArray* patchlist = mxGetCell(c_top_faces_[fdim], 5 * faceind + 4); if (patchlist == 0) throw_error("Unable to retrieve patchlist from brep face"); int prow = mxGetM(patchlist); int numpatch = mxGetN(patchlist); if (numpatch > 0 && prow != 3) throw_error("Patchlist should be 3-by-k"); if (patchind < 0 || patchind >= numpatch) throw_error("Patchind out of range");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -