Beispiel #1
0
void
EdgeStrip::build(Bvert* v, Bedge* e, CSimplexFilter& filter)
{
   // continue building the edge strip, starting with the
   // given edge e. if v is not null, e must contain v.
   // in that case v will be the leading vertex of the strip.

   // must have an edge to proceed,
   // and the edge must be accepted by the filter.
   if (!(e && filter.accept(e))) // someone has to punch its ticket
      return;

   assert(!v || e->contains(v));

   static Bvert_list stack(64);
   stack.clear();

   // first loop:
   build_line_strip(v ? v : e->v1(), e, filter, stack);

   // get the rest of them
   while (!stack.empty()) {
      if ((v = stack.pop()) && (e = next_edge(v, stack, filter))) 
         build_line_strip(v, e, filter, stack);
   }
}
Beispiel #2
0
inline Bvert_list
reorder(CBedge_list& edges)
{
   Bvert_list ret;

   Bvert_list verts = edges.get_verts();
   for (Bvert_list::size_type i = 0; i < verts.size(); i++)
      if (Bpoint::find_controller(verts[i]) || Bcurve::find_controller(verts[i])) {
         ret.push_back(verts[i]);
         break;
      }
   if (ret.empty())
         return ret;

   for (Bvert_list::size_type i = 1; i < verts.size(); i++) {
      for (Bedge_list::size_type j = 0; j < edges.size(); j++) {
         Bvert* v = edges[j]->other_vertex(ret.back());
         if (v && std::find(ret.begin(), ret.end(), v) == ret.end()) {
            ret.push_back(v);
            break;
         }
      }
   }

   err_adv(debug, "   reorder: num of verts: %d", ret.size());
   return ret;
}
Beispiel #3
0
inline double
compute_h(Bvert* v)
{
   assert(v);
   PCell_list cells = Panel::find_cells(v->get_faces());

   if (cells.size() == 2) {
      // common case: vertex in a tube ring (2 neighboring cells)
      if (Bpoint::find_controller(v) || Bcurve::find_controller(v))
         return cells[0]->shared_boundary(cells[1]).avg_len()/2;

      Bvert_list verts = reorder(cells[0]->shared_boundary(cells[1]));
      double num = verts.size()-1;
      assert(num > 1);
      int index = verts.get_index(v);
      assert(index != -1);
      double h = (compute_h(verts.front()) + compute_h(verts.back())) / 2;
      return h * (1 + min(index/num, 1-index/num));

   } else if (cells.size() > 2) {
      // multiple adjacent cells
      return PCell::shared_edges(cells).avg_len()/2;
   } else if (cells.size() == 1) {
      // just one cell, e.g. tip of a tube, or part of a disk
      if (cells[0]->num_corners() == 3) {
         if (cells[0]->nbrs().size() != 1) {
            return cells[0]->boundary_edges().avg_len()/2;
         }
         assert(cells[0]->nbrs().size() == 1);
         return 0; // it's the tip of the triangle
      } else if (cells[0]->num_corners() == 4) {
         if (cells[0]->nbrs().size() == 0) {
            return cells[0]->boundary_edges().avg_len()/2;
         } else if (cells[0]->nbrs().size() == 1) {
            // or maybe should do same rule as next case
            Bedge_list end_edges = quad_cell_end_edges(cells[0]);
            err_adv(debug, "found %d end edges", end_edges.size());
            return end_edges.avg_len()/2;
         }
         return v->strong_edges().avg_len()/2;
      }
      if (Bpoint::find_controller(v) || Bcurve::find_controller(v))
         return cells[0]->boundary_edges().filter(BorderEdgeFilter()||BcurveFilter()).avg_len()/2;

      Bvert_list nbrs;
      v->get_nbrs(nbrs);
      assert(!nbrs.empty());
      return 1.5 * compute_h(nbrs[0]);
   } 

   err_adv(debug, "compute_h: unexpected number of cells: %d", cells.size());
   return -1;
}
Beispiel #4
0
SubdivUpdater::SubdivUpdater(LMESHptr m, CBvert_list& verts) :
   _parent(nullptr)
{
   // Screened in SubdivUpdater::create():
   assert(m && m == verts.mesh());

   _mesh = m;
   _verts = verts;

   // Get bbases, add to inputs
   _inputs = Bbase::find_owners(verts).bnodes();

   if (debug) {
      err_msg("SubdivUpdater::SubdivUpdater:");
      cerr << "  "; print_dependencies();
      err_msg("  level %d, %d verts, %d boss memes",
              m->subdiv_level(), verts.size(),
              Bbase::find_boss_vmemes(verts).size());
   }

   // If not covered, create parent
   if (!Bbase::is_covered(verts)) {
   
      // Get parent verts list
      Bvert_list parents = LMESH::get_subdiv_inputs(verts);

      // If non-empty create parent SubdivUpdater
      if (!parents.empty()) {

         // Create parent subdiv updater on parent verts
         // and add to _inputs
         _parent = create(parents);
         _inputs += _parent;
      }

   }

   hookup();
}