qseparation.cpp
来自「算断裂的」· C++ 代码 · 共 844 行 · 第 1/2 页
CPP
844 行
} // Loop over patches and evaluate the curve-control function // to set the rqvariance_ field. { Point incpoint_real; Point incpoint_par; for (int relnum = 0; relnum < b.num_patch(); ++relnum) { Patch_in_ActiveBox patch = b.patch(relnum); PatchTable::Index patchind = patch.patchind(); Brep::Face_Spec owner = patchtable_.owner(patchind); if (owner.fdim() == 0) continue; int numinc = patch.num_incidence(); for (int ii = 0; ii < numinc; ii++) { IncidenceTable::Index inc = patch.incidence(ii); incpoint_real = inc_table_.real_coord(inc); incpoint_par = inc_table_.param_coord(inc); pair<Real,bool> rval = curve_control_.eval(incpoint_real, incpoint_par, patchind); Real rqvariance1 = rval.first; if (rqvariance_(owner) > rqvariance1) rqvariance_(owner) = rqvariance1; if (logstr_.verbosity() >= 10) { logstr_.str() << " rqvariance(" << owner << ") = " << rqvariance_(owner) << '\n'; } } } } // Initialize the track_max_min map. { int old_serial_num = serial_num_; ++serial_num_; // check for overflow in serial_num_ if (serial_num_ <= old_serial_num) { serial_num_ = 1; for (Brep::Face_Spec_Loop_Over_Faces fspec(brep_); fspec.notdone(); ++fspec) { max_min_initialized_(fspec) = 0; curvature_is_checked_(fspec) = 0; } } for (int relnum = 0; relnum < b.num_patch(); ++relnum) { PatchTable::Index patchind = b.patch(relnum).patchind(); Brep::Face_Spec owner = patchtable_.owner(patchind); if (max_min_initialized_(owner) == serial_num_) continue; max_min_initialized_(owner) = serial_num_; for (int l = 0; l < num_test_directions_actual_; ++l) { track_max_min_(owner).lower_bound[l] = 100; track_max_min_(owner).upper_bound[l] = -100; } } } // Figure out the variation of the normal on each topological // face in the box. Use a heuristics: find the maximum variation // in each direction in test_directions. { for (int relnum = 0; relnum < b.num_patch(); ++relnum) { PatchTable::Index patchind = b.patch(relnum).patchind(); Brep::Face_Spec owner = patchtable_.owner(patchind); int pdim = patchtable_.gdim(patchind); if (logstr_.verbosity() >= 9) { logstr_.str() << "relnum = " << relnum << " patchind = " << patchind << " owner = " << owner << '\n'; } int numinc = b.patch(relnum).num_incidence(); for (int ii = 0; ii < numinc; ++ii) { IncidenceTable::Index incind = b.patch(relnum).incidence(ii); Point paramcoord = inc_table_.param_coord(incind); Point realcoord = inc_table_.real_coord(incind); process_incidence1_(patchind, paramcoord, realcoord); if (pdim == di_ - 1) continue; for (PatchTable::Loop_over_parents loop(patchtable_, patchind); loop.notdone(); ++loop) { PatchTable::Index parentind = loop.parent_index(); Point paramcoord1 = patchtable_.lift_parameters(paramcoord, patchind, loop.listind()); process_incidence1_(parentind, paramcoord1, realcoord); if (pdim == di_ - 2) continue; for (PatchTable::Loop_over_parents loop2(patchtable_, parentind); loop2.notdone(); ++loop2) { PatchTable::Index grandparentind = loop2.parent_index(); Point paramcoord2 = patchtable_.lift_parameters(paramcoord1, parentind, loop2.listind()); process_incidence1_(grandparentind, paramcoord2, realcoord); } } } } } // Loop over patches and compare the variation of the normal over // the patch to the curve-control function. Size_Return ret; { Point incpoint_real; Point incpoint_par; for (int relnum = 0; relnum < b.num_patch(); relnum++) { Patch_in_ActiveBox patch = b.patch(relnum); PatchTable::Index patchind = patch.patchind(); Brep::Face_Spec owner = patchtable_.owner(patchind); if (owner.fdim() == 0) continue; if (curvature_is_checked_(owner) == serial_num_) continue; curvature_is_checked_(owner) = serial_num_; Real rq1 = rqvariance_(owner); for (int l = 0; l < num_test_directions_actual_; ++l) { Real delta = track_max_min_(owner).upper_bound[l] - track_max_min_(owner).lower_bound[l]; if (logstr_.verbosity() >= 14) { logstr_.str() << "pat#" << patchind << "# owner " << owner << " dir " << l << " delta = " << delta << '\n'; } if (delta > rq1) { if (logstr_.verbosity() >= 8) logstr_.str() << " curvature not ok rqvariance = " << rq1 << " variation on " << owner << " is " << delta << " dir " << l<< " crv-return false\n"; ret.fspec = owner; ret.val = rq1; ret.ok = false; logstr_.change_verbosity(oldverb); return ret; } } } } // All the stuff in the box should be connected, either directly // or by using patches outside the box by a factor of 2. // The farther-away patches must satisfy the curvature rqt. patch_searched_.reset(My_bool(false)); acceptable_for_search_cache_.reset(-1); map_to_relnum_.reset(-1); { for (int relnum = 0; relnum < b.num_patch(); ++relnum) map_to_relnum_[b.patch(relnum).patchind()] = relnum; } Point bmidpoint; for (int j = 0; j < di_; ++j) { if (b.flatdim(j)) { bmidpoint[j] = b.real_lowerleft()[j]; } else { bmidpoint[j] = b.real_lowerleft()[j] + boxwidth; } } patchind_stack_.resize(0); patchind_stack_.push_back(b.patch(0).patchind()); while (patchind_stack_.size() > 0) { PatchTable::Index newpatch = patchind_stack_.back(); patchind_stack_.pop_back(); if (patch_searched_[newpatch]) continue; if (logstr_.verbosity() >= 10) { logstr_.str() << " searching pat#" << newpatch << "#\n"; } patch_searched_[newpatch] = true; for (PatchTable::Loop_over_children cloop(patchtable_, newpatch); cloop.notdone(); ++cloop) { PatchTable::Index pind1 = cloop.child_index(); if (acceptable_for_search_(pind1, bmidpoint, boxwidth)) patchind_stack_.push_back(pind1); } for (PatchTable::Loop_over_parents ploop(patchtable_, newpatch); ploop.notdone(); ++ploop) { PatchTable::Index pind1 = ploop.parent_index(); if (acceptable_for_search_(pind1, bmidpoint, boxwidth)) patchind_stack_.push_back(pind1); } } // Find if there is a patch that was not reached by the preceding search. for (int relnum = 0; relnum < b.num_patch(); ++relnum) { if (!patch_searched_[b.patch(relnum).patchind()]) { if (logstr_.verbosity() >= 8) logstr_.str() << " curvature not ok disconnection on patch pat#" << b.patch(relnum).patchind() << "# relnum " << relnum << " from root pat#" << b.patch(0).patchind() << "# relnum " << relnum << " crv-return false\n"; ret.fspec = patchtable_.owner(b.patch(relnum).patchind()); ret.val = rqvariance_(ret.fspec); ret.ok = false; logstr_.change_verbosity(oldverb); return ret; } } if (logstr_.verbosity() >= 8) logstr_.str() << " crv-return true"; ret.ok = true; logstr_.change_verbosity(oldverb); return ret;}QMG::MG::Separation_Functor::Separation_Functor(const Brep& brep, const PatchTable& patchtable, IncidenceTable& inc_table, const SizeControl& size_control, const SizeControl& curve_control, Brep_Orbits& orbits, double scfac, double tol, Logstream& logstr, Meshgen_gui& gui) :brep_(brep),logstr_(logstr),patchtable_(patchtable),inc_table_(inc_table),size_control_(size_control),curve_control_(curve_control),orbits_(orbits),scfac_(scfac),tol_(tol),di_(brep.embedded_dim()),lca_(brep),track_max_min_(brep),num_test_directions_actual_((di_ == 2)? NUM_TEST_DIRECTIONS_2D:NUM_CURVATURE_TEST_DIRECTION),test_directions_(num_test_directions_actual_, Point()),patch_searched_(patchtable, My_bool(false)),acceptable_for_search_cache_(patchtable, 0),map_to_relnum_(patchtable,0),rqvariance_(brep),serial_num_(1),max_min_initialized_(brep),curvature_is_checked_(brep),crt_wkspa_(patchtable, inc_table, logstr, gui, scfac, tol){ for (int i = 0; i < num_test_directions_actual_; ++i) { for (int j = 0; j < di_; ++j) { test_directions_[i][j] = test_direction_init[i*3+j]; } test_directions_[i].normalize(); }} // Process a completely interior box for separation. The only reason to// split such a box is the size function.void QMG::MG::Separation_Functor::completely_interior(NonConstActiveBox& b, ActiveBoxVec& smallboxvec) { int di = b.embedded_dim(); #ifdef DEBUGGING if (!b.completely_interior()) { throw_error("Wrong separation function called 1."); return; }#endif if (logstr_.verbosity() >= 2) logstr_.str() << "separation comp int on box " << b; bool size_verified = b.size_function_verified(); int split_reason = 0; Brep::Face_Spec apex(di, b.owner()); Size_Return ret; if (!size_verified) { ret = ok_for_size_function_completely_interior_(b, apex); if (ret.ok) b.mark_size_verified(); else split_reason = 2; } if (split_reason) { if (logstr_.verbosity() >= 2) logstr_.str() << " split reason = " << split_reason << '\n'; if (b.iwidth() >= MAXLEV) { ostringstream os; os << "Quadtree has been split too finely because of the size" << " control function on region " << brep_.face_name(ret.fspec) << ".\nCould not match requested size of " << ret.val; throw_error(os.str()); } ActiveBoxVec::split_completely_interior_box_and_push_children(b, smallboxvec, logstr_); } else { if (logstr_.verbosity() >= 2) logstr_.str() << " put in orbit of " << apex.fdim() << ":" << apex.faceind() << '\n'; orbits_.retrieve_orbit(apex, b.iwidth()).push_box_completely_interior(b, logstr_); }}// Process a box during the separation stage. Box not completely interior.void QMG::MG::Separation_Functor::not_interior(NonConstActiveBox& b, int phase, ActiveBoxVec& tempstack, ActiveBoxVec& smallboxstack, ActiveBoxVec& idlestack, ActiveBoxVec& smallboxidlestack) {#ifdef DEBUGGING if (b.completely_interior()) throw_error("Wrong separation function called 2.");#endif if (logstr_.verbosity() >= 2) { logstr_.str() << "separation on box "; if (logstr_.verbosity() >= 4) b.full_dump(logstr_.str()); else logstr_.str() << b; } // First test: is it crowded? Triple<Brep::Face_Spec, Brep::Face_Spec, bool> returnval = is_crowded_(b, phase); bool crowded = returnval.third; Brep::Face_Spec apex = returnval.first; Brep::Face_Spec apex2 = returnval.second; bool size_verified = b.size_function_verified(); bool curvature_verified = b.curvature_verified(); Size_Return size_ret, curve_ret; if (apex.fdim() > phase) { if (logstr_.verbosity() >= 2) logstr_.str() << " no apex (idle)\n"; idlestack.push_box_shrink_ex(b, crt_wkspa_); } else { int split_reason = 0; if (crowded) { split_reason = 1; } // second test: is it too big for the size function? if (!split_reason && !size_verified) { size_ret = ok_for_size_function_(b, apex); if (size_ret.ok) b.mark_size_verified(); else split_reason = 2; } // third test: is it too curvy for the curve control function? if (!split_reason && !curvature_verified) { curve_ret = ok_for_curvature_(b); if (curve_ret.ok) b.mark_curvature_verified(); else split_reason = 3; } if (split_reason) { if (logstr_.verbosity() >= 2) { logstr_.str() << " split reason " << split_reason << '\n'; if (split_reason == 1) { Brep::Face_Spec apex2 = returnval.second; logstr_.str() << " crowding caused by " << apex.fdim() << ":" << apex.faceind() << " and " << apex2.fdim() << ":" << apex2.faceind() << '\n'; } else if (split_reason == 2) { logstr_.str() << " size function failed on facespec " << size_ret.fspec << '\n'; } else if (split_reason == 3) { logstr_.str() << " curvature function failed on facespec " << curve_ret.fspec << "\n"; } } if (b.iwidth() >= MAXLEV || 1.0 / static_cast<double>(1 << b.iwidth()) < 100 * tol_) { ostringstream os; os << "Quadtree has been split too finely, possibly indicating an error\n" << "in the input brep. The cause of the last split is:\n"; if (split_reason == 1) { os << "Unable to separate brep faces " << brep_.face_name(apex) << " from " << brep_.face_name(apex2); } else if (split_reason == 2) { os << "Unable to match desired size function value of " << size_ret.val << " on topological entity " << brep_.face_name(size_ret.fspec); } else if (split_reason == 3) { os << "Unable to match curvature value of " << curve_ret.val << " on topological entity " << brep_.face_name(curve_ret.fspec); os << " Patches involved are: "; for (int relnum = 0; relnum < b.num_patch(); ++relnum) { PatchTable::Index patchind = b.patch(relnum).patchind(); if (patchtable_.owner(patchind) != curve_ret.fspec) continue; if (patchtable_.gdim(patchind) != curve_ret.fspec.fdim()) continue; os << patchtable_.orig_index(patchind) << " "; } } throw_error(os.str()); } ActiveBoxVec::split_box_and_push_children(phase, tempstack, smallboxstack, smallboxidlestack, b, inc_table_, crt_wkspa_); } else { if (logstr_.verbosity() >= 2) logstr_.str() << " moved to orbit of " << apex.fdim() << ":" << apex.faceind() << '\n'; orbits_.retrieve_orbit(apex, b.iwidth()).push_box_shrink_ex(b, crt_wkspa_); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?