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