예제 #1
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;
}
예제 #2
0
//! 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();
}