Exemplo n.º 1
0
 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
 }
Exemplo n.º 2
0
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;
}