qsizectl.cpp

来自「算断裂的」· C++ 代码 · 共 300 行

CPP
300
字号
// ------------------------------------------------------------------// qsizectl.h//// This file contains member functions for evaluating the size// control or curvature control function of the brep.// ------------------------------------------------------------------// 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.// ------------------------------------------------------------------#include "qsizectl.h"namespace QMG {  extern istream& eatwhite(istream& is);  extern int compare_nocase(const string& s1, const string& s2);}namespace {  using namespace QMG;// ------------------------------------------------------------------// parse_const// Checks whether a size control string is of the form// "(const xxx)".  If so, it parses the string and returns// xxx.// If the size control function has some other form then// return -1.// This is an optimization for the common case.// ------------------------------------------------------------------  Real parse_const(const string& sizefun) {    istringstream ist(sizefun);    string s1;    Real sz;    char c = 0;    char c2= 0;    ist >> eatwhite >> c >> eatwhite >> s1 >> eatwhite >> sz >> eatwhite >> c2;    if (!ist || c != '(' || compare_nocase(s1,"const") || sz <= 0.0      || c2 != ')')      return -1;    ist >> s1;    if (ist && s1.length() > 0)      return -1;    return sz;  }}// ------------------------------------------------------------------// Constructor// Lookups up "size_control" properties for each face of the brep// and puts them in a table. Creates ancestor lookup.// Parses size-control properties of the form const x.//  Also calls fe_initialize in sizectl_fe.// ------------------------------------------------------------------QMG::MG::SizeControl::SizeControl(const Brep& g,                                  const PatchTable& patchtable,                                  const string& property_name,                                   const string& extern_funcname,                                  const string& default1,                                  const string& user_data,                                  FrontEnd::Interpreter& interp,                                  Logstream& logfile) :g_(g),default_size_(default1),default_const_sizefunc_(parse_const(default_size_)),user_data_(user_data),extern_funcname_(extern_funcname),lca_lookup_(g),sizefuncs_(g),const_sizefunc_(g),interp_(interp),logstr_(logfile),di_(g.embedded_dim()),patchtable_(patchtable),is_on_stack_(g,0),serial_number_(1){  if (logfile.verbosity() >= 1) {    logfile.str() << "default " << property_name << " = " << default_size_;    if (default_const_sizefunc_ > 0)       logfile.str() << "  parsed as constant value " << default_const_sizefunc_      << "\n";    else      logfile.str() << " not const value\n";  }    for (Brep::Face_Spec_Loop_Over_Faces fspec(g); fspec.notdone(); ++fspec) {     string sz_control = g.face_lookup_prop_val(fspec, property_name);    if (sz_control.size() > 0) {      sizefuncs_(fspec) = sz_control;      Real sz1 = parse_const(sz_control);      const_sizefunc_(fspec) = sz1;      if (logfile.verbosity() >= 1) {        logfile.str() << "for face " << g.face_name(fspec) << property_name << " string is "          << sz_control;        if (const_sizefunc_(fspec) > 0)          logfile.str() << " parsed as constant value "          << const_sizefunc_(fspec) << "\n";        else          logfile.str() << " not const value \n";      }    }    else {      sizefuncs_(fspec) = "";      const_sizefunc_(fspec) = -1;      if (logfile.verbosity() >= 1)        logfile.str() << "for face " << g.face_name(fspec) << " no " << property_name <<" string\n";    }  }  fe_initialize();}QMG::MG::SizeControl::~SizeControl() {  fe_terminate();}        // ------------------------------------------------------------------// eval (member function)// Figures out the the upper bound on the size at a given point, which// lies in the interior of chaber sourcespec.// If the string is const, the front end is not invoked.// Returns the size and also a bool to indicate whether all the functions// were "const".#ifndef BUG_IN_USINGusing QMG::pair;#endifpair<QMG::Real, bool>QMG::MG::SizeControl::eval(const Point& realpoint,                           const Point& parampoint,                           PatchTable::Index patchind) const {   Real size = BIG_REAL;  // use a dfs because we must loop over the patch and  // all ancestors.  bool everything_was_const = true;  dfs_stack_.resize(1);  dfs_stack_param_.resize(1, Point());  dfs_stack_[0] = patchind;  dfs_stack_param_[0] = parampoint;  int old_serial_number = serial_number_;  ++serial_number_;  // Check for overflow  if (serial_number_ <= old_serial_number) {    serial_number_ = 1;    for (Brep::Face_Spec_Loop_Over_Faces fspec(g_);    fspec.notdone();    ++fspec) {      is_on_stack_(fspec) = 0;    }  }  bool global_was_evaluated = false;  while (dfs_stack_.size() > 0) {    PatchTable::Index eval_patchind = dfs_stack_.back();    dfs_stack_.pop_back();    Point param = dfs_stack_param_.back();    dfs_stack_param_.pop_back();    Brep::Face_Spec owner;    bool ok_to_eval;    Brep::PatchIndex orig_index;    int pdim;    if (eval_patchind < 0) {      owner = Brep::Face_Spec(di_, -eval_patchind - 1);      ok_to_eval = true;      pdim = di_;    }    else {      owner = patchtable_.owner(eval_patchind);      pdim = patchtable_.gdim(eval_patchind);      ok_to_eval = owner.fdim() == pdim;      orig_index = patchtable_.orig_index(eval_patchind);    }    if (ok_to_eval && is_on_stack_(owner) < serial_number_) {      is_on_stack_(owner) = serial_number_;      const string& this_size_func = sizefuncs_(owner);      if (this_size_func.size() > 0) {        Real rqsize;        Real constsize = const_sizefunc_(owner);        if (constsize > 0)          rqsize = constsize;        else {          if (pdim < di_)            rqsize = fe_invoke_sizefunc(realpoint, param, owner, orig_index, this_size_func);          else            rqsize = fe_invoke_sizefunc_interior(realpoint, owner, this_size_func);          everything_was_const = false;        }        if (rqsize <= 0.0)          throw_error("Size function returned zero or negative value 3");        if (rqsize < size)          size = rqsize;	      }      if (!global_was_evaluated) {        Real rqsize;        if (default_const_sizefunc_ > 0)          rqsize = default_const_sizefunc_;        else {          if (pdim < di_)            rqsize = fe_invoke_sizefunc(realpoint, param, owner, orig_index, default_size_);          else            rqsize = fe_invoke_sizefunc_interior(realpoint, owner, default_size_);          everything_was_const = false;        }        if (rqsize <= 0)          throw_error("Size function returned zero or negative value 4");        if (rqsize < size)          size = rqsize;        global_was_evaluated = true;      }    }    if (eval_patchind < 0) continue;    if (pdim == di_ - 1) {      Brep::Face_Spec front = patchtable_.front_side(eval_patchind);      if (front.faceind() >= 0) {        dfs_stack_.push_back(-front.faceind() - 1);        dfs_stack_param_.push_back(Point());      }           Brep::Face_Spec back = patchtable_.back_side(eval_patchind);      if (back.faceind() >= 0) {        dfs_stack_.push_back(-back.faceind() - 1);        dfs_stack_param_.push_back(Point());      }    }    else {      for (PatchTable::Loop_over_parents parloop(patchtable_, eval_patchind);      parloop.notdone();      ++parloop) {        dfs_stack_.push_back(parloop.parent_index());        dfs_stack_param_.push_back(patchtable_.lift_parameters(param,           eval_patchind, parloop.listind()));      }    }  }  return pair<Real,bool>(size, everything_was_const);}// ------------------------------------------------------------------// eval_interior (member function)// Figures out the the upper bound on the size at a given point, which// lies in the interior of chaber sourcespec.// If the string is const, the front end is not invoked.pair<QMG::Real, bool>QMG::MG::SizeControl::eval_interior(const Point& realpoint,                                    const Brep::Face_Spec& sourcespec) const {  Real size = BIG_REAL;  Brep::Face_Spec ancestor;  bool everything_was_const = true;  const string& this_size_func = sizefuncs_(sourcespec);  if (this_size_func.size() > 0) {    Real rqsize;    Real constsize = const_sizefunc_(sourcespec);    if (constsize > 0)      rqsize = constsize;    else {      rqsize = fe_invoke_sizefunc_interior(realpoint, sourcespec, this_size_func);      everything_was_const = false;    }    if (rqsize <= 0.0)      throw_error("Size function returned zero or negative value 3");    if (rqsize < size)      size = rqsize;  }  Real rqsize1;  if (default_const_sizefunc_ > 0)    rqsize1 = default_const_sizefunc_;  else {    rqsize1 = fe_invoke_sizefunc_interior(realpoint, Brep::Face_Spec(-1,-1), default_size_);    everything_was_const = false;  }  if (rqsize1 <= 0)    throw_error("Size function returned zero or negative value 4");  if (rqsize1 < size)    size = rqsize1;  return pair<Real,bool>(size, everything_was_const);}

⌨️ 快捷键说明

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