コード例 #1
0
ファイル: circle_widget.C プロジェクト: Benignoperez/jot-lib
bool
CIRCLE_WIDGET::finish_literal(void)
{
   MULTI_CMDptr cmd = new MULTI_CMD;

   // Get a mesh to put the new curve into.
   LMESHptr mesh = TEXBODY::get_skel_mesh(cmd);
   assert(mesh != 0);

   Wplane P = get_draw_plane(_literal_shape);

   int res_level = 3;
   int num_edges = 4; // XXX - default is 4 edges; should be smarter:
   // Create the curve

   Bcurve* curve = BcurveAction::create(
      mesh, _literal_shape, P.normal(), num_edges, res_level, 0, 0, cmd
      );
   curve->mesh()->update_subdivision(res_level);

   // If the curve completes a closed loop (on its own or by
   // joining existing curves), fill the interior with a
   // "panel" surface:
   PanelAction::create(curve->extend_boundaries(), cmd);
   WORLD::add_command(cmd);
   return true;
}
コード例 #2
0
ファイル: circle_widget.C プロジェクト: Benignoperez/jot-lib
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;
}
コード例 #3
0
ファイル: draw_manip.C プロジェクト: ArnaudGastinel/jot-lib
//! Find a plane associated with the Bcurve; return a
//! parallel plane that contains the given point p.  
//! To be used for translating the curve in the plane.
inline Wplane
find_xlate_plane(Bcurve* c, CWpt& p)
{

   Wplane P = find_plane(c);
   if (P.is_valid())
      return Wplane(p, P.normal());
   return Wplane();
}
コード例 #4
0
ファイル: circle_widget.C プロジェクト: Benignoperez/jot-lib
bool
CIRCLE_WIDGET::create_literal(GESTUREptr gest)
{
   PIXEL hit_start, hit_end;
   Bpoint* b1 = Bpoint::hit_point(gest->start(), 8, hit_start);
   Bpoint* b2 = Bpoint::hit_point(gest->end(),   8, hit_end);

   // Find a plane to project the stroke into, but only
   // accept planes that are sufficiently parallel to the
   // film plane.
   Wplane P = get_plane(b1, b2);
   if (!P.is_valid()) {
      b1 = b2 = 0;
      // Ignoring the endpoints, try for a plane from the FLOOR
      // or AxisWidget:
      P = get_draw_plane(gest->pts());
      if (!P.is_valid()) {
         return false;
      }
   }

   // Project pixel trail to the plane, and if the gesture
   // is "closed", make the Wpt_list form a closed loop.
   //DrawPen::project_to_plane(gest, P, _literal_shape);
   _literal_shape.clear();

   gest->pts().project_to_plane(P, _literal_shape);

   if (gest->is_closed()) {
      // If closed, remove the final few points to prevent jagginess
      for (int i = _literal_shape.num()-1;i>=0;i--)
         if (PIXEL(_literal_shape[0]).dist(PIXEL(_literal_shape[i])) < 15)
            _literal_shape.remove(i);
         else
            break;

      // add the first point as the last point
      _literal_shape += _literal_shape[0];

      _literal_shape.update_length();
   }
   return true;
}
コード例 #5
0
ファイル: paper_doll.cpp プロジェクト: QuLogic/jot-lib
bool 
PAPER_DOLL::init(CBcurve_list& contour)
{
   if (contour.empty()) {
      err_adv(debug, "PAPER_DOLL::init: empty contour");
      return false;
   }
   LMESHptr skel_mesh = contour.mesh();
   if (!skel_mesh) {
      err_adv(debug, "PAPER_DOLL::init: curves don't share a mesh");
      return false;
   }
   if (!contour.is_each_straight()) {
      err_adv(debug, "PAPER_DOLL::init: curves not straight");
      return false;
   }
   if (!contour.forms_closed_chain()) {
      err_adv(debug, "PAPER_DOLL::init: curves don't form a closed chain");
      return false;
   }
   if (!contour.is_planar()) {
      err_adv(debug, "PAPER_DOLL::init: curves not planar");
      return false;
   }
   Wpt_list pts = contour.get_chain().get_verts().pts();
   if (!(pts.size() == 4 || pts.size() == 5)) {
      err_adv(debug, "PAPER_DOLL::init: can't do %d-gon", pts.size());
      return false;
   }

   Wplane P;
   if (!pts.get_plane(P)) {
      err_adv(debug, "PAPER_DOLL::init: can't get plane from contour");
      return false;
   }
   assert(P.is_valid());
   Wpt  o = pts.average();
   Wvec n = P.normal();

   // make plane normal point toward camera
   if (VIEW::eye_vec(o) * n > 0)
      n = -n;

   // reverse order of points if needed so they go CCW
   // around plane normal:
   err_adv(debug, "contour winding number: %f", pts.winding_number(o, n));
   if (pts.winding_number(o, n) > 1) {
      std::reverse(pts.begin(), pts.end());
   }

   // create the primitive
   MULTI_CMDptr cmd = make_shared<MULTI_CMD>();
   Primitive* p = Primitive::init(skel_mesh, pts, P.normal(), cmd);
   if (!p) {
      err_adv(debug, "PAPER_DOLL::init: Primitive::init() failed");
      return false;
   }

   // hide the curves
   // take over drawing the primitive (?)
   //   or just augment
   // activate

   delete_all(contour);

   get_instance()->init(p);

   err_adv(debug, "PAPER_DOLL::init: curves okay");
   return true;
}
コード例 #6
0
ファイル: circle_widget.C プロジェクト: Benignoperez/jot-lib
//! Returns true if the gesture is valid for beginning a circle_widget
//! session.
bool
CIRCLE_WIDGET::init(CGESTUREptr&  gest)
{

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

   err_adv(debug, "CIRCLE_WIDGET::init");

   // Get the ellipse description:
   PIXEL center;  // the center
   VEXEL axis;    // the long axis (unit length)
   double r1, r2; // the long and short radii, respectively
   bool suggest_active;

   if (!gest->is_ellipse(center, axis, r1, r2)) {
      if (!gest->is_almost_ellipse(center, axis, r1, r2)) {
         return 0;
      } else {
         suggest_active = true;
      }
   } else {
      suggest_active = false;
   }

   Wplane plane = get_draw_plane(center);
   if (!plane.is_valid()) {
      // didn't work out this time
      return false;
   }

   ///////////////////////////////////////////////////////
   //
   //            y1
   //
   //    x0       c ------> x1
   //                axis
   //            y0
   //
   //  Project the extreme points of the ellipse to the
   //  plane and check that after projection they are
   //  reasonably equidistant from the center.
   //
   //  I.e., the ellipse should reasonably match the
   //  foreshortened circle as it would actually appear in
   //  the given plane.
   ///////////////////////////////////////////////////////
   VEXEL perp = axis.perpend();
   Wpt x0 = Wpt(plane, Wline(XYpt(center - axis*r1)));
   Wpt x1 = Wpt(plane, Wline(XYpt(center + axis*r1)));
   Wpt y0 = Wpt(plane, Wline(XYpt(center - perp*r2)));
   Wpt y1 = Wpt(plane, Wline(XYpt(center + perp*r2)));

   Wpt c = Wpt(plane, Wline(XYpt(center)));

   // The two diameters -- we'll check their ratio
   double dx = x0.dist(x1);
   double dy = y0.dist(y1);

   // XXX - Use environment variable for testing phase:
   // XXX - don't make static (see below):
   double MIN_RATIO = Config::get_var_dbl("EPC_RATIO", 0.85,true);

   // Be more lenient when the plane is more foreshortened:
   //
   // XXX - not sure what the right policy is, but for a
   // completely edge-on plane there's certainly no sense in
   // doing a real projection... the following drops the
   // min_ratio lower for more foreshortened planes:
   double cos_theta = VIEW::eye_vec(c) * plane.normal();
   double scale = sqrt(fabs(cos_theta)); // XXX - just trying this out
   MIN_RATIO *= scale;  // XXX - this is why it can't be static
   double ratio = min(dx,dy)/max(dx,dy);
   err_adv(debug, "CIRCLE_WIDGET::init: projected ratio: %f, min: %f",
           ratio, MIN_RATIO);
   if (ratio < MIN_RATIO)
      return false;

   CIRCLE_WIDGETptr me = get_instance();

   static const int DISK_RES = Config::get_var_int("DISK_RES", 4,true);
   me->_plane = plane;
   me->_radius = dx/2;
   me->_disk_res = DISK_RES;

   me->_center = c;

   me->_init_stamp = VIEW::stamp();
   if( me->_suggest_active = suggest_active ) {
      me->create_literal(gest);
   }
   //PIXEL gest_center = gest->center();

   me->make_preview();

   return go();
}