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); } } }
inline void try_append(Bface_list& A, Bface* f) { // Helper method used below in try_append(); if (f && !f->flag()) { f->set_flag(); A.push_back(f); } }
inline Bface_list copy_faces(CBface_list& faces, CVertMapper& vmap, Primitive* p, bool reverse=false) { assert(p && vmap.is_valid()); Bface_list ret; for (Bface_list::size_type i=0; i<faces.size(); i++) { ret.push_back(copy_face(faces[i], vmap, p, reverse)); } copy_edges(faces.get_edges(), vmap); return ret; }
Bface_list Bface_list::quad_complete_faces() const { // If the list contains any "quad" faces but not their partners, // returns the "completed" list, containing the missing partners: mark_faces(); Bface* p=nullptr; Bface_list ret = *this; for (Bface_list::size_type i=0; i<size(); i++) if ((p = check_partner(at(i)))) ret.push_back(p); return ret; }
bool TriStrip::build( Bface* start, // build a new strip starting here. Bface_list& stack // used to build nearby parallel strips ) { // a set flag means this face is already in a TriStrip assert(!start->flag()); // start fresh reset(); // repeat 1st vertex if needed if (!start->orient_strip()) start->orient_strip(start->v1()); // get the starting vert. i.e., the strip will // continue onto the next face across the edge // opposite this vertex. Bvert *a = start->orient_strip(), *b, *c; // squash and stretch start = backup_strip(start,a); if (!start) { // should never happen, but can happen // if there are inconsistently oriented faces err_msg("TriStrip::build: error: backup_strip() failed"); err_msg("*** check mesh for inconsistently oriented faces ***"); return 0; } // claim it claim_face(start); // record direction of strip on 1st face: start->orient_strip(a); // faces alternate CCW / CW if (_orientation) { c = start->next_vert_ccw(a); b = start->next_vert_ccw(c); } else { b = start->next_vert_ccw(a); c = start->next_vert_ccw(b); } add(a,start); add(b,start); add(c,start); Bface* opp; if ((opp = start->opposite_face(b)) && is_cleared(opp) && opp->patch() == start->patch()) { opp->orient_strip(_orientation ? a : c); stack.push_back(opp); } int i=_orientation; Bface* cur = start; while ((cur = cur->next_strip_face()) && !is_claimed(cur)) { claim_face(cur); i++; a = b; b = c; c = cur->other_vertex(a,b); cur->orient_strip(a); if ((opp = cur->opposite_face(b)) && is_cleared(opp) && opp->patch() == start->patch()) { opp->orient_strip(i % 2 ? a : c); stack.push_back(opp); } add(c,cur); } return 1; }