📄 gm_vizp.cpp
字号:
// ------------------------------------------------------------------// gm_vizp.cpp//// This file contains the driver function and worker function for // for gmvizp, a routine for processing a brep or simplicial// complex and extracting points, edges or triangles for graphics.// ------------------------------------------------------------------// 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.// ------------------------------------------------------------------#ifdef _MSC_VER#if _MSC_VER == 1200#include "qmatvec.h"#endif#endif#include "qbrep.h"#include "qsimpcomp.h"#include "qmatvec.h"#include "qfrontend.h"namespace QMG { extern istream& eatwhite(istream&);} namespace { using namespace QMG; const int MAXDIM = 3; // ------------------------------------------------------------------ // SimpKey: a data structure for keeping track of which simplices // have already been generated so that we don't do them twice, since // rendering may be slow. struct SimpKey { static int dim; SimpComplex::VertexOrdinalIndex verts[MAXDIM + 1]; bool operator<(const SimpKey&) const; bool operator==(const SimpKey&) const; void sort(); }; int SimpKey::dim; bool SimpKey::operator<(const SimpKey& o) const { for (int j = 0; j < dim + 1; ++j) { if (verts[j] < o.verts[j]) return true; if (verts[j] > o.verts[j]) return false; } return false; } bool SimpKey::operator==(const SimpKey& o) const { for (int j = 0; j < dim + 1; ++j) { if (verts[j] != o.verts[j]) return false; } return true; } void SimpKey::sort() { for (int m = dim; m >= 1; --m) { for (int k = 0; k < m; ++k) { if (verts[k] > verts[k+1]) { SimpComplex::VertexOrdinalIndex tmp = verts[k]; verts[k] = verts[k+1]; verts[k+1] = tmp; } } } } struct Vizp_data { Matrix coords; IntMatrix simps; Matrix colors; Vizp_data(Matrix& coor1, IntMatrix& si1, Matrix& col1) : coords(coor1), simps(si1), colors(col1) { } // Destructive copy semantics. private: class Vizp_data_returnval { private: friend struct Vizp_data; Vizp_data& dref_; Vizp_data_returnval(Vizp_data& v, int) : dref_(v) { } }; public: Vizp_data(Vizp_data& o) : coords(o.coords), simps(o.simps), colors(o.colors) { } Vizp_data(const Vizp_data_returnval& x) : coords(x.dref_.coords), simps(x.dref_.simps), colors(x.dref_.colors) { } operator Vizp_data_returnval() { return Vizp_data_returnval(*this, 0); } }; // ------------------------------------------------------------------ // This routine extracts coordinates and simplices from a simplicial // complex. Vizp_data get_pts_simps(const SimpComplex& sc, const vector<Real>& default_color, int dim) { int di = sc.embedded_dim(); Point::init_static_data(di); int gdim = sc.gdim(); if (dim > gdim || dim < 0) throw_error("dim argument out of range in get_pts_simps"); if (default_color.size() != 4) throw_error("Wrong color length in get_pts_simps"); int numnodes = sc.num_nodes(); int numelem = sc.num_elements(); // Get the nodes Matrix vc(numnodes, di); for (SimpComplex::VertexOrdinalIndex vnum_o = 0; vnum_o < numnodes; ++vnum_o) { for (int i = 0; i < di; ++i) vc(vnum_o, i) = sc.real_coord_o(vnum_o,i); } // Get the simplices. Loop over subsets of indices with // exactly the right number of entries. vector<int> selected_verts; map<SimpKey, int> faces_drawn; SimpKey key; SimpKey::dim = dim; vector<SimpComplex::VertexOrdinalIndex> outputsimps; for (unsigned int subsetmask = 0; subsetmask < (1 << (gdim + 1)); ++subsetmask) { selected_verts.resize(0); for (int j = 0; j < gdim + 1; ++j) { if (subsetmask & (1<<j)) selected_verts.push_back(j); } int slvs = selected_verts.size(); if (slvs != dim + 1) continue; // Get all the subfaces with the selected vertices. int levsize = sc.brep_levelsize(gdim); for (Brep::FaceIndex faceind = 0; faceind < levsize; ++faceind) { Brep::Face_Spec fspec(gdim, faceind); int nmf = sc.num_meshface_on_face(fspec); for (int seqno = 0; seqno < nmf; ++seqno) { for (int l = 0; l < dim + 1; ++l) { SimpComplex::VertexGlobalIndex vnum = sc.node_of_meshface_on_face(fspec, seqno, selected_verts[l]); key.verts[l] = sc.global_to_ordinal(vnum); } key.sort(); if (faces_drawn[key] == 0) { faces_drawn[key] = 1; for (int l1 = 0; l1 < dim + 1; ++l1) { outputsimps.push_back(key.verts[l1]); } } } } } int outputcount = outputsimps.size() / (dim + 1); IntMatrix faces(outputcount, dim + 1); Matrix colors(outputcount, 4); int pos = 0; for (int ocount = 0; ocount < outputcount; ++ocount) { for (int l = 0; l < dim + 1; ++l) { faces(ocount, l) = outputsimps[pos++]; } for (int cc = 0; cc < 4; ++cc) { colors(ocount, cc) = default_color[cc]; } } return Vizp_data(vc, faces, colors); } struct Colorspec { Real co[4]; }; // ------------------------------------------------------------------ // This routine is for parsing the "color" property of a brep face. // The corresponding value should be a four-tuple of reals (r g b alpha) Colorspec parse_color_propval(const Brep& g, const Brep::Face_Spec& fspec) { Colorspec returnval; string colorstring = g.face_lookup_prop_val(fspec, "color"); if (colorstring.length() == 0) { returnval.co[0] = -1; return returnval; } istringstream ist(colorstring); char c = 0; char c2 = 0; ist >> eatwhite >> c >> eatwhite >> returnval.co[0] >> eatwhite >> returnval.co[1] >> eatwhite >> returnval.co[2] >> eatwhite >> returnval.co[3] >> eatwhite >> c2; if (!ist || c != '(' || c2 != ')') { ostringstream os; os << "Value associated with \"color\" property of face " << g.face_name(fspec) << " incorrectly formatted.\n" << "Should be (r g b alpha) where r,g,b,alpha are real numbers"; throw_error(os.str()); } return returnval; } // ------------------------------------------------------------------ // This routine is for extracting simplices from a simplicial complex // in which we look up the color specs in the corresponding brep. Vizp_data get_pts_simps(const SimpComplex& sc, const Brep& g, const vector<Real>& default_color, int dim) { int di = sc.embedded_dim(); Point::init_static_data(di); int gdim = sc.gdim(); if (dim > gdim || dim < 0) throw_error("dim argument out of range in get_pts_simps"); if (gdim > g.gdim() || di != g.embedded_dim()) throw_error("mesh dimension does not match brep dimension"); if (compare_nocase(g.lookup_brep_propval(Brep::global_id_propname()), sc.lookup_prop_val(Brep::global_id_propname())) != 0) throw_error("mesh's brep id does not match brep's id"); if (default_color.size() != 4) throw_error("Wrong color length in get_pts_simps"); int numnodes = sc.num_nodes(); int numelem = sc.num_elements(); // Make a table holding all the colors map<Brep::Face_Spec, Colorspec> colortable; for (Brep::Face_Spec_Loop_Over_Faces fspec(g); fspec.notdone(); ++fspec) { Colorspec facecolor = parse_color_propval(g,fspec); if (facecolor.co[0] < 0) { for (int j = 0; j < 4; ++j) facecolor.co[j] = default_color[j]; } colortable[fspec] = facecolor; } SimpKey::dim = dim; // Get the nodes Matrix vc(numnodes, di); for (SimpComplex::VertexOrdinalIndex vnumo = 0; vnumo < numnodes; ++vnumo) { for (int i = 0; i < di; ++i) vc(vnumo, i) = sc.real_coord_o(vnumo,i); } // Get the simplices. Loop over subsets of indices with // exactly the right number of entries. vector<int> selected_verts; map<SimpKey, int> faces_drawn; SimpKey key; vector<SimpComplex::VertexOrdinalIndex> outputsimps; vector<Colorspec> colors; for (int fdim = 0; fdim <= gdim; ++fdim) { int levsize = g.level_size(fdim); if (levsize != sc.brep_levelsize(fdim)) throw_error("Mismatch in brep and sc level sizes");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -