static int max_subdiv_edit_level(Bface_list all, Bface_list core=Bface_list()) { // what is the deepest subdiv level that is either: // - controlled by a Bbase // - has holes cut // - has new surface regions attached err_adv(debug, "max_subdiv_edit_level:"); if (all.empty()) { assert(core.empty()); err_adv(debug, " face list is empty"); return 0; } assert(all.mesh() && all.contains_all(core)); int R = 0; // level at which deepest edits happened int k = 0; // current level being examined while (!all.empty()) { k++; all = get_subdiv_faces(all,1); if (all.empty()) break; // check for controllers if (!Bbase::find_owners(all).empty()) { err_adv(debug, " controllers at level %d", k); R = k; } // check for holes at this level: if (all.has_any_secondary()) { all = all.primary_faces(); err_adv(debug, " hole at level %d", k); R = k; // holes exist at this level } // check for new regions if (core.empty()) continue; core = get_subdiv_faces(core,1); Bface_list new_faces = core.two_ring_faces().primary_faces(); // see if any of these new ones are actually new: new_faces.set_flags(1); all.clear_flags(); new_faces = new_faces.filter(SimplexFlagFilter(1)); if (!new_faces.empty()) { all.append(new_faces); err_adv(debug, " new faces at level %d", k); R = k; // new stuff exists at this level } } return R; }
void TriStrip::get_strips( Bface* start, vector<TriStrip*>& strips ) { // if starting face was visited already, stop if (!is_cleared(start)) return; // stack is used to record faces adjacent to // the current strip, in order to build additional // strips that align with the current one static Bface_list stack(1024); stack.clear(); stack.push_back(start); BMESHptr mesh = start->mesh(); while (!stack.empty()) { start = stack.back(); stack.pop_back(); if (is_cleared(start)) { TriStrip* strip = mesh->new_tri_strip(); strip->build(start, stack); strips.push_back(strip); } } }
Skin::Skin( Skin* parent, CBface_list& skel_faces, MULTI_CMDptr cmd) : _skel_faces(skel_faces), _updater(0), _partner(0), _reverse(false) { _inflate = parent->_inflate; err_adv(debug, "Skin::Skin: (child)"); assert(parent && parent->_res_level > 0); set_name(parent->name()); _reverse = parent->_reverse; // assert(!_skel_faces.has_any_secondary()); // Update parent mesh elements to our level. // This also ensures the child patch is created and filled. LMESH::update_subdivision(parent->skin_faces(), 1); err_adv(debug, " updated subdivision at parent"); // Bsurface method: record parent/child relationship mutually. // set _parent = parent and parent->_child = this. // set Patch = child of parent's Patch. // set mesh = child of parent's mesh. // set res level = parent res level - 1. set_parent(parent); err_adv(debug, " set parent"); // Set up our vert mapper, based on the parent: _mapper = subdiv_mapper(parent->_mapper); if (_mapper.is_valid()) err_adv(debug, " set mapper"); else err_adv(debug, " failed to get subdiv mapper"); // Generate verts, edges, faces of the new skin. // But if any already exist, it does not duplicate them. // Also add memes as needed. gen_faces(); err_adv(debug, " generated elements"); Bface_list extras = skin_faces().minus(_mapper.a_to_b(_skel_faces)); if (debug && !extras.empty()) { cerr << "found " << extras.num() << " unexpected faces" << endl; push(extras, cmd); } // finish up: create child or join to skeleton: finish_ctor(cmd); }
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 check(CBface_list& faces) { Bface_list bad; for (int i=0; i<faces.num(); i++) if (is_bad(faces[i])) bad += faces[i]; if (bad.empty()) return true; GtexUtil::show_tris(bad); return false; }