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