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 + -
显示快捷键?