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; }
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; }
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 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) ); }