gmcoarsetopo.cpp
来自「算断裂的」· C++ 代码 · 共 924 行 · 第 1/3 页
CPP
924 行
string otherval = b.face_lookup_prop_val(parent2, pvloop.prop()); if (pvloop.val() != otherval) { // ctlog << " not deleting; parents differ in property " << pvloop.prop() // << " values = " << pvloop.val() << "," << otherval << '\n'; ok_to_delete(fspec) = false; break; } } if (!ok_to_delete(fspec)) continue; for (Brep::Loop_over_propvals_of_face pvloop2(b, parent2); pvloop2.notdone(); ++pvloop2) { string otherval = b.face_lookup_prop_val(parent1, pvloop2.prop()); if (pvloop2.val() != otherval) { //ctlog << " not deleting; parents differ in property " << pvloop2.prop() // << " values = " << pvloop2.val() << "," << otherval << '\n'; ok_to_delete(fspec) = false; break; } } if (!ok_to_delete(fspec)) continue; // Check that the two parents have the same parents. parent1_parentlabels.resize(0); for (Brep::Ancestor_Lookup::Loop_over_ancestors ancloop1(anc_lookup, parent1); ancloop1.notdone(); ++ancloop1) { Brep::Face_Spec afspec = ancloop1.ancestor_fspec(); if (afspec.fdim() != fdim + 2) continue; if (ok_to_delete(afspec)) continue; for (int j = 0; j < ancloop1.occurrence_count(); ++j) parent1_parentlabels.push_back(uf[fdim+1].get_label(afspec.faceind())); } parent2_parentlabels.resize(0); for (Brep::Ancestor_Lookup::Loop_over_ancestors ancloop2(anc_lookup, parent2); ancloop2.notdone(); ++ancloop2) { Brep::Face_Spec afspec = ancloop2.ancestor_fspec(); if (afspec.fdim() != fdim + 2) continue; if (ok_to_delete(afspec)) continue; for (int j = 0; j < ancloop2.occurrence_count(); ++j) parent2_parentlabels.push_back(uf[fdim+1].get_label(afspec.faceind())); }/* { ctlog << " parent labels of parent1 = "; for (int jj = 0; jj < parent1_parentlabels.size(); ++jj) { ctlog << parent1_parentlabels[jj] << ' '; } ctlog << " of parent2 = "; for (int jj2 = 0; jj2 < parent2_parentlabels.size(); ++jj2) { ctlog << parent2_parentlabels[jj2] << ' '; } ctlog << '\n'; } */ if (parent1_parentlabels.size() != parent2_parentlabels.size()) { ok_to_delete(fspec) = false; // ctlog << " not deleting; different length parent labels\n"; continue; } sort(parent1_parentlabels.begin(), parent1_parentlabels.end()); sort(parent2_parentlabels.begin(), parent2_parentlabels.end()); for (int jj = 0; jj < parent1_parentlabels.size(); ++jj) { if (parent1_parentlabels[jj] != parent2_parentlabels[jj]) { ok_to_delete(fspec) = false; // ctlog << " not deleting; different parents\n"; break; } } if (!ok_to_delete(fspec)) continue; // If the number of ancestors is 2, loop over patches of // the face to see if the parent patches have sufficiently // close normals.. for (Brep::Loop_over_patches_of_face patchloop(b, fspec); patchloop.notdone(); ++patchloop) { Brep::PatchIndex ind = patchloop.index(); PatchTable::Index patchind = lookup_patchind[PatchInBrepAddress(fspec,ind)]; int numends = fdim + 1; for (int whichend = 0; whichend < numends; ++whichend) { // Find the two ancestors of this patch. int pt_anc_count = 0; Point prev_normal_or_tan; Point param; param[0] = static_cast<double>(whichend); Point paramdirec; paramdirec[0] = 1.0; for (PatchTable::Loop_over_parents parloop(patchtable, patchind); parloop.notdone(); ++parloop) { PatchTable::Index ppatchind = parloop.parent_index(); Brep::PatchIndex thisparentind = patchtable.orig_index(ppatchind); Brep::Face_Spec thisparent = patchtable.owner(ppatchind); if (patchtable.gdim(ppatchind) != fdim + 1 || thisparent.fdim() != fdim + 1) throw_error("patch loop inconsistency"); if (ok_to_delete(thisparent)) continue; if (thisparent != parent1 && thisparent != parent2) throw_error("patch loop problem 2"); // Lift the coordinates, and compute the normal. // Do this differently depending on the type of patch. int lift0 = parloop.lift_index(0); int lift1 = (fdim == 1)? parloop.lift_index(1) : 0; Point liftparam = patchtable.lift_parameters(param, patchind, parloop.listind()); Point normal_or_tan; if (fdim == 0) { normal_or_tan = b.patchmath(thisparent, thisparentind). direc_deriv(liftparam, paramdirec); if (normal_or_tan.l2norm() == 0) throw_error("Vanishing tangent on curve"); normal_or_tan.normalize(); } else { normal_or_tan = b.patchmath(thisparent, thisparentind). normal(liftparam); } // Flip sign if necessary. if (lookup_orientation_[lift0*10+lift1] != (pt_anc_count == 0)) { for (int j = 0; j < di; ++j) normal_or_tan[j] = -normal_or_tan[j]; } if (pt_anc_count == 0) prev_normal_or_tan = normal_or_tan; else { if (!twovec_ok_for_curve_bound(prev_normal_or_tan, normal_or_tan, allowable_curvature)) ok_to_delete(fspec) = false; } /* ctlog << " normal on patch " << patchtable.orig_index(patchind) << " end " << whichend << " parent patch " << thisparent << ':' << thisparentind << " (count = " << pt_anc_count << ") is" << normal_or_tan << '\n'; if (!ok_to_delete(fspec)) ctlog << " not ok to delete --curvature\n"; */ ++pt_anc_count; } if (pt_anc_count != 2) { throw_error("Patch table problem 3"); } if (!ok_to_delete(fspec)) break; } if (!ok_to_delete(fspec)) break; } } else { // anc_count == 0 // ctlog << " no parents\n"; if (fdim == 0 && di == 3) { // In this special case, must loop over patches // containing this node to check if they // line up. init_maxmin_(); PatchTable::Index patchind = lookup_patchind[PatchInBrepAddress(fspec,0)]; int parcount1 = 0; int parcount2 = 0; for (PatchTable::Loop_over_parents parloop(patchtable, patchind); parloop.notdone(); ++parloop) { ++parcount1; if (parloop.listind() > 0) continue; PatchTable::Index firstcurve = parloop.parent_index(); PatchTable::Index prev2D = -1; PatchTable::Index currcurve = firstcurve; int currendp = parloop.lift_index(0); already_seen.reset(My_bool(false)); while (!already_seen[currcurve]) {/* ctlog << " looping over parent patch " << currcurve << " dim " << patchtable.gdim(currcurve) << " owner " << patchtable.owner(currcurve); if (patchtable.owner(currcurve).fdim() == patchtable.gdim(currcurve)) ctlog << ':' << patchtable.orig_index(currcurve); ctlog << '\n'; */ // Loop over parents of currcurve; find a parent // not equal to prev2D; already_seen[currcurve] = true; int parcount3 = 0; PatchTable::Index nextcurve = -1; PatchTable::Index nextprev2d; int nextendp; for (PatchTable::Loop_over_parents parloop2(patchtable, currcurve); parloop2.notdone(); ++parloop2) { ++parcount3; PatchTable::Index gpindex = parloop2.parent_index(); if (gpindex == prev2D) continue; for (PatchTable::Loop_over_children chloop(patchtable, gpindex); chloop.notdone(); ++chloop) { PatchTable::Index uncleindex = chloop.child_index(); if (uncleindex == currcurve) continue; for (PatchTable::Loop_over_children chloop2(patchtable, uncleindex); chloop2.notdone(); ++chloop2) { if (chloop2.child_index() == patchind) { nextprev2d = gpindex; nextcurve = uncleindex; nextendp = chloop2.lift_index(0); } } } } if (parcount3 != 2) { ok_to_delete(fspec) = false; // ctlog << " parent patch does not have two parents; not OK to delete\n"; break; } if (nextcurve < 0) throw_error("Nextcurv not found?"); Point paramcoord, direc; paramcoord[0] = static_cast<double>(currendp); direc[0] = (currendp)? -1.0 : 1.0; Point tan1 = patchtable.patchmath(currcurve). direc_deriv(paramcoord, direc); paramcoord[0] = static_cast<double>(nextendp); direc[0] = (nextendp)? -1.0 : 1.0; Point tan2 = patchtable.patchmath(nextcurve). direc_deriv(paramcoord, direc); Point nrml = Point::cross_product(tan1, tan2); if (nrml.l2norm() == 0) throw_error("Zero normal?"); nrml.normalize(); // ctlog << " crossprod with nextcurve " << nextcurve << " tan yields " << nrml // << '\n'; bool ok1 = update_maxmin_(nrml, allowable_curvature); if (!ok1) { ok_to_delete(fspec) = false; // ctlog << " curvature not met; not OK to delete\n"; break; } currcurve = nextcurve; currendp = nextendp; prev2D = nextprev2d; ++parcount2; } if (currcurve != firstcurve) { // ctlog << " didn't return to first patch currcurve = " << currcurve // << " firstcurve = " << firstcurve << "; not ok to delete\n"; ok_to_delete(fspec) = false; } if (!ok_to_delete(fspec)) break; } if (parcount1 != parcount2) ok_to_delete(fspec) = false; } } if (!ok_to_delete(fspec)) continue; // ctlog << "OK to delete " << fspec; if (anc_count == 2) { uf[fdim + 1].merge(parent1.faceind(), parent2.faceind()); // ctlog << " merged " << parent1 << "," << parent2 << " under label " // << uf[fdim+1].get_label(parent1.faceind()); } // ctlog << '\n'; } } } // uf gives numbers to indicate which faces are merged. // Now make a map from old faces to new. // We renumber the uf labels to skip over deleted faces. Brep::Face_Labeling<Brep::FaceIndex> old_to_new_map(b,0); vector<int> new_level_size(di + 1); { vector<Brep::FaceIndex> renumuf; for (int fdim = 0; fdim <= di; ++fdim) { int numlabels = uf[fdim].pack_labels(); renumuf.resize(numlabels); for (int j = 0; j < numlabels; ++j) renumuf[j] = -1; Brep::FaceIndex nextnewfaceind = 0; for (Brep::Face_Spec_Loop_Over_Faces_Of_Dim fspec(b, fdim); fspec.notdone();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?