// 2 // 3|_|1 // 0 Bface* ProxySurface::neighbor_face(int dir, Bface* face) { UVpt base_uv = baseUVpt(face); UVpt uv1, uv2, uv3, uv4; switch (dir) { case 0: uv1 = UVpt(base_uv[0], base_uv[1]); uv2 = UVpt(base_uv[0]+1, base_uv[1]); uv3 = UVpt(base_uv[0], base_uv[1]-1); uv4 = UVpt(base_uv[0]+1, base_uv[1]-1); break; case 1: uv1 = UVpt(base_uv[0]+1, base_uv[1]); uv2 = UVpt(base_uv[0]+2, base_uv[1]); uv3 = UVpt(base_uv[0]+1, base_uv[1]+1); uv4 = UVpt(base_uv[0]+2, base_uv[1]+1); break; case 2: uv1 = UVpt(base_uv[0], base_uv[1]+1); uv2 = UVpt(base_uv[0]+1, base_uv[1]+1); uv3 = UVpt(base_uv[0], base_uv[1]+2); uv4 = UVpt(base_uv[0]+1, base_uv[1]+2); break; case 3: uv1 = UVpt(base_uv[0]-1, base_uv[1]); uv2 = UVpt(base_uv[0], base_uv[1]); uv3 = UVpt(base_uv[0], base_uv[1]+1); uv4 = UVpt(base_uv[0]-1, base_uv[1]+1); break; default: cerr << "ProxySurface::neighbor_face: invalid diraction" << endl; assert(0); } Bvert* v1 = get_vert_grid(uv1); Bvert* v2 = get_vert_grid(uv2); Bvert* v3 = get_vert_grid(uv3); Bvert* v4 = get_vert_grid(uv4); if(!v1 || !v2 || !v3 || !v4) return 0; Bface* n = lookup_quad(v1, v2, v3, v4); assert(n); assert(n->is_quad()); n = (n->is_quad_rep()) ? n : n->quad_partner(); return n; }
int SELECT_WIDGET:: slash_cb(CGESTUREptr& gest, DrawState*& s) { if (_mode==SEL_FACE) //widget is in face selection mode { select_list.clear(); Bface* f = find_face(gest->start(),0.25,MIN_PIX_AREA); // f should be the currently selected face if (f && f->is_selected() && f->is_quad()) { f=f->quad_rep(); //line in screen space coresponding to the slash PIXELline slash(gest->start(),gest->end()); Bedge *e1,*e2,*e3,*e4; Bedge* edge = 0; //get and test the quad edges against the stroke line f->get_quad_edges(e1,e2,e3,e4); if( e1->pix_line().intersect_segs(slash) ) { edge=e1; } else if( e2->pix_line().intersect_segs(slash) ) { edge=e2; } else if( e3->pix_line().intersect_segs(slash) ) { edge=e3; } else if( e4->pix_line().intersect_segs(slash) ) { edge=e4; } else { //error cerr << "ERROR no intersection" << endl; return 1; } //walk the geometry and select faces Bface* fn = f; do { if (!fn->is_selected()) select_list +=fn; assert(edge); //I'm paranoid too assert(edge->f1()!=edge->f2()); //grabs the face on the other side of the edge //even if we are not directly adjacent to this edge fn=fn->other_quad_face(edge); if (fn) //if a valid face than advance the edge pointer { assert(edge!=fn->opposite_quad_edge(edge)); edge = fn->opposite_quad_edge(edge); fn = fn->quad_rep(); //all faces on the selection list are rep faces } else cerr << "No face on the other side of the edge" << endl; } //quit if not a valid face or not a quad while(fn&&(fn->is_quad())&&edge&&(fn!=f)); _mode=SLASH_SEL; //go into pattern editing mode end_face=0; //prepare the 2nd step data pattern=0; for (int i=0; i<MAX_PATTERN_SIZE; i++) pattern_array[i]=1; //fill the default pattern with ones } else cerr << "This is not a quad" << endl; } else if( _mode==SLASH_SEL)//pattern editing mode { //activates upon second slash motion //adds the entire list to the selected group //undo deselects the entire group Bface_list final_list; //copy the face pointers to the final list //using the pattern as a repeating template //and stop at the end face for (int i = 0; i<(end_face ? (end_face) : select_list.num()) ; i++) { if (pattern ? pattern_array[(i%pattern)+1] : 1) final_list+=select_list[i]; } WORLD::add_command(new MESH_SELECT_CMD(final_list)); return cancel_cb(gest,s); } else cerr << "wrong mode " << endl; return 1; }