Esempio n. 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);
   }
}
Esempio n. 2
0
Bvert_list
BvertGrid::col(int i) const
{
   Bvert_list ret;
   for (int j=0; j<nrows(); j++)
      ret.push_back(vert(i,j));
   return ret;
}
Esempio n. 3
0
bool 
Bface::get_quad_verts(Bvert_list& verts) const 
{
   verts.clear();
   Bvert *v1=nullptr, *v2=nullptr, *v3=nullptr, *v4=nullptr;
   if (!get_quad_verts(v1,v2,v3,v4))
      return 0;
   verts.push_back(v1);
   verts.push_back(v2);
   verts.push_back(v3);
   verts.push_back(v4);
   return 1;

}
Esempio n. 4
0
Bvert_list 
Bface_list::interior_verts() const 
{
   // Return list vertices that are not adjacent to any external face.

   Bvert_list ret = get_verts();
   for (Bvert_list::size_type i=0; i<get_boundary().verts().size(); i++) {
      Bvert_list::iterator it;
      it = std::find(ret.begin(), ret.end(), get_boundary().verts()[i]);
      ret.erase(it);
   }
   return ret;

   // mark internal faces w/ flag 1, external faces with flag 0:
   mark_faces(); 
   return get_verts().filter(VertFaceDegreeFilter(0, SimplexFlagFilter(0)));
}
Esempio n. 5
0
inline VertMapper
subdiv_mapper(CVertMapper& pmap)
{
   Bedge_list a_edges = pmap.a_edges();
   Bedge_list b_edges = pmap.a_to_b(a_edges);
   assert(a_edges.num() == b_edges.num());

   if (0 && debug) {
      err_msg("parents: verts: %d --> %d, edges: %d --> %d",
              pmap.A().num(), pmap.B().num(), a_edges.num(), b_edges.num());
      err_msg("children: verts: %d --> %d",
              (child_verts<Bvert_list,Lvert>(pmap.A()) +
               child_verts<Bedge_list,Ledge>(a_edges)).num(),
              (child_verts<Bvert_list,Lvert>(pmap.B()) +
               child_verts<Bedge_list,Ledge>(b_edges)).num());

      Bvert_list c = (child_verts<Bvert_list,Lvert>(pmap.A()) +
                      child_verts<Bedge_list,Ledge>(a_edges));
      if (c.has_duplicates()) {
         err_msg("*** child verts have duplicates ***");
         if (pmap.A().has_duplicates()) {
            err_msg("  A verts have duplicates");
         }
         if (pmap.a_edges().has_duplicates()) {
            err_msg("  A edges have duplicates");
         }
         if (child_verts<Bvert_list,Lvert>(pmap.A()).has_duplicates()) {
            err_msg("  vert children have duplicates");
         }
         if (child_verts<Bedge_list,Ledge>(pmap.a_edges()).has_duplicates()) {
            err_msg("  edge children have duplicates");
         }
         WORLD::show_pts(c.pts());
      }
   }

   return VertMapper(
      child_verts<Bvert_list,Lvert>(pmap.A()) +
      child_verts<Bedge_list,Ledge>(a_edges),
      child_verts<Bvert_list,Lvert>(pmap.B()) +
      child_verts<Bedge_list,Ledge>(b_edges)
      );
}
Esempio n. 6
0
/*!
	Given edge e containing endpoint v, return the subdiv
	verts at the current level, in order starting at v and
	running to the other endpoint.
 */
inline Bvert_list
get_cur_level_verts(Bvert* v, Bedge* e)
{

   assert(v && e && e->contains(v));

   Bvert_list ret;

   LMESH* mesh = LMESH::upcast(e->mesh());
   if (mesh) {
      ((Ledge*)e)->get_subdiv_verts(mesh->rel_cur_level(), ret);
   } else {
      ret += e->v1();
      ret += e->v2();
   }
   if (e->v1() != v)
      ret.reverse();
   return ret;
}
Esempio n. 7
0
bool
EdgeStrip::get_chain(int& k, Bvert_list& chain) const
{
   // Return the chain starting at index k,
   // and advance k to the start of the next chain.

   chain.clear();               // get set...

   if (k < 0 || k >= num())     // if out of range, reject
      return false;

   if (!has_break(k))           // if k is not a chain endpoint, reject
      return false;             

   chain += vert(k);            // add leading vertex
   do {
      chain.add(next_vert(k));  // add subsequent vertex
   } while (!has_break(++k));   // advance k, break at chain end

   return true;
}
Esempio n. 8
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();
}
Esempio n. 9
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;
}
Esempio n. 10
0
inline int
match_span(Bvert* v, Bedge* e, CPIXEL_list& trail, int k, double thresh)
{
   // Ensure various required conditions are true:
   if (!(v && e && e->contains(v) && trail.valid_index(k))) {
      err_adv(debug, "match_span: invalid vert/edge/index");
      return -1;
   }

   // Get the chain of vertices at the "current" mesh level:
   Bvert_list verts = get_cur_level_verts(v, e);
   assert(verts.num() > 1);

   // Ensure the vertex chain starts near the current
   // position in the pixel trail:
   if (trail[k].dist(verts.first()->wloc()) > thresh) {
      err_adv(debug, "match_span: vert chain too far from pixel trail: %f > %f",
              trail[k].dist(verts.first()->wloc()), thresh);
      return -1;
   }

   // Test that the length of the refined edge is
   // close to the length of the chosen span.
   //
   // This is a cheap way of seeing that the projected edge
   // lies reasonably along the given portion of the pixel trail.
   int ret = next_match(verts.last(), trail, k, thresh);
   if (ret < 0) {
      err_adv(debug, "match_span: can't match next vert");
      return -1;
   }
   double vlen = pix_len(verts.wpts());
   if (vlen < 0)
      return -1;
   // Measure length of the trail, including distance to
   // beginning and end of the projected edge:
   double tlen = length(trail, k, ret);
   double e1 = verts.first()->pix().dist(trail[  k]);
   double e2 = verts.last ()->pix().dist(trail[ret]);;
   err_adv(debug, "adding %3.0f, %3.0f", e1, e2);
   err_adv(debug, "edge length: %3.0f, span length: %3.0f, ratio: %1.2f: %s",
           vlen, tlen, tlen/vlen, (tlen > 1.2*vlen) ? "rejected" : "accepted");
   if (tlen > 1.2*vlen)
      return -1;
   return ret;
}
Esempio n. 11
0
Bvert_list
LMESH::get_subdiv_inputs(CBvert_list& verts)
{
   static bool debug = Config::get_var_bool("DEBUG_LMESH_SUBDIV_INPUTS",false);

   // Given a set of vertices from the same LMESH, return
   // the vertices of the parent LMESH that affect the
   // subdivision locations of the given vertices.

   // Require verts share common LMESH
   // XXX - could relax this, provided we test each Bvert
   //       to ensure it is really an Lvert.
   if (!dynamic_pointer_cast<LMESH>(verts.mesh()))
      return Bvert_list();

   // Get direct parent vertices and edges
   Bvert_list vp;       // vertex parents
   Bedge_list ep;       // edge parents
   get_parents(verts, vp, ep);

   err_adv(debug, "%d verts: parents: %d verts, %d edges",
           verts.size(), vp.size(), ep.size());

   // Clear flags of all adjacent faces
   clear_face_flags(vp);
   ep.clear_flag02();

   // Put all adjacent faces into a list
   Bface_list faces = get_q_faces(vp);
   err_adv(debug, "parent faces from verts: %d", faces.size());
   try_append(faces, ep.get_primary_faces());
   err_adv(debug, "parent faces from edges too: %d", faces.size());

   // Pull out the vertices:
   return faces.get_verts();
}
Esempio n. 12
0
bool
OVERSKETCH::compute_offsets(CPIXEL_list& pts, CEdgeStrip& sils)
{
   double yardstick = compute_yardstick(sils.edges(), debug);

   assert(sils.num_line_strips() == 1);
   Bvert_list chain;
   int k = 0;
   sils.get_chain(k, chain);
   int count = 0;
   vector<double> offsets;
   Wpt_list new_locs = chain.pts();
   for (Bvert_list::size_type i=0; i<chain.size(); i++) {
      offsets.push_back(compute_offset(chain[i], pts, yardstick));
      if (offsets.back() > 0) {
         count++;
      }
   }
   err_adv(debug, "found %d/%d offsets", count, chain.size());

   apply_offsets(chain, offsets);

   return true;
}
Esempio n. 13
0
inline void
debug_check_verts(const string& msg, CBvert_list& verts, CBvert_list& dirty_verts)
{
   Bvert_list A = verts.filter(BitSetSimplexFilter(Lvert::DIRTY_VERT_LIST_BIT));
   if (!dirty_verts.contains_all(A)) {
      Bvert_list bad = A.minus(dirty_verts);
      cerr << msg << ": found " << bad.size()
           << " vertices missing from dirty list" << endl;
      WORLD::show_pts(bad.pts(), 8, Color::red);
   }
   Bvert_list B = verts.filter(BitClearSimplexFilter(Lvert::DIRTY_VERT_LIST_BIT));
   if (dirty_verts.contains_any(B)) {
      Bvert_list bad = dirty_verts.minus(B);
      cerr << msg << ": found " << bad.size()
           << " unexpected vertices in dirty list" << endl;
      WORLD::show_pts(bad.pts(), 8, Color::blue);
   }
}
Esempio n. 14
0
inline void
add_p(Lvert* v, Bvert_list& vp, Bedge_list& ep)
{
   // Helper method used below in get_parents();
   // Given an Lvert, add its parent simplex to the
   // appropriate list depending on whether the parent
   // is an Lvert or Ledge.

   assert(v);

   Bsimplex* p = v->parent();
   if (!p)
      return;
   if (is_vert(p))
      vp.push_back((Bvert*)p);
   else if (is_edge(p))
      ep.push_back((Bedge*)p);
   else
      assert(0);
}
Esempio n. 15
0
inline void
make_strip(Bvert_list chain, int k0, int k1, EdgeStrip& strip)
{
   assert(chain.forms_chain());
   assert(0 <= k0 && k0 < (int)chain.size() && 0 <= k1 && k1 < (int)chain.size());
   assert(k0 != k1);
   if (k0 > k1) {
      std::reverse(chain.begin(), chain.end());
      int n = chain.size()-1;
      k0 = n - k0;
      k1 = n - k1;
   }
   strip.reset();
   for (int i=k0; i<k1; i++) {
      strip.add(chain[i], lookup_edge(chain[i], chain[i+1]));
   }
}
Esempio n. 16
0
void 
Skin::draw_debug()
{
   if (!_show_memes)
      return;

   //if (!debug)
   //   return;

   // frozen: blue
   // sticky: orange
   // unglued: grey

   Skin* cur = upcast(cur_subdiv_bbase());
   if (!cur) return;
   Bvert_list    verts = cur->skin_verts();
   Bvert_list   frozen = cur->frozen_verts(verts);
   verts = verts.minus(frozen);
   Bvert_list   sticky = cur->sticky_verts(verts);
   Bvert_list  unglued = verts.minus(sticky);
   GL_VIEW::draw_pts(frozen.pts(),  Color::blue,   0.8, 8);
   GL_VIEW::draw_pts(sticky.pts(),  Color::orange, 0.8, 8);
   GL_VIEW::draw_pts(unglued.pts(), Color::grey6,  0.8, 8);

   if (debug) GL_VIEW::draw_lines(
      bundle_lines(verts.pts(), cur->track_points(verts)),
      Color::yellow,
      0.8,
      1,
      false
      );
   if (debug) GL_VIEW::draw_lines(
      bundle_lines(verts.pts(), centroids(verts)),
      Color::red,
      0.8,
      1,
      false
      );
}
Esempio n. 17
0
bool
BvertGrid::build(
   CBvert_list& bottom,         // bottom row
   CBvert_list& top,            // top row
   CBvert_list& left,           // left column
   CBvert_list& right           // right column
   )
{
   // Vertices of bottom and top run left to right.
   // On the left and right they run bottom to top.

   // Check everything is righteous:
   if (bottom.size() < 2                ||
       bottom.size() != top.size()      ||
       left.size() < 2                  ||
       left.size() != right.size()      ||
       bottom.front() != left.front()   ||
       bottom.back()  != right.front()  ||
       top.front()    != left.back()    ||
       top.back()     != right.back()   ||
       !bottom.same_mesh()              ||
       !top.same_mesh()                 ||
       !left.same_mesh()                ||
       !right.same_mesh()               ||
       bottom.mesh() == nullptr) {
      err_msg("BvertGrid::build: can't deal with CRAP input");

      std::ostream_iterator<Bvert*> err_it (std::cerr, ", ");

      cerr << "bottom: ";
      std::copy(bottom.begin(), bottom.end(), err_it);
      cerr << endl;

      cerr << "top:    ";
      std::copy(top.begin(), top.end(), err_it);
      cerr << endl;

      cerr << "left:   ";
      std::copy(left.begin(), left.end(), err_it);
      cerr << endl;

      cerr << "right:  ";
      std::copy(right.begin(), right.end(), err_it);
      cerr << endl;

      return false;
   }

   // Wipe the old:
   clear();

   // Build the new...
   //   bottom row:
   _grid.push_back(bottom);

   BMESHptr m = bottom.mesh();    assert(m);

   // Internal rows:
   for (Bvert_list::size_type j=1; j<left.size()-1; j++) {
      Bvert_list row;                    // vertices for row j
      row.push_back(left[j]);            // add first vertex for row j
      for (Bvert_list::size_type i=1; i<bottom.size()-1; i++)
         row.push_back(m->add_vertex()); // add internal vertices
      row.push_back(right[j]);           // add last vertex for row j
      _grid.push_back(row);
   }

   // top row:
   _grid.push_back(top);

   // Now compute cached values:
   cache();

   return true;
}
Esempio n. 18
0
void 
ProxySurface::trim_proxy_surface()
{
   assert(_proxy_mesh);

   int n = 0; //number of faces outside the bounding box   
   //get all the quads
   Bface_list faces = _proxy_mesh->faces();
   //clear out all the markings
   for(int i=0; i < faces.num(); ++i)
   {
      if(faces[i])
         ProxyData::set_mark(faces[i],this, false);
      //else
      //   cerr << "FACE is NULL" << endl;
   }
   //mark all the faces that do not overap bounding box
   for(int i=0; i < faces.num(); ++i)
   {
      if(faces[i]){
         bool t1 = (is_inside_bounding_box(faces[i]->e1())) ? true : false;
         bool t2 = (is_inside_bounding_box(faces[i]->e2())) ? true : false;
         bool t3 = (is_inside_bounding_box(faces[i]->e3())) ? true : false;
         
         // If all the edges are outside, then mark the face
         if(!t1 && !t2 && !t3){
            //cerr << "we can delete this face" << endl;
            ProxyData::set_mark(faces[i], this, true);
            n++;
         }
      }else {
         //cerr << "FACE is NULL" << endl;
      }
   }

   if(n < 1)
      return; 

   //for all verts check to see if all the faces that it is attached to has a marked
   Bvert_list verts = _proxy_mesh->verts();
   for(int i=0; i < verts.num(); ++i)
   {
      ARRAY<Bface*> ret;
      verts[i]->get_quad_faces(ret);
      // Make sure that all adjasent faces need to be deleted
      bool do_it=true;
      for(int k=0; k < ret.num(); ++k)
      {
         if(ret[k]){
            assert(ret[k]->is_quad());            
            if(!ProxyData::get_mark(ret[k], this) || !ProxyData::get_mark(ret[k]->quad_partner(), this))
            {
              // cerr << "vert degree " << verts[i]->p_degree() << endl;
               do_it = false;
               break;
            }
         }
      }
      if(do_it){
         UVpt remove_uv;
         UVdata::get_uv(verts[i], remove_uv);
         remove_vert_grid(remove_uv);

         _proxy_mesh->remove_vertex(verts[i]);
         _proxy_mesh->changed();
      }
   }
   //clean up faces
   Bface_list faces2 = _proxy_mesh->faces();
   for(int i=0; i < faces2.num(); ++i)
   {
      if(!(faces2[i]->is_quad()) || !(faces2[i]->quad_partner())){
         _proxy_mesh->remove_face(faces2[i]);
         _proxy_mesh->changed();
      }
      
   }

   //debug_grid();

   
}
Esempio n. 19
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;
}