qinctab.cpp

来自「算断裂的」· C++ 代码 · 共 559 行 · 第 1/2 页

CPP
559
字号
// ------------------------------------------------------------------// qinctab.cpp//// This file contains member functions for IncidenceTable.// ------------------------------------------------------------------// 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 "qinctab.h"#include "qmatvec.h"#include "qmg_gui.h"#include <cstddef>#ifdef DEBUGGINGnamespace {  int get_incidence_invocation_count;}#endif// ------------------------------------------------------------------// PatchMath_for_curve_on_triangle// This routine allows us to treat a curve that sits on a patch as// a separate Bezier curve.  The patch is described by two parameters// alpha and beta which are the slopes of the curve.class QMG::MG::IncidenceTable::PatchMath_for_curve_on_triangle : public QMG::PatchMath {private:  const PatchTable& patchtab_;  PatchTable::Index patchind_;  Real alpha_,beta_;  int deg_;  Real control_point_coord_(int cpnum, int d) const;public:  PatchMath_for_curve_on_triangle(const PatchTable& patchtab,    PatchTable::Index patchind,    Real alpha,    Real beta) :  PatchMath(BEZIER_TRIANGLE, IncidenceTable::get_patch_degree1_(patchtab, patchind),     0, 1, 3, true),    patchtab_(patchtab),    patchind_(patchind),    alpha_(alpha),    beta_(beta),    deg_(IncidenceTable::get_patch_degree1_(patchtab,patchind))  { }  ~PatchMath_for_curve_on_triangle() { }};// ------------------------------------------------------------------// The control point coordinates of the curve are interpolated// from the patch's control points.        QMG::Real QMG::MG::IncidenceTable::PatchMath_for_curve_on_triangle::control_point_coord_(int cpnum, int d) const {  // Should use decasteljau here, but no obvious way to allocate workspace  Real coef = 1.0;  for (int jj = 0; jj < cpnum; ++jj)    coef *= beta_;  Real t = 0.0;  int liftcp = (deg_ - cpnum) * (deg_ - cpnum + 1) / 2;  int incliftcp = deg_ - cpnum + 2;  for (int j = 0; j <= cpnum; ++j) {    t += IncidenceTable::get_patch_control_point_coord_(patchtab_, patchind_, liftcp, d)       * coef;    coef *= alpha_ / beta_ * (cpnum - j) / (j + 1);    liftcp += incliftcp;    ++incliftcp;  }  return t;}// ------------------------------------------------------------------// PatchMath_for_curve_on_quad// This routine allows us to treat a curve that sits on a quad patch as// a separate Bezier curve.  The curve has a fixed v and varying u.// The fixed value of v is parameter beta.class QMG::MG::IncidenceTable::PatchMath_for_curve_on_quad : public QMG::PatchMath {private:  const PatchTable& patchtab_;  PatchTable::Index patchind_;  Real beta_;  int deg1_, deg2_;  Real control_point_coord_(int cpnum, int d) const;public:  PatchMath_for_curve_on_quad(const PatchTable& patchtab,    PatchTable::Index patchind,    Real beta) :  PatchMath(BEZIER_TRIANGLE, IncidenceTable::get_patch_degree1_(patchtab, patchind),     0, 1, 3, true),    patchtab_(patchtab),    patchind_(patchind),    beta_(beta),    deg1_(IncidenceTable::get_patch_degree1_(patchtab,patchind)),        deg2_(IncidenceTable::get_patch_degree2_(patchtab,patchind))  { }  ~PatchMath_for_curve_on_quad() { }};    // The control points of the curve are interpolated from// control points of the patch.    QMG::Real QMG::MG::IncidenceTable::PatchMath_for_curve_on_quad::control_point_coord_(int cpnum, int d) const {  // Should use decasteljau here, but no obvious way to allocate workspace  Real coef = 1.0;  for (int jj = 0; jj < deg2_; ++jj)    coef *= (1 - beta_);  Real t = 0.0;  int liftcp = cpnum;  for (int j = 0; j <= deg2_; ++j) {    t += IncidenceTable::get_patch_control_point_coord_(patchtab_, patchind_, liftcp, d)      * coef;    coef *= beta_ / (1 - beta_) * (deg2_ - j) / (j + 1);    liftcp += deg1_ + 1;  }  return t;}// Functions to expose otherwise hidden patchtable fields.intQMG::MG::IncidenceTable::get_patch_degree1_(const PatchTable& patchtable,                                           PatchTable::Index patchind) {  return patchtable.patches_[patchind].degree1;}intQMG::MG::IncidenceTable::get_patch_degree2_(const PatchTable& patchtable,                                           PatchTable::Index patchind) {  return patchtable.patches_[patchind].degree2;}QMG::PatchTypeQMG::MG::IncidenceTable::get_patch_type_(const PatchTable& patchtable,                                           PatchTable::Index patchind) {  return patchtable.patches_[patchind].ptype;}QMG::Real QMG::MG::IncidenceTable::get_patch_control_point_coord_(const PatchTable& patchtable,                                                    PatchTable::Index patchind,                                                    int cpnum,                                                    int d)  {  int cpstart = patchtable.patches_[patchind].control_point_start;  Brep::ControlPointIndex cpi = patchtable.control_point_list_[cpstart + cpnum];  return patchtable.brep_.control_point(cpi, d);}bool QMG::MG::IncidenceTable::Key::operator<(const Key& other) const {  if (patchind < other.patchind)    return true;  if (patchind > other.patchind)    return false;  if ((UInt32) flatdim < (UInt32) other.flatdim)    return true;  if ((UInt32) flatdim > (UInt32) other.flatdim)    return false;  int sgndif = IntCoord::compare(intcoord, other.intcoord);  if (sgndif < 0)    return true;  if (sgndif > 0)    return false;  if (seqno < other.seqno)    return true;  return false;}int QMG::MG::IncidenceTable::compare_index(const Index& i1, const Index& i2) {  return (i1 -> first.seqno) - (i2 -> first.seqno);}QMG::MG::IncidenceTable::IncidenceTable() : sequence_number_(0) {#ifdef DEBUGGING  get_incidence_invocation_count = 0;#endif}// This the main routine for IncidenceTable: it computes// the incidence (intersection) between a box entity// and a brep entity.  The box entity is described by// flatdim and midpoint coord, and midpointcoord_real// is midpoint_coord converted to real coordinates.// The box entity is patchind.// The result is placed in output_vec.void     QMG::MG::IncidenceTable::get_incidence(Mask flatdim,                                        const IntCoord& midpointcoord,                                        const Point& midpointcoord_real,                                       const PatchTable& patchtable,                                       PatchTable::Index patchind,                                       vector<Index>& output_vec, // output variable                                       Logstream& logstr,                                        double scfac,                                       double tol,                                       PatchMath::Workspace& workspace,                                       vector<PatchMath::IntersectRecord>& os_workspace,                                       Meshgen_gui& gui) {#ifdef DEBUGGING  ++get_incidence_invocation_count;  int invoc_count = get_incidence_invocation_count;#endif  int di = patchtable.embedded_dim();  int patchdim = patchtable.patches_[patchind].gdim;  int affinedim = flatdim.dim();  const int GUI_UPDATE_FREQUENCY = 20;  // If the dimension is too low, no intersection.  if (affinedim + patchdim < di)    return;  // Look up the incidence; see if already computed.  Key key;  key.intcoord = midpointcoord;  key.flatdim = flatdim;  key.patchind = patchind;  key.seqno = 0;  for (int j = 0; j < di; ++j) {    if (!key.flatdim[j]) {      key.intcoord[j] = 0;    }  }  typedef map<Key,Data> TTTYPE;  typedef TTTYPE::iterator TTTYPE_IT;  Index rangestart = table_.lower_bound(key);  key.seqno = sequence_number_;  Index rangeend = table_.upper_bound(key);  if (rangestart != rangeend) {    // Check if the first record indicates "no intersection."    if (rangestart -> second.param_coord[0] == code_for_no_intersection())       return;    // Otherwise return all the incidence records.    for (Index i1 = rangestart; i1 != rangeend; ++i1) {      output_vec.push_back(i1);    }    return;  }

⌨️ 快捷键说明

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