qpatchtab.h
来自「算断裂的」· C头文件 代码 · 共 389 行
H
389 行
// ------------------------------------------------------------------// qpatchtab.h//// This file contains the class holding the patchtable during// mesh generation.// ------------------------------------------------------------------// 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.// ------------------------------------------------------------------#ifndef QMGPATCHTAB_H#define QMGPATCHTAB_H#include "qmgnamesp.h"#include "qbrep.h"#include "qsmall.h"#include "qlog.h"#include "qpatchmath.h"// ------------------------------------------------------------------// This is a singleton class holding the patches that make up// the Brep.class QMG::MG::PatchTable {public: typedef int Index;private: struct PatchParentInfo { Index parentnum; int lift_index[MAXDIM - 1]; }; struct PatchChildInfo { Index childnum; int lift_index[MAXDIM - 1]; }; struct PatchInfo { Brep::Face_Spec owner; Brep::FaceIndex front_side; Brep::FaceIndex back_side; PatchType ptype; Brep::PatchIndex orig_index; // Real normal_deriv_estimate; int control_point_start; int child_start; int num_parents; int parent_start; unsigned int num_children : 4; unsigned int gdim : 3; unsigned int degree1 : 10; unsigned int degree2 : 10; bool is_forward : 1; bool is_root : 1; int num_ctl_pts() const; }; class PatchMath_for_PatchTable; friend class PatchMath_for_PatchTable; // This is a wrapper around PatchMath so that we // can do math on patches in the patch table. class PatchMath_for_PatchTable : public QMG::PatchMath { private: const PatchTable& patchtab_; Index patchind_; int cpstart_; Real control_point_coord_(int cprel, int d) const { Brep::ControlPointIndex cpi = patchtab_.control_point_list_[cpstart_ + cprel]; return patchtab_.brep_.control_point(cpi, d); } public: PatchMath_for_PatchTable(const PatchTable& patchtab, Index patchind) : PatchMath(patchtab.patches_[patchind].ptype, patchtab.patches_[patchind].degree1, patchtab.patches_[patchind].degree2, patchtab.patches_[patchind].gdim, patchtab.di_, patchtab.patches_[patchind].is_forward), patchtab_(patchtab), patchind_(patchind), cpstart_(patchtab.patches_[patchind].control_point_start) {#ifdef RANGECHECK if (patchind_ < 0 || patchind >= patchtab.patches_.size()) throw_error("Patchind out of range in patchmath_for_patchtable");#endif } ~PatchMath_for_PatchTable() { } }; const Brep& brep_; // needed to lookup control points. vector<PatchInfo> patches_; vector<Brep::ControlPointIndex> control_point_list_; vector<PatchChildInfo> childlists_; vector<PatchParentInfo> parentlists_; int di_; friend class IncidenceTable; class Constructor_Helper; friend class Constructor_Helper;public: void dump_patch(Index i, ostream& str) const; class Loop_over_children; friend class Loop_over_children; class Loop_over_parents; friend class Loop_over_parents; int embedded_dim() const { return di_; } Brep::Face_Spec front_side(Index patchind) const {#ifdef DEBUGGING if (!patches_[patchind].is_root) { throw_error("front_side called for nonroot patch"); }#endif return Brep::Face_Spec(di_, patches_[patchind].front_side); } Brep::Face_Spec back_side(Index patchind) const {#ifdef DEBUGGING if (!patches_[patchind].is_root) { throw_error("back_side called for nonroot patch"); }#endif return Brep::Face_Spec(di_, patches_[patchind].back_side); } int gdim(Index patchind) const { return patches_[patchind].gdim; } PatchType ptype(Index patchind) const { return patches_[patchind].ptype; } bool is_root(Index patchind) const { return patches_[patchind].is_root; } bool is_forward(Index patchind) const { return patches_[patchind].is_forward; } /* Real normal_deriv_est(Index patchind) const { return patches_[patchind].normal_deriv_estimate; } Real& normal_deriv_est_nonconst(Index patchind) { return patches_[patchind].normal_deriv_estimate; } */ // This routine maps the patch index to the patch's // original index in the input brep. Brep::PatchIndex orig_index(Index patchind) const { return patches_[patchind].orig_index; } int numpatch() const { return patches_.size(); } // Project vec from 3d to 2d using a hh transform. static void apply_3d_hh_and_shift(Real beta, const Point& hhtransform, Point& vec); // This routine takes a point on a patch, and finds // the tangent in the parent parent face outward // from the given point. Point get_outward_tan_in_parent(const Point& paramcoord, Index patchind, Loop_over_parents& loop_in_progress) const; // This complicated routine determines for a ray coming out of the // patch what chamber contains the ray. // member function vtxnbd_patchcone_bdry_tans_ // takes a 2D patch containing a 0D patch, and // computes the tangents to the two boundary // edges at the point. private: Triple<Point,Point,Point> vtxnbd_patchcone_bdry_tans_(Index patchind, Index grandparent_index) const;public: Point vtxnbd_select_patchcone_randpoint(Index patchind, Index ancestor_index) const; enum ConeIntersectCode {HITS_PATCH_FRONT, HITS_PATCH_BACK, HITS_EDGE, MISSES_PATCH, DEGEN}; pair<ConeIntersectCode, Real> vtxnbd_patchcone_meets_seg(Index patchind, Index grandparent_index, const Point& endpoint1, const Point& endpoint2, const Point& segtan, double degen_cutoff) const; pair<Index, ConeIntersectCode> determine_ray_front_face(Index patchind, const Point& param_coord, const Point& ray_direction, double tol) const; const Brep::Face_Spec& owner(Index ind) const {return patches_[ind].owner;} int num_control_points(Index ind) const { return patches_[ind].num_ctl_pts(); } PatchMath_for_PatchTable patchmath(Index ind) const { return PatchMath_for_PatchTable(*this, ind); } // Two separate routines for lifting parametric coordinatesfrom // a child patch to a parent patch. In the first one, we are // given the child patch index and the list index of which parent. // In the second version we are given the parent patch index // and the list index of which child. Point lift_parameters(const Point& lowdim_param, Index childind, int listind) const; Point lift_parameters_from_childloop(const Point& lowdim_param, Index parentind, int listind) const; bool is_ancestor(Index child, Index ancestor) const; static Real ang_distance(const Point& vec1, const Point& vec2) { return Point::l2dist(vec1, vec2); } PatchTable(const Brep& brep, Logstream& logstr, double scfac, double tol); ~PatchTable() { }private: // No copying, no assignment PatchTable(const PatchTable& p): brep_(p.brep_) { } void operator=(const PatchTable&) { }};// Class for looping over the child patches of a patch.class QMG::MG::PatchTable::Loop_over_children {private: const PatchTable& patchtab_; Index patchind_; int base_; int nc_; int it_;public: Loop_over_children(const PatchTable& patchtab, Index patchind) : patchtab_(patchtab), patchind_(patchind), base_(patchtab_.patches_[patchind].child_start), nc_(patchtab_.patches_[patchind].num_children), it_(0) { } ~Loop_over_children() { } Index child_index() const {return patchtab_.childlists_[base_ + it_].childnum;} int lift_index(int j) {return patchtab_.childlists_[base_ + it_].lift_index[j];} int listind() const {return it_;} void operator++() {++it_;} bool notdone() const {return it_ < nc_;}};// class for looping over the parent patches of a patch.class QMG::MG::PatchTable::Loop_over_parents {private: const PatchTable& patchtab_; Index patchind_; int base_; int np_; int it_;public: Loop_over_parents(const PatchTable& patchtab, Index patchind) : patchtab_(patchtab), patchind_(patchind), base_(patchtab_.patches_[patchind].parent_start), np_(patchtab_.patches_[patchind].num_parents), it_(0) { } ~Loop_over_parents() { } Index parent_index() const {return patchtab_.parentlists_[base_ + it_].parentnum;} int listind() const {return it_;} int lift_index(int j) {return patchtab_.parentlists_[base_ + it_].lift_index[j];} void operator++() {++it_;} bool notdone() const {return it_ < np_;}};// This struct holds the index (fspec,patchindpair) for looking// up a specific patch within a brep. Used as a map key.struct QMG::MG::PatchInBrepAddress { Brep::Face_Spec fspec; Brep::PatchIndex patchind; PatchInBrepAddress(const Brep::Face_Spec& f, Brep::PatchIndex p) : fspec(f), patchind(p) { } PatchInBrepAddress(const PatchInBrepAddress& o) : fspec(o.fspec), patchind(o.patchind) { } PatchInBrepAddress() { } bool operator<(const PatchInBrepAddress& ip) const; bool operator==(const PatchInBrepAddress& ip) const;};#ifdef TEMPLATE_IN_NAMESPACEnamespace QMG { namespace MG { using namespace QMG; template<class T> class PatchTableIndexMap {#else template<class T> class QMG::MG::PatchTableIndexMap {#endif private: vector<T> data_; vector<unsigned int> lastseqno_; unsigned int seqno_; T default_; PatchTableIndexMap(const PatchTableIndexMap<T>&) { } void operator=(const PatchTableIndexMap<T>&) { } public: PatchTableIndexMap(const PatchTable& pt, const T& init) : data_(pt.numpatch(),init), lastseqno_(pt.numpatch(), static_cast<unsigned int>(0)), seqno_(1), default_(init) { } ~PatchTableIndexMap() { } void reset(const T& init) { default_ = init; unsigned int oldseqno = seqno_; ++seqno_; // check for overflow; special case if overflow. if (seqno_ <= oldseqno) { seqno_ = 1; int sz = data_.size(); for (PatchTable::Index i = 0; i < sz; ++i) { lastseqno_[i] = static_cast<unsigned int>(0); } } } const T& operator[](PatchTable::Index i) const { if (lastseqno_[i] < seqno_) return default_; else return data_[i]; } T& operator[](PatchTable::Index i) { if (lastseqno_[i] < seqno_) { lastseqno_[i] = seqno_; data_[i] = default_; } return data_[i]; }#ifdef TEMPLATE_IN_NAMESPACE }; }}#else};#endif#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?