Exemple #1
0
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;

}
Exemple #2
0
int
CIRCLE_WIDGET::tap_cb(CGESTUREptr& g, DrawState*& s)
{
   err_adv(debug_all, "CIRCLE_WIDGET::tap_cb()");
   PIXEL pdummy;
   int idummy;

   if( _suggest_active ) {
      _preview.update_length();
      _literal_shape.update_length();
      double preview_dist = PIXEL_list(_preview).closest( PIXEL(g->start()), pdummy, idummy );
      double literal_dist = PIXEL_list(_literal_shape).closest( PIXEL(g->start()), pdummy, idummy );
      if( preview_dist < literal_dist && preview_dist < PIXEL_DIST_THRESH ) {
         _suggest_active = false;
         make_preview();
         return 1;
      } else if( literal_dist < preview_dist && literal_dist < PIXEL_DIST_THRESH ) {
         finish_literal();
         return cancel_cb(g,s);
      } else {
         return cancel_cb(g,s);
      }
   }

   if (_cmd)
      WORLD::add_command(_cmd);

   return cancel_cb(g,s);
}
Exemple #3
0
//! 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
SELECT_WIDGET::tap_cb(CGESTUREptr& g, DrawState*& s)
{
   err_adv(debug, "SELECT_WIDGET::tap_cb()");

   assert(g && g->is_tap());


   if (_mode==SLASH_SEL)
   {
	   //pattern editing
		Bface* f = find_face(g->start(),0.25,MIN_PIX_AREA);
		if (f) {
			if (select_list.contains(f)||select_list.contains(f->quad_partner()))
			{
	
				//get whichever part of the quad is in the selection list
				int temp = select_list.contains(f) ? select_list.get_index(f)+1 : select_list.get_index(f->quad_partner())+1 ;


				if (temp>end_face) //user selected the end face
				{
					end_face=temp;
				}
				else //user is selecting a pattern
				{
					if (pattern<temp)
						pattern=temp;

					//select/deselect face
					if (temp < MAX_PATTERN_SIZE)
					pattern_array[temp]=!pattern_array[temp];

				}
				return 1;
			}
			else
				cerr << "tap found a NULL face !" << endl;
		}

		return cancel_cb(g,s);


   }
   else
   {
   // Tap a selected face near the middle to deselect it:
	if (try_deselect_face(g->center(), 0.25))
		  return 1;

   // Tap edge to deselect
	if (try_deselect_edge(g->center()))
		  return 1;

   }
   // Otherwise, turn off SELECT_WIDGET
   
   return cancel_cb(g,s);
}
Exemple #5
0
//! Given a set of enclosed face, activate the widget to sweep out a
//! shape. Checks for errors, returns true on success.
bool
SWEEP_DISK::setup(CGESTUREptr& gest, double dur)
{

   static bool debug =
      Config::get_var_bool("DEBUG_SWEEP_SETUP",false) || debug_all;

   if (!(gest && gest->is_dslash())) {
      err_adv(debug, "SWEEP_DISK::setup: bad gesture");
      return false;
   }

   // XXX - shouldn't require it is a Panel:
   Panel* p = dynamic_cast<Panel*>(Bsurface::hit_ctrl_surface(gest->start()));
   if (!p) {
      err_adv(debug, "SWEEP_DISK::setup: non-panel");
      return false;
   }

   Bface_list faces = p->bfaces();

   _boundary = faces.get_boundary();
   if (_boundary.num_line_strips() != 1) {
      err_adv(debug, "SWEEP_DISK::setup: error: boundary is not a single piece");
      return false;
   }

   // Get the best-fit plane, rejecting if the boundary Wpt_list
   // doesn't lie within 0.1 of its total length from the plane:
   if (!_boundary.verts().pts().get_plane(_plane, 0.1)) {
      err_adv(debug,"SWEEP_DISK::setup: Error: can't find plane");
      return false;
   }
   
   // Find the center
   Wpt o = _boundary.verts().pts().average();

   // decide guideline direction (normal to plane):
   Wvec n = _plane.normal();
   if (VIEW::eye_vec(o) * n > 0)
      n = -n;

   // decide the length for the guideline:
   double len = world_length(o, GUIDE_LEN);

   // compute guideline endpoint:
   Wpt b = o + n.normalized()*len;

   // try basic setup
   if (!SWEEP_BASE::setup(dynamic_pointer_cast<LMESH>(faces.mesh()), o, b, dur))
      return false;

   // ******** From here on we accept it ********

   _enclosed_faces = faces;

   return true;
}
int
SELECT_WIDGET::stroke_cb(CGESTUREptr& g, DrawState*&)
{
   assert(g);

   select_faces(g->pts()) || select_edges(g->pts());

   return 1;
}
int
SELECT_WIDGET::sm_circle_cb(CGESTUREptr& g, DrawState*& s)
{
   err_adv(debug, "SELECT_WIDGET::sm_circle_cb()");

   try_select_face(g->center(), 0.25) || try_select_edge(g->center());

   return 1;
}
Exemple #8
0
int
XformPen::tap_cb(CGESTUREptr& tap, DrawState*& s)
{
   assert(tap);
   if (tap->is_double_tap()) {
      // should never happen given order of arcs in XformPen constructor
      cerr << "XformPen::tap_cb: error: gesture is double tap"
           << endl;
      return 0;
   }

   // tap on cursor?
   BMESHray ray(tap->center());
   _view->intersect(ray);
   Cursor3D* c = Cursor3D::upcast(ray.geom());
   if (c) {
      err_adv(debug, "XformPen::tap_cb: hit axis");
      c->handle_gesture(tap);
      return 0;
   }

   // tap on mesh?
   _mesh = 0;
   Bface* f = cur_face();
   if (!f) {
      err_adv(debug, "XformPen::tap_cb: missed face");
      return cancel_cb(tap, s);
   }
   BMESH* m = f->mesh();
   if (!m) {
      err_adv(debug, "XformPen::tap_cb: hit face, no mesh");
      return cancel_cb(tap, s);
   }
   GEOMptr g = bmesh_to_geom(m);
   if (!g) {
      err_adv(debug, "XformPen::tap_cb: hit mesh, no geom");
      return cancel_cb(tap, s);
   }
   // skip floor:
   if (FLOOR::isa(g)) {
      err_adv(debug, "XformPen::tap_cb: hit floor, skipping...");
      return cancel_cb(tap, s);
   }

   // tap on ordinary mesh (not floor):
   _mesh = m;
   assert(_mesh);
   BMESH::set_focus(_mesh, f->patch());
   FLOOR::show();
   FLOOR::realign(_mesh,0); // 0 = no undo command

   Cursor3D::attach(g);

   return 0;
}
Exemple #9
0
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...
}
Exemple #10
0
bool 
PAPER_DOLL::init(CGESTUREptr& g)
{
   if (!(g && g->is_stroke()))
      return false;

   if (g->below_min_length() || g->below_min_spread())
      return false;

   if (!g->is_ellipse()) {
      err_adv(debug, "PAPER_DOLL::init: non-ellipse");
      return false;
   }
   Panel* p = dynamic_cast<Panel*>(
      Bsurface::get_surface(get_top_level(VisRefImage::get_faces(g->pts())))
      );
   err_adv(debug, "PAPER_DOLL::init: %s panel", p?"found":"could not find");
   if (!(p && p->is_selected())) {
      err_adv(debug, "PAPER_DOLL::init: ellipse not over selected panel");
      return false;
   }
   assert(p && p->bfaces().size() > 0);
   Bface_list faces = Bface_list::reachable_faces(p->bfaces().front());
   assert(!faces.empty());
   if (!faces.is_planar(deg2rad(1.0))) {
      err_adv(debug, "PAPER_DOLL::init: region is not planar");
      return false;
   }

   EdgeStrip boundary = faces.get_boundary();
   if (boundary.empty()) {
      err_adv(debug, "PAPER_DOLL::init: region has no boundary");
      return false;
   }

   Bsurface_list surfs = Bsurface::get_surfaces(faces);
   if (!are_all_bsurfaces<Panel>(surfs)) {
      err_adv(debug, "PAPER_DOLL::init: region not all panels");
      return 0;
   }

   err_adv(debug, "PAPER_DOLL::init: proceeding...");

   err_adv(debug, "  boundary edges: %d, components: %d, panels: %d",
           boundary.edges().size(), boundary.num_line_strips(), surfs.num()
      );

   if (get_instance()->build_primitive(faces)) {
      err_adv(debug, "  ... succeeded");
      return true;
   }
   err_adv(debug, "  ... failed");
   return false;
}
//! Currently checks to see that the gesture was a small circle.
//! If so, this may be an indication that the user wants to go 
//! into edge selection mode. It then executes try_select_edge() 
//! to try to find the edge. When successful, the widget enters 
//! edge selection mode.
bool 
SELECT_WIDGET::init_select_edge(CGESTUREptr& g)
{
   if (!g->is_small_circle())
      return false;
   if (!try_select_edge(g->center()))
      return false;
   _mode = SEL_EDGE;
   reset_timeout();
   activate();
   return true;
}
Exemple #12
0
void  
Pen::notify_gesture(GEST_INT* gi, CGESTUREptr& gest)
{
   if (Config::get_var_bool("DEBUG_GESTURES",false)) {
      gest->print_stats();
      gest->print_types();
   }

   _fsa.handle_event(gest);

   if (_fsa.is_reset())
      gi->reset();
}
Exemple #13
0
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;
}
Exemple #14
0
bool
OVERSKETCH::find_matching_sil(CGESTUREptr& g)
{
   err_adv(debug, "OVERSKETCH::find_matching_sil");

   const size_t MIN_GEST_PTS = 10;
   if (!(g && g->pts().size() >= MIN_GEST_PTS))
      return false;

   if (BMESH::_freeze_sils)
      return false;

   VisRefImage *vis_ref = VisRefImage::lookup(VIEW::peek());
   if (!vis_ref)
      return false;

   // 1. see if the gesture runs along a silhouette
   //    of a single mesh.

   SilEdgeFilter sil_filter;
   const  PIXEL_list& pts = g->pts();
   BMESHptr mesh = nullptr;
   for (PIXEL_list::size_type i=0; i<pts.size(); i++) {
      Bedge* e = (Bedge*)
         vis_ref->find_near_simplex(pts[i], SIL_SEARCH_RAD, sil_filter);
      if (!(e && e->mesh())) {
         err_adv(debug, "   gesture too far from silhouette");
         return false;
      }
      if (mesh && mesh != e->mesh()) {
         err_adv(debug, "   found a second mesh, rejecting");
         return false;
      }
      mesh = e->mesh();
   }
   if (!dynamic_pointer_cast<LMESH>(mesh)) {
      err_adv(debug, "   found non-LMESH, rejecting");
      return false;
   }

   err_adv(debug, "   gesture aligns with silhouette");
   err_adv(debug, "   mesh level %d", mesh->subdiv_level());

   // 2. extract the portion of the silhouette that matches
   //    the gesture, store in _selected_sils

   return find_matching_sil(pts, mesh->sil_strip());
}
Exemple #15
0
bool 
OVERSKETCH::init(CGESTUREptr& g)
{
   if (!(g && g->is_stroke()))
      return false;

   if (g->below_min_length() || g->below_min_spread())
      return false;

   if (get_instance()->find_matching_sil(g))
      return true;

   // add more cases here...

   return false;
}
Exemple #16
0
int
NPRPen::tap_cb(CGESTUREptr& gest, DrawState*&)
{
   cerr << "NPRPen::tap_cb" << endl;

   Bface *f = VisRefImage::Intersect(gest->center());
   Patch* p = get_ctrl_patch(f);
   if (!(f && p)) {
      if (_curr_npr_tex)
         deselect_current_texture();
      return 0;
   }

   // Set the selected face's patch to using NPRTexture
   // It might already be doing this, but who cares!
   p->set_texture(NPRTexture::static_name());

   GTexture* cur_texture = p->cur_tex();
   NPRTexture* nt = dynamic_cast<NPRTexture*>(cur_texture);
   if (nt == nullptr)
      return 0; //Shouldn't happen

   if (_curr_npr_tex)
      {
         if (_curr_npr_tex != nt)
            {
               deselect_current_texture();
               select_current_texture(nt);
            }
      }
   else
      select_current_texture(nt);

   return 0;
}
Exemple #17
0
int
SWEEP_BASE::trim_line_cb(CGESTUREptr& g, DrawState*&)
{
   // Activity occurred to extend the deadline for fading away:
   reset_timeout();

   // A slash gesture across the guideline trims its tip

   static bool debug =
      Config::get_var_bool("DEBUG_SWEEP_TRIM",false) || debug_all;

   err_adv(debug, "SWEEP_BASE::trim_cb");

   // Find where the slash intersects the guideline.
   PIXEL p;
   if (g->endpt_line().intersect_segs(pix_line(), p)) {

      // Reset the endpoint to match screen position p:
      reset_endpoint(p);

      return 1;
   }

   // The slash gesture missed the guideline...
   // XXX - policy on failure?

   err_adv(debug, "SWEEP_BASE::trim_line_cb: Missed the guideline");

   return 1; // This means we DID use up the gesture
}
Exemple #18
0
bool
PatternPen::compute_target_cell(CGESTUREptr& gest){
   if (_target_cell) {
      print_target_cell();
   }

   int nb_pts = gest->pts().num();
   if (nb_pts < 2) return false;
  
   if (_current_cell_type == BBOX_CELL){
      _target_cell = new BBoxCell(gest->pts()[0], gest->pts()[nb_pts-1]);
   } else if (_current_cell_type == RECT_CELL){
      double thickness;
      GESTUREptr axis_gesture;
      update_rect_drawer(gest, axis_gesture, thickness);
      if (axis_gesture) {
         _target_cell = new RectCell(axis_gesture, thickness);
      } else {
         return false;
      }
   } else if (_current_cell_type == PATH_CELL){
      double thickness;
      GESTUREptr axis_gesture;
      update_path_drawer(gest, axis_gesture, thickness);
      if (axis_gesture) {
         _target_cell = new PathCell(axis_gesture, thickness);
      } else {
         return false;
      }
   } else if (_current_cell_type == CARRIER_CELL){
      GESTUREptr first_gesture;
      GESTUREptr second_gesture;
      update_carrier_drawer(gest, first_gesture, second_gesture);
      if (first_gesture) {
         _target_cell = new CarriersCell(first_gesture, second_gesture);
      } else {
         return false;
      }
   } else {
      return false;    
   }

   _target_cell->set_global_scale(_current_global_scale);
   return true;
}
Exemple #19
0
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);
}
Exemple #20
0
int  
OVERSKETCH::stroke_cb(CGESTUREptr& gest, DrawState*& s)
{
   err_adv(debug, "OVERSKETCH::stroke_cb");
   assert(gest);

   try_oversketch(gest->pts());

   return 1; // This means we did use up the gesture
}
Exemple #21
0
int
INFLATE::tap_cb(CGESTUREptr& gest, DrawState*& state)
{
   err_adv(debug, "INFLATE::tap_cb");

   // Tracks if the tap was near a guideline
   bool near_guidelines = false;

   PIXEL pdummy;
   int idummy;
   if ( PIXEL_list(_lines).closest( PIXEL(gest->start()), pdummy, idummy ) < 5 )
      near_guidelines = true;

   // Check if gesture hits a BFace
   Bface* face = 0;
   Bsurface::hit_ctrl_surface(gest->start(), 1, &face);

   // Fail if Gesture missed guidelines and geometry
   if ( !face && !near_guidelines )
      return cancel_cb(gest,state);

   // Check that we are trying to inflate
   if ( _orig_face ) {

      // Find the reachable faces from the starting point
      Bface_list set
         = _mode ? _faces : Bface_list::reachable_faces(_orig_face);

      // verify that the user tapped a face that is part of the inflation region
      if ( face && !set.contains( face ) ) {
         return cancel_cb(gest,state);
      }

      // Attempt to inflate the surface
      INFLATE_CMDptr cmd = _mode ? (new INFLATE_CMD( _faces, _preview_dist )) :
         (new INFLATE_CMD( _orig_face, _preview_dist ));
      WORLD::add_command(cmd);
   }

   // On fail, cancel
   return cancel_cb(gest,state);
}
Exemple #22
0
///////////////////
// Proxy methods
///////////////////
void 
PatternPen::add_stroke_to_proxy(CGESTUREptr& gest)
{
   if (gest->pts().num() < 2) {
      WORLD::message("Failed to generate hatch stroke (too few samples)...");
      return;
   }
   //NDCpt_list ndcpts = gest->pts();
   //if (_pattern_texture)
   //_pattern_texture->proxy_surface()->add(
   //   gest->pts(),gest->pressures(), _gesture_drawer->base_stroke_proto());
}
Exemple #23
0
//! 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);
}
Exemple #24
0
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;
}
Exemple #25
0
//! 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
}
Exemple #26
0
int
PatternPen::tap_cb(CGESTUREptr& gest, DrawState*& s){
//   err_msg("PatternPen::tap_cb()");
   if (_mode == PROXY){
      Bface* f;
      f = VisRefImage::Intersect(gest->center());
      if(f)
         init_proxy(f);
   } else {
      return stroke_cb(gest, s);  
   }
   return 1;
}
Exemple #27
0
void
PatternPen::update_path_drawer(CGESTUREptr& gest, GESTUREptr& axis_gesture, double& thickness){
   if (_path_gesture){
      thickness = gest->endpoint_dist();
      axis_gesture = new GESTURE(*_path_gesture);

      _path_gesture = GESTUREptr();
   } else {
      _path_gesture = new GESTURE(*gest);
      _path_gesture->set_drawer(_blank_gesture_drawer);
   }

   _path_gesture_drawer->set_path(_path_gesture);
}
Exemple #28
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);
}
Exemple #29
0
bool
SWEEP_BASE::from_center(CGESTUREptr& g) const
{
   assert(g != nullptr);
   return g->start().dist(sweep_origin()) < DIST_THRESH_PIXELS;
}
Exemple #30
0
//! 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);
}