bool SELECT_WIDGET::select_faces(CPIXEL_list& pts) { err_adv(debug, "SELECT_WIDGET::select_faces:"); if (pts.num() < 2) { err_adv(debug, " too few points: %d", pts.num()); return false; } Bface* f = find_face(pts[0], 0.25, MIN_PIX_AREA); if (!(f && f->is_selected())) { err_adv(debug, " bad starter face"); return false; } // // XXX - Old code (to be deleted). Selects faces individually instead of as // // a group: // for (int i=0; i<pts.num(); i++) // try_select_face(pts[i], 0.1); Bface_list flist; for(int i = 0; i < pts.num(); ++i){ f = find_face(pts[i], 0.1, MIN_PIX_AREA); if (!f || f->is_selected()) continue; flist += f; } if(flist.num() > 0){ WORLD::add_command(new MESH_SELECT_CMD(flist)); err_adv(debug, " succeeded"); return true; } err_adv(debug, " no faces selected"); return false; }
//! Same as try_select_face(), but deselects. //! Also requires the found face is currently selected. bool SELECT_WIDGET::try_deselect_face(CPIXEL &pix, double margin) { Bface* f = find_face(pix, margin, MIN_PIX_AREA); if (!(f && f->is_selected())) return false; WORLD::add_command(new MESH_DESELECT_CMD(f)); return true; }
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; }