virtual bool accept(CBsimplex* s) const { if (!is_edge(s)) // reject if non-edge return false; Bedge* e = (Bedge*)s; if (e->sil_stamp() == _stamp) // reject if previously checked return 0; e->set_sil_stamp(_stamp); // mark as checked this frame if (_skip_secondary && e->is_secondary()) // reject secondary edges as needed return false; return e->is_sil(); // accept if silhouette }
Bsimplex* Bface::ndc_walk( CNDCpt& target, CWvec &passed_bc, CNDCpt &nearest, int is_on_tri, bool use_passed_in_params) const { // just like local_search, but in NDC space // // start from this face, move in NDC space // across the mesh to reach the target // // if reached, return the simplex that contains // the target point. // we only move if it will get us closer to the goal. Hence, we // can never wander off forever. // if can't reach it, return 0 NDCpt y (nearest); Wvec bc(passed_bc); if (!use_passed_in_params) { y = nearest_pt_ndc(target, bc, is_on_tri); } Bsimplex* sim = bc2sim(bc); if (is_on_tri) { // target is on this triangle // return the lowest-dimensional // simplex on which it lies return sim; } if (is_edge(sim)) { Bedge* e = (Bedge*)sim; Bface* f = e->is_sil() ? nullptr : e->other_face(this); if (f) { Wvec new_bc; int new_on_tri; NDCpt new_best = f->nearest_pt_ndc(target, new_bc, new_on_tri); if (new_best.dist_sqrd(target) < y.dist_sqrd(target)) return f->ndc_walk(target, new_bc, new_best, new_on_tri, true); else return nullptr; } else { return nullptr; } } // better be a vertex assert(is_vert(sim)); Bvert* v = (Bvert*)sim; if (v->degree(SilEdgeFilter()) > 0) return nullptr; Bface_list nbrs(16); ((Bvert*)sim)->get_faces(nbrs); double dist_sqrd = 1e50; Bface* best = nullptr; Wvec best_bc; NDCpt best_nearest; int best_on_tri = 0; Wvec curr_bc; NDCpt curr_nearest; int curr_on_tri=0; for (Bface_list::size_type k = 0; k < nbrs.size(); k++) { if (nbrs[k] != this) { curr_nearest = nbrs[k]->nearest_pt_ndc(target, curr_bc, curr_on_tri); if (curr_nearest.dist_sqrd(target) < dist_sqrd ) { dist_sqrd = curr_nearest.dist_sqrd(target); best_bc = curr_bc; best_on_tri = curr_on_tri; best_nearest = curr_nearest; best = nbrs[k]; } } } if (dist_sqrd < y.dist_sqrd(target)) { return best->ndc_walk(target, best_bc, best_nearest, best_on_tri, true); } return nullptr; }