//! Draw a straight line cross-ways to an existing //! straight Bcurve to create a rectangle: bool SWEEP_LINE::create_rect(CGESTUREptr& gest) { static bool debug = Config::get_var_bool("DEBUG_CREATE_RECT",false) || debug_all; err_adv(debug, "SWEEP_LINE::create_rect"); if (!(gest && gest->is_line())) { err_adv(debug, "SWEEP_LINE::create_rect: gesture is not a line"); return false; } // central axis must be on-screen if (!sweep_origin().in_frustum()) { err_adv(debug_all, "SWEEP_LINE::stroke_cb: error: sweep origin off-screen"); return false; } if (!from_center(gest)) { WORLD::message("Stroke must begin on curve at guideline"); return false; } if (!hits_line(gest->end())) { WORLD::message("Line must follow axis"); return false; } // compute vector along guideline, based on input stroke: Wvec v = project_to_guideline(gest->end()) - sweep_origin(); return create_rect(v); }
int CIRCLE_WIDGET::stroke_cb(CGESTUREptr& g, DrawState*&) { err_adv(debug_all, "CIRCLE_WIDGET::stroke_cb()"); // Activity occurred to extend the deadline for fading away: reset_timeout(); // sanity check assert(g); if( !g->is_line() ) return 1; _preview.update_length(); if (PIXEL_list(_preview).dist(g->start()) < PIXEL_DIST_THRESH || g->start().dist(_center) < PIXEL_DIST_THRESH ) { if ( _circle ) { Bcurve *border = Bcurve::lookup(_circle->bfaces().get_boundary().edges()); if ( border != 0 ) { Wplane plane = border->plane(); _radius = _center.dist(Wpt(plane, Wline(XYpt(g->end())))); } } else { Wplane P = get_draw_plane(g->end()); if (!P.is_valid()) return 1; _radius = _center.dist(Wpt(P, Wline(XYpt(g->end())))); } make_preview(); } return 1; }
int TRACE::tap_cb(CGESTUREptr& gest, DrawState*& s) { assert (gest->is_tap()); if (_calib_mode_flag) { // we are in calibration point XYpt sample = gest->end(); _samples[_cur_calib_pt_index] = sample; cerr << "recorded sample " << _cur_calib_pt_index << endl; _cur_calib_pt_index++; /* seems impractical to distort image, leaving this at 2 - alexni if (_cur_calib_pt_index == 4) { */ if (_cur_calib_pt_index == 2) { // if we have sampled four points, we are done with calibration _calib_mode_flag = false; _calibrated = true; WORLD::message("Calibration complete"); } return 1; } else return 0; }
int SWEEP_BASE::line_cb(CGESTUREptr& g, DrawState*& s) { // Activity occurred to extend the deadline for fading away: reset_timeout(); static bool debug = Config::get_var_bool("DEBUG_SWEEP_LINE_CB",false) || debug_all; err_adv(debug, "SWEEP_BASE::line_cb"); // If gesture aligns with guideline: // if it starts near the end and extends past the end, extend // if it starts near the beginning, do uniform sweep // If it's across the gesture, trim // If it's a trim stroke, it has to be short and run // across the guideline. const double TRIM_MAX_LEN = 65; if (g->length() < TRIM_MAX_LEN) { const double TRIM_ANGLE_THRESH = 80; // degrees double angle = line_angle(g->endpt_vec(), pix_line().direction()); if (rad2deg(angle) > TRIM_ANGLE_THRESH) { // Nice angle. But did it cross? if (g->endpt_line().intersect_segs(pix_line())) return trim_line_cb(g, s); } } // do uniform sweep if straight gesture starts at sweep origin // and ends near the guideline: if (from_center(g)) { if (hits_line(g->end())) return do_uniform_sweep(project_to_guideline(g->end()) - sweep_origin()); return stroke_cb(g,s); } // extend the guideline if straight gesture starts near guideline end // and is nearly parallel: const double ALIGN_ANGLE_THRESH = 15; // degrees if (pix_line().endpt().dist(g->start()) < DIST_THRESH_PIXELS && rad2deg(g->endpt_vec().angle(pix_line().direction())) < ALIGN_ANGLE_THRESH) return extend_line_cb(g, s); return stroke_cb(g,s); }
int SWEEP_BASE::tap_cb(CGESTUREptr& g, DrawState*& s) { err_adv(debug_all, "SWEEP_BASE::tap_cb"); // tap near end of guideline: do uniform sweep based // on guideline length: if (g->center().dist(sweep_end()) < DIST_THRESH_PIXELS) return do_uniform_sweep(sweep_vec()); // tap elsewhere on the guideline: do uniform sweep based // on tap location: if (hits_line(g->end())) return do_uniform_sweep(project_to_guideline(g->end()) - sweep_origin()); // tap elsewhere: cancel: return cancel_cb(g,s); }
//! They want to make the guideline longer. //! It's easy. int SWEEP_BASE::extend_line_cb(CGESTUREptr& g, DrawState*&) { static bool debug = Config::get_var_bool("DEBUG_SWEEP_BASE_EXTEND",false) || debug_all; if (debug) err_msg("SWEEP_BASE::extend_line_cb"); reset_endpoint(g->end()); return 1; // This means we DID use up the gesture }
inline Wvec endpt_vec(CGESTUREptr& g, CWplane& P) { return Wpt(P, Wline(g->end())) - Wpt(P, Wline(g->start())); }
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; }