int Patch::draw_crease_strips(StripCB *cb) { EdgeStrip* strip = cur_creases(); if (strip) strip->draw(cb); return 0; }
EdgeStrip EdgeStrip::get_filtered(CSimplexFilter& filter) const { EdgeStrip ret; for (int i=0; i<num(); i++) if (filter.accept(edge(i))) ret.add(vert(i), edge(i)); return ret; }
bool PAPER_DOLL::init(CGESTUREptr& g) { if (!(g && g->is_stroke())) return false; if (g->below_min_length() || g->below_min_spread()) return false; if (!g->is_ellipse()) { err_adv(debug, "PAPER_DOLL::init: non-ellipse"); return false; } Panel* p = dynamic_cast<Panel*>( Bsurface::get_surface(get_top_level(VisRefImage::get_faces(g->pts()))) ); err_adv(debug, "PAPER_DOLL::init: %s panel", p?"found":"could not find"); if (!(p && p->is_selected())) { err_adv(debug, "PAPER_DOLL::init: ellipse not over selected panel"); return false; } assert(p && p->bfaces().size() > 0); Bface_list faces = Bface_list::reachable_faces(p->bfaces().front()); assert(!faces.empty()); if (!faces.is_planar(deg2rad(1.0))) { err_adv(debug, "PAPER_DOLL::init: region is not planar"); return false; } EdgeStrip boundary = faces.get_boundary(); if (boundary.empty()) { err_adv(debug, "PAPER_DOLL::init: region has no boundary"); return false; } Bsurface_list surfs = Bsurface::get_surfaces(faces); if (!are_all_bsurfaces<Panel>(surfs)) { err_adv(debug, "PAPER_DOLL::init: region not all panels"); return 0; } err_adv(debug, "PAPER_DOLL::init: proceeding..."); err_adv(debug, " boundary edges: %d, components: %d, panels: %d", boundary.edges().size(), boundary.num_line_strips(), surfs.num() ); if (get_instance()->build_primitive(faces)) { err_adv(debug, " ... succeeded"); return true; } err_adv(debug, " ... failed"); return false; }
inline bool create_sides( CBface_list& faces, CVertMapper& tmap, CVertMapper& bmap, Primitive* p ) { assert(p && tmap.is_valid() && bmap.is_valid()); Bface_list ret; EdgeStrip boundary = faces.get_boundary(); assert(!boundary.empty()); EdgeStrip top_strip = tmap.a_to_b(boundary); EdgeStrip bot_strip = bmap.a_to_b(boundary); assert(!(top_strip.empty() || bot_strip.empty())); UVpt a, b, c, d; Bedge *top_e, *bot_e; Bface *top_f, *bot_f; Bvert *v1, *v2, *v3, *v4; for (int i = 0; i < top_strip.num(); i++) { top_e = top_strip.edge(i); bot_e = bot_strip.edge(i); top_f = top_e->get_face(); bot_f = bot_e->get_face(); v1 = top_strip.vert(i); v2 = top_e->other_vertex(v1); v3 = bot_strip.vert(i); v4 = bot_e->other_vertex(v3); bool has_uv = UVdata::get_uvs(top_f, a, b, c); if (has_uv) { assert(top_f->is_quad() && bot_f->is_quad()); a = UVdata::get_uv(v1, top_f); b = UVdata::get_uv(v2, top_f); c = UVdata::get_uv(v3, bot_f); d = UVdata::get_uv(v4, bot_f); if (c[0]==0 && d[0]==0) c[0] = d[0] = a[0]+abs((UVdata::get_uv(top_f->other_vertex(v1, v2), top_f))[0]-a[0]); if (top_f->other_vertex(top_f->weak_edge()) == v1) p->add_quad(v1, v3, v4, v2, a, c, d, b); else { assert(top_f->other_vertex(top_f->weak_edge()) == v2); p->add_quad(v3, v4, v2, v1, c, d, b, a); } } else { p->add_quad(v1, v3, v4, v2); } } return true; }
bool Bface_list::push_layer(bool push_boundary) const { // Given a set of faces from a single mesh, mark the // faces as a separate "layer" of the mesh, with // lower priority than the primary, manifold layer: if (!can_push_layer()) { err_msg("Bface_list::push_layer: invalid operation"); return false; } // If the region is already entirely secondary, // our job is done, so report "success": if (is_all_secondary()) return true; // Mark all faces non-primary. // (Bface virtual method sets bit Bface::SECONDARY_BIT; // in Lface it's propagated to lower subdiv levels.) make_secondary(); // XXX - hack; still trying to work out the correct policy... if (push_boundary) { // Distinguish boundary edges by setting their flags to 1 // while all other flags are 0. EdgeStrip bdry = get_boundary(); // pass the word down the subdiv hierarchy // that uv coords are splitting UVdata::split(bdry); // Now visit boundary edges and ensure faces of this list // do not occupy primary _f1 or _f2 slots in each edge. get_edges().clear_flags(); // bdry.edges().filter(InteriorEdgeFilter()).set_flags(); bdry.edges().set_flags(); // See inlined demote() above for (Bface_list::size_type i=0; i<size(); i++) demote(at(i)); } // Notify mesh to rebuild tri-strips, check topology etc. assert(mesh()); mesh()->changed(); return true; }
EdgeStrip Bface_list::get_boundary() const { // Returns the boundary of this set of faces. // I.e., returns an edge strip describing chains of edges // that wind CCW around the faces in this list. // Mark internal faces with flag = 1, // neighboring faces outside the list with flag = 0: mark_faces(); EdgeStrip ret; ret.build_ccw_boundaries(get_edges(), SimplexFlagFilter(1)); return ret; }
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])); } }
int ProxySurface::grow_proxy_surface() { assert(_proxy_mesh); int n = 0; //number of edges that will be grown // Get the boundary of the current proxy surface EdgeStrip boundary = _proxy_mesh->faces().get_boundary(); //cerr << "ProxySurface::grow_proxy_surface " << boundary.num() << " total "<< endl; for(int i=0; i < boundary.num(); ++i) { //cerr << "ProxySurface::grow_proxy_surface now: " << i << endl; if(is_inside_bounding_box(boundary.edge(i))){ grow_quad_from_edge(_proxy_mesh, &boundary, i); _proxy_mesh->changed(); n++; } } return n; }
bool Bface_list::unpush_layer(bool unpush_boundary) const { // Given a set of faces from a single mesh, // restore the faces to "primary" status. if (!can_unpush_layer()) { err_msg("Bface_list::unpush_layer: invalid operation"); return false; } // If the region is already entirely primary, // our job is done, so report "success": if (is_all_primary()) return true; // Mark all faces primary // (virtual method propagates change to lower subdiv levels) make_primary(); if (unpush_boundary) { // Ensure all edge flags are clear except the boundary ones. EdgeStrip bdry = get_boundary(); get_edges().clear_flags(); bdry.edges().set_flags(); // See inlined promote() above for (Bface_list::size_type i=0; i<size(); i++) promote(at(i)); } // Notify mesh to rebuild tri-strips, check topology etc. assert(mesh()); mesh()->changed(); return true; }
inline void add_to_strip(Bvert* v, CEdgeStrip& source, EdgeStrip& ret) { assert(v); CBvert_list& verts = source.verts(); CBedge_list& edges = source.edges(); int k = verts.get_index(v); assert(verts.valid_index(k) && edges[k]->flag()); while (verts.valid_index(k) && edges[k]->flag()) { edges[k]->clear_flag(); ret.add(verts[k], edges[k]); if (source.has_break(k+1)) { k = verts.get_index(source.next_vert(k)); } else { k++; } } }
inline Bedge_list quad_cell_end_edges(PCell* cell) { // if the cell is a quad (4 sides) and has one neigbhor, // return the side opposite from the neighbor. assert(cell && cell->num_corners() == 4); PCell_list nbrs = cell->nbrs(); if (nbrs.size() != 1) { err_adv(debug, "quad_cell_end_edges: neighbors: %d != 1", nbrs.size()); return Bedge_list(); } // find an edge of the shared boundary. // do it now before messing with flags... assert(!cell->shared_boundary(nbrs[0]).empty()); Bedge* e = cell->shared_boundary(nbrs[0]).front(); assert(e); EdgeStrip boundary = cell->get_boundary(); assert(boundary.num_line_strips() == 1); // iterate around the boundary, setting edge flags to value // k that is incremented whenever we pass a cell corner. int k = 0; PCellCornerVertFilter filter; for (int i=0; i<boundary.num(); i++) { if (filter.accept(boundary.vert(i))) k = (k + 1)%4; boundary.edge(i)->set_flag(k); } // we want the edges with flag == k + 2 mod 4 return boundary.edges().filter( SimplexFlagFilter((e->flag() + 2)%4) ); }