int INFLATE::stroke_cb(CGESTUREptr& gest, DrawState*& s) { err_adv(debug, "INFLATE::stroke_cb"); reset_timeout(); // Verify that we have a starting face if ( _orig_face ) { Bface* face = 0; // Check that the stroke is straight enough to represent a line if (!(gest->straightness() > 0.8)) { err_adv(debug, "INFLATE::stroke_cb: gesture not straight"); return false; } // Check that the gesture starts on the mesh Bsurface::hit_ctrl_surface(gest->start(), 1, &face); if (!(face)) { err_adv(debug, "INFLATE::stroke_cb: can't get hit face"); return false; } // create VEXELs for the gesture and the face normal VEXEL fvec = VEXEL(face->v1()->loc(), face->norm()); VEXEL fgest = gest->endpt_vec(); // If gesture nearly parallel to normal: double a = rad2deg(line_angle(fvec,fgest)); err_adv(debug, "INFLATE::stroke_cb: angle: %f %s", a, (a > 15) ? "(bad)" : "(good)"); if (a > 15) { // Fail if angle is too extreme WORLD::message("Bad angle"); return 0; } // calculate extrude width double dist = fgest.length()/fvec.length(); err_adv(debug, "INFLATE::stroke_cb: strong_edge_len: %f, gest_len: %f, \ fvect_len: %f", avg_strong_edge_len(face), fgest.length(), fvec.length() ); // Convert to relative to local edge length dist /= avg_strong_edge_len(face); if (fvec*fgest<0) dist=-dist; // Get the sign right // Store the new inflate distance _preview_dist = dist; } return 1; // we used up the gesture... }
int INFLATE::line_cb(CGESTUREptr& gest, DrawState*& s) { // Activity occurred to extend the deadline for fading away: reset_timeout(); err_adv(debug, "INFLATE::line_cb"); // Verify that we have a starting face if ( _orig_face ) { // Check that the stroke is straight enough to represent a line Bface* face = 0; if (!(gest->straightness() > 0.8)) { err_adv(debug, "INFLATE::line_cb: gesture not straight"); return false; } // Check that the gesture starts on the mesh Bsurface::hit_ctrl_surface(gest->start(), 1, &face); if (!(face)) { err_adv(debug, "INFLATE::line_cb: can't get hit face"); return false; } // create VEXELs for the gesture and the face normal VEXEL fvec = VEXEL(face->v1()->loc(), face->norm()); VEXEL fgest = gest->endpt_vec(); // If gesture nearly parallel to normal: double a = rad2deg(line_angle(fvec,fgest)); err_adv(debug, "INFLATE::line_cb: angle: %f %s", a, (a > 15) ? "(bad)" : "(good)"); if (a > 15) { return false; } // calculate extrude width double dist = fgest.length()/fvec.length(); if (fvec*fgest<0) dist=-dist; // Get the sign right _preview_dist = dist; } // get here if nothing happened... // don't cancel (which would deactivate the widget), // just return 1 to indicate that we used up the gesture: return 1; }
//! Given an initial slash gesture (or delayed slash) on a //! defined plane (FLOOR, Cursor3D, or existing Bpoint), set up //! the widget to provide a guideline for drawing a straight line. bool SWEEP_POINT::setup(CGESTUREptr& slash, double dur) { static bool debug = Config::get_var_bool("DEBUG_SWEEP_SETUP",false) || debug_all; err_adv(debug, "SWEEP_POINT::setup"); // check the gesture if (!(slash && slash->straightness() > 0.9)) { err_adv(debug, "SWEEP_POINT::setup: gesture is bad"); return false; } // find the (straight) Bpoint near slash start _point = Bpoint::hit_ctrl_point(slash->start()); return false; // return SWEEP_BASE::setup(_curve->mesh(), o, endpt, dur); }
//! Given an initial slash gesture (or delayed slash) near the //! center of an existing straight Bcurve, set up the widget to //! do a sweep cross-ways to the Bcurve: bool SWEEP_LINE::setup(CGESTUREptr& slash, double dur) { static bool debug = Config::get_var_bool("DEBUG_SWEEP_SETUP",false) || debug_all; err_adv(debug, "SWEEP_LINE::setup"); // check the gesture if (!(slash && slash->straightness() > 0.99)) { err_adv(debug, "SWEEP_LINE::setup: gesture is bad"); return false; } // find the (straight) Bcurve near slash start _curve = Bcurve::hit_ctrl_curve(slash->start()); if (!(_curve && _curve->is_straight())) { err_adv(debug, "SWEEP_LINE::setup: no straight curve at start"); return false; } // find endpoints Bpoint *b1 = _curve->b1(), *b2 = _curve->b2(); assert(b1 && b2); // straight curve must have endpoints // curve cannot be connected to other curves if (b1->vert()->degree() != 1 || b2->vert()->degree() != 1) { err_adv(debug, "SWEEP_LINE::setup: curve is not isolated"); return false; } // ensure the gesture starts near the center of the straight line Bcurve: { PIXEL a = b1->vert()->pix(); PIXEL b = b2->vert()->pix(); double t = (slash->start() - a).tlen(b-a); if (t < 0.35 || t > 0.65) { err_adv(debug, "SWEEP_LINE::setup: gesture not near center of line"); return false; } } // find the plane to work in _plane = check_plane(shared_plane(b1, b2)); if (!_plane.is_valid()) { err_adv(debug, "SWEEP_LINE::setup: no valid plane"); return false; } // check that slash is perpendicular to line Wpt a = b1->loc(); // endpoint at b1 Wpt b = b2->loc(); // endpoint at b2 Wvec t = b - a; // vector from endpt a to endpt b Wpt o = a + t/2; // center of straight line curve Wvec n = cross(_plane.normal(), t); // direction across line ab Wvec slash_vec = endpt_vec(slash, _plane); const double ALIGN_ANGLE_THRESH = 15; double angle = rad2deg(slash_vec.angle(n)); if (angle > 90) { angle = 180 - angle; n = -n; } if (angle > ALIGN_ANGLE_THRESH) { err_adv(debug, "SWEEP_LINE::setup: slash is not perpendicular to line"); err_adv(debug, " angle: %f", angle); return false; } // compute guideline endpoint: Wpt endpt = o + n.normalized()*a.dist(b); return SWEEP_BASE::setup(_curve->mesh(), o, endpt, dur); }