qboxstack.h

来自「算断裂的」· C头文件 代码 · 共 750 行 · 第 1/2 页

H
750
字号
// ------------------------------------------------------------------// qboxstack.h//// This file contains a classes for boxes in the mesh generator.// ------------------------------------------------------------------// 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 QMGBOXSTACK_H#define QMGBOXSTACK_H#include "qmgnamesp.h"#include "qsmall.h"#include "qpatchtab.h"#include "qinctab.h"#include "qbfdag.h"#include "qunionfind.h"// ------------------------------------------------------------------// class BoxAddress// A box address is a binary address of the lower left// corner plus a mask indicating in which dimensions// the box is flat.class QMG::MG::BoxAddress {// Default copy, assign, destructor, constructor are all OK.private:  IntCoord lowerleft_;  Mask flatdim_;  static Point global_coordinate_origin_;  static Real multiplier_;  static int di_;public:  UInt32 lowerleft(int i) const {return lowerleft_[i];}  const IntCoord& lowerleft() const { return lowerleft_; }  IntCoord& lowerleft() { return lowerleft_;}  Mask flatdim() const {    return flatdim_;  }  Mask& flatdim() {    return flatdim_;  }  bool flatdim(int i) const {    return flatdim_[i];  }  int dim() const {return flatdim_.dim();}  Point real_lowerleft() const;  static Real multiplier() {return multiplier_;}  static Real global_coordinate_origin(int i) {return global_coordinate_origin_[i];}  static void init_static_data(int di) { di_ = di;}  static void init_global_box_coords(Point origin, Real mult) {    global_coordinate_origin_ = origin;    multiplier_ = mult;  }};// ------------------------------------------------------------------// class ActiveBoxVec// This is a vector of active boxes.  Their data is actually spread// over several real vectors, with indexes linking the data together.class QMG::MG::ActiveBoxVec {public:  // These classes defined below.  class Create_Subbox_Workspace;  class RayHitRecord;  class Loop_over_boxes;  class Loop_over_boxes_nonconst;  friend class Patch_in_ActiveBox;  friend class ActiveBox;  friend class NonConstActiveBox;  friend class Loop_over_boxes;  friend class Loop_over_boxes_nonconst;  typedef int Index;private:  // Patch_Data is the data on one patch in a box.  This data  // is the patch index in the patchtable, number of incidences,  // and vector position of the first incidence.  struct Patch_Data {    PatchTable::Index patchnum;    int inc_begin;    int num_inc;  };  // Box_Data is the data one box, including its address, where its  // patches begin in the patch vector, how many patches it has,  // its linkage in the dag (link_parent, link_parent_side, link_parent_dim),  // whether it is completely interior, whether the size_function is  // verified, whether the curvature function is verified, whether  // the box has been killed, and whether it has a close face.  struct Box_Data {    BoxAddress bxa;    int patchvec_begin;    int num_patch;    BoxFaceDag::Index link_parent;    int weights_begin;    unsigned int link_parent_side : 2;    unsigned int link_parent_dim : 3;    bool box_completely_interior : 1;    bool size_function_verified : 1;    bool curvature_verified : 1;    bool killed: 1;    bool has_close_face : 1;    unsigned int is_front_surface : 2;  };  static int di_;  // no copying, no assignment  ActiveBoxVec(const ActiveBoxVec&) { }  void operator=(const ActiveBoxVec&) { }  // Here's the data of the class   int iwidth_;  vector<IncidenceTable::Index> incidencevec_;  vector<Patch_Data> patchvec_;  vector<Weight_t> weights_;  vector<Box_Data> boxvec_;  int num_killed_;  Real expa_;public:  int iwidth() const {return iwidth_;}  int numboxes() const {return boxvec_.size() - num_killed_;}private:    // Member functions to create boxes.  These are in crtsubbox.cpp  // rather than qboxstack.cpp.  // deletes last box that was added to a vector.    void delete_last_box_();  // Get the last box added.  ActiveBox get_last_box_() const;  int create_new_subbox_(const ActiveBox_As_Parent& b,    const BoxAddress& bxa,    int bwidth,    BoxFaceDag::Index parentind,    int facetval,    int facetdim,    const PatchTableIndexMap<int>& componum,    int current_componum,    Create_Subbox_Workspace& wkspa);  // Postprocess a box: set weights; call specialized postprocessing  // in parent.    void post_process_box_(const ActiveBox_As_Parent& b,    const ActiveBox& newb,    int lowest_patch_dim,    Logstream& logstr);public:  // These next two functions add a box to an activeboxvec  // They are static because, for the first one, the destination stack is not  // determined until the box is processed.  // Create a subbox of b at address bxa and width bwidth.  Argument  // cutoffdim controls the disposition of the box; if it meets top. faces  // of dimension cutoffdim or lower, then place it in low_dim_dest   // else place it in high_dim_dest.  static void create_subbox(const ActiveBox_As_Parent& b,    const BoxAddress& bxa,    int bwidth,    int cutoffdim,    BoxFaceDag::Index parentind,    int facetval,    int facetdim,    ActiveBoxVec& low_dim_dest,    ActiveBoxVec& high_dim_dest,    Create_Subbox_Workspace& wkspa);  // Adds a new box that is completely interior.  No reason  // to make this static except for consistency with the  // predecessor.    static void create_subbox_completely_interior(const ActiveBox_As_Parent& b,    const BoxAddress& bxa,    int bwidth,    ActiveBoxVec& destvec,    BoxFaceDag::Index parentind,    int facetval,    int facetdim,    Logstream& logstr);  // push a box onto a stack and shrink its expanded neighborhood.  void push_box_shrink_ex(const ActiveBox& b,    Create_Subbox_Workspace& wkspa);    // Push a completely interior box on the stack.  void push_box_completely_interior(const ActiveBox& b,    Logstream& logstr);  // Split a box that's not completely interior.  Make it static  // because we don't know the dest. vector a priori.  // The next two member functions are in split1.cpp.  // Note that we pass the incidence table explicitly even  // though it is in wkspa because this routine needs nonconst  // incidence table (because the table gets updated with  // new incidences).  static void split_box_and_push_children(int cutoffdim,    ActiveBoxVec& tempvec,    ActiveBoxVec& smallboxvec,    ActiveBoxVec& idlevec,    const ActiveBox& b,    IncidenceTable& inc_table,    Create_Subbox_Workspace& wkspa);  // Split a completely interior box.  static void split_completely_interior_box_and_push_children(const ActiveBox& b,     ActiveBoxVec& smallboxvec,    Logstream& logstr);  // These functions aredefined in this file once ActiveBox is defined.  inline ActiveBox getbox(Index i) const;  inline NonConstActiveBox getbox_nonconst(Index i);   inline Index endindex() const {return boxvec_.size();}  void killbox(Index i, Logstream& logstr);  bool iskilled(Index i) const {    return boxvec_[i].killed;  }  Real expa() const { return expa_;}  void reset_expa(Real val) { expa_ = val;}  ActiveBoxVec(Real expa, int w) : iwidth_(w), incidencevec_(0), patchvec_(0),  weights_(0), boxvec_(0), num_killed_(0), expa_(expa) { }  // Push the top box -- starts mesh generation.    void push_top_box(const Brep& g,    IncidenceTable& inc_table,    Create_Subbox_Workspace& wkspa);  static int embedded_dim() {return di_;}  static void init_static_data(int di) {di_ = di;}  void dump(ostream& str) const;  void debug(const PatchTable& patchtable,    const IncidenceTable& inc_table,    const BoxFaceDag& dag) const;  ~ActiveBoxVec();};// This class intersections between a ray and patches of a box.// Should be private, except it has to be exposed for the// unnamed-namespace functions in crtsubbox.cpp.class QMG::MG::ActiveBoxVec::RayHitRecord {public:  int relnum;  Brep::Face_Spec front_hit;  Brep::Face_Spec back_hit;  Real dist;  bool is_front;  bool operator<(const RayHitRecord& o) const;};// This class holds all the auxiliary data and workspaces// needed for creating subboxes.  We use this so that we// don't need huge argument lists.class QMG::MG::ActiveBoxVec::Create_Subbox_Workspace {public:    // Workspaces:    PatchTableIndexMap<int> map_to_relnum;  UnionFind uf;  vector<RayHitRecord> hitlist;  PatchMath::Workspace rworkspace;  vector<PatchMath::IntersectRecord> output_stack;  vector<My_bool> ray_shot_from_label;  PatchTableIndexMap<My_bool> patch_was_included;  PatchTableIndexMap<int> patchcomponum;  vector<int> lowest_patchdim_of_component;  ActiveBoxVec tmp_boxvec;  map<Brep::Face_Spec, int> example_patchrelnum;      // Auxiliary data.    const IncidenceTable& inc_table;  const PatchTable& patchtable;  double scfac;  double tol;  Logstream& logstr;  Meshgen_gui& gui;    Create_Subbox_Workspace(const PatchTable& pt,    const IncidenceTable& it,    Logstream& ls,    Meshgen_gui& gu,    double scfac1,    double tol1) : map_to_relnum(pt,0), patch_was_included(pt,My_bool(false)),    patchcomponum(pt,0), tmp_boxvec(0,0), inc_table(it), patchtable(pt), logstr(ls), gui(gu),    scfac(scfac1), tol(tol1) { }    // No copying, no assignment.  Copying prevented because activeboxvec  // has private copy constructor.private:  void operator=(const Create_Subbox_Workspace&) { }};// Patch_in_ActiveBox is an ActiveBoxVec and// an index of the position in the vector.// The actual patch data must be looked up.class QMG::MG::Patch_in_ActiveBox {private:  const ActiveBoxVec& owner_;  int idx_;public:  Patch_in_ActiveBox(const ActiveBoxVec& abv, int idx) : owner_(abv), idx_(idx) { }  ~Patch_in_ActiveBox() { }  Patch_in_ActiveBox(const Patch_in_ActiveBox& pia) :   owner_(pia.owner_), idx_(pia.idx_) { }  inline PatchTable::Index patchind() const {    return owner_.patchvec_[idx_].patchnum;  }  inline int num_incidence() const {    return owner_.patchvec_[idx_].num_inc;  }  inline IncidenceTable::Index incidence(int i) const {#ifdef RANGECHECK    if (i < 0 || i >= owner_.patchvec_[idx_].num_inc) {      throw_error("Arg out of range for incidence()");    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?