Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
void
CIRCLE_WIDGET::make_preview( void )
{
   _preview.clear();

   // Get a coordinate system
   Wvec Z = _plane.normal();
   Wvec X = Z.perpend();
   Wvec Y = cross(Z,X);
   Wtransf xf(_center, X, Y, Z);

   // Make the hi-res circle for the curve's map1d3d:
   const int ORIG_RES = 256;
   _preview.realloc(ORIG_RES + 1);
   double dt = (2*M_PI)/ORIG_RES;
   for (int i=0; i<ORIG_RES; i++) {
      double t = dt*i;
      _preview += xf*Wpt(_radius*cos(t), _radius*sin(t), 0);
   }
   _preview += _preview[0];       // make it closed

   if( _suggest_active ) {
      return;
   }

   if( _circle == 0 ) {
      // XXX - no undo! should fix
      _circle = PanelAction::create(
         _plane, _center, _radius, TEXBODY::get_skel_mesh(0), _disk_res, 0
         );
   } else {
      Bcurve *border = Bcurve::lookup(_circle->bfaces().get_boundary().edges());
      if( border != 0 ) {
         Wpt_listMap *map = Wpt_listMap::upcast(border->map());
         if( map )
            map->set_pts(_preview);
      }
   }

}
Exemplo n.º 4
0
int
DrawManip::move(CEvent &e, State *&s)
{
   if (!_cmd)
      return 0;

   // XXX - needs work, doing plane constraint ATM...
   if (plane().is_valid()) {
      apply_translation(plane().intersect(ptr_ray()) - _down_pt);
      return 0;
   }

   // XXX - need comments...
   CRV_SKETCHptr cs = CRV_SKETCH::get_instance();
   if (cs->is_active() & _down) {
      Bcurve* curve = cs->curve();
      Wpt_listMap* map = cs->shadow_map();
      Wpt pt = Wpt(curve->shadow_plane(), Wline(ptr_cur()));
      if (_first) 
         map->set_p0(new WptMap(pt));
      else
         map->set_p1(new WptMap(pt));
      map->recompute();

      SurfaceCurveMap* o = (SurfaceCurveMap*)curve->map();
      Wpt first = o->map(0), last = o->map(1);
      if (curve->b1()) {
         curve->b1()->move_to(first);
      }
      if (curve->b2()) {
         curve->b2()->move_to(last);
      }

      cs->reset_timeout();

      return 0;
   }

   return 0;
}
Exemplo n.º 5
0
bool
SWEEP_DISK::build_box(CWpt& o, CWvec& t, CWpt_list& spts, MULTI_CMDptr cmd)
{
   // Editing or Creating
   bool is_editing = !(_surfs.empty());

   // get list of Bpoints around the boundary of the base surface:
   ARRAY<Bpoint*> bot_pts = is_editing ? _points.extract(_points.num()/2, _points.num()/2) : 
      Bpoint::get_points(_boundary.verts());  
   assert ( bot_pts.num() > 2 );
   int n = bot_pts.num();
   Bpoint_list top_pts(n);

   // If surface normals of base surface point along the sweep
   // direction, they have to be reversed. otherwise, the
   // boundary runs CW, so we reverse the order of the bottom
   // points to get them to run CCW:
   //
   // XXX - needs fix to work on embedded region, similar to
   //       build_tube() above.

   if ( _plane.normal()*t  < 0 ) {
      if (!is_editing) bot_pts.reverse();
   } else {
      reverse_faces( _enclosed_faces );
      if(cmd)
         cmd->add(make_shared<REVERSE_FACES_CMD>(_enclosed_faces, true));
   }

   double avg_len = _boundary.edges().avg_len();
   if ( isZero(avg_len) ) {
      cerr << "SWEEP_DISK::build_box(): ERROR, boundary avg len is zero" << endl;
      return false;
   }

   int num_edges = max( (int)round( spts.length()/avg_len ), 1 );
   int res_level = Config::get_var_int("BOX_RES_LEVEL", 2,true);

   // we'll keep lists of all curves and surfaces for the box,
   // for setting their res level uniformly:
   Bcurve_list   curves   = Bcurve::get_curves(_boundary.edges());
   Bsurface_list surfaces = Bsurface::get_surfaces(_enclosed_faces);

   if (!surfaces.empty())
      res_level = surfaces.min_res_level();
   else if (!curves.empty())
      res_level = curves.min_res_level();

   curves.clear();
   surfaces.clear();

   // XXX - Zachary: add SWEEP_CMD (BOX_CMD?) here:

   // Create/Edit the top points matching the bottom points
   // and the curves running vertically between them
   int i = 0;
   for ( i=0; i<n; i++ ) {
      Wvec n = (bot_pts[i]->loc() - o).orthogonalized(t).normalized();
      Wvec b = cross(n,t);
      Wpt_list cpts = spts;
      cpts.xform( Wtransf(o, t, b, n) );

      // XXX - should be undoable
      if (is_editing) {
         Wpt_listMap* m = dynamic_cast<Wpt_listMap*>(_curves[i]->map());
         cmd->add(make_shared<WPT_LIST_RESHAPE_CMD>(m,cpts));
      } else {
         top_pts += BpointAction::create(_mesh, cpts.back(), b, n, res_level, cmd);
         curves  += BcurveAction::create(_mesh, cpts, b, num_edges , res_level,
                                 bot_pts[i], top_pts[i], cmd);
      }
   }

   if (!is_editing) {
      // Create curves joining each top point to the next.
      for ( i=0; i<n; i++ ) {
         int j = (i+1) % n;

         Bcurve* c = bot_pts[i]->lookup_curve( bot_pts[j] );
         if ( !c ) {
            cerr << "SWEEP_DISK::build_box(): ERROR, can't find boundary curve"
               << endl;
            continue;
         }

         // Ensure orientation of top and bottom curves is the same.
         int i1 = i;
         int i2 = j;
         if ( c->b1() != bot_pts[i1] ) 
            swap( i1, i2 );
         assert( c->b1() == bot_pts[i1] &&
               c->b2() == bot_pts[i2] );

         // Create the new top curve with the same shape as the bottom curve.
         Wpt_list cpts = c->get_wpts();
         cpts.fix_endpoints( top_pts[i1]->loc(), top_pts[i2]->loc() );
         
         curves += BcurveAction::create(_mesh, cpts, t, c->num_edges(),
                              res_level, top_pts[i1], top_pts[i2], cmd);

         build_coons(bot_pts[i], bot_pts[j], top_pts[j], top_pts[i], surfaces, cmd);
      }

      // Slap on a top if base is quadrilateral
      // XXX - should handle other cases
      if (n == 4)
         build_coons(top_pts[0], top_pts[1], top_pts[2], top_pts[3], surfaces, cmd);
   }

   _mesh->changed();

   // set the res level uniformly over the box:
   for (int i = 0; i < bot_pts.num(); i++)
      bot_pts[i]->set_res_level(res_level);
   top_pts.set_res_level(res_level);
   curves.set_res_level(res_level);
   surfaces.set_res_level(res_level);
   _mesh->update_subdivision(res_level);

   // Record data necessary to return to this mode
   Panel* p = dynamic_cast<Panel*>(Bsurface::get_surface(_enclosed_faces));
   assert(p);
   if (is_editing) {
      vector<Panel*>::iterator it = std::find(panels.begin(), panels.end(), p);
      assert(it != panels.end());
      int loc = it - panels.begin();
      profiles[loc] = _profile;
   } else {
      panels.push_back(p);
      top_pts += bot_pts;
      bpoints.push_back(top_pts);
      bcurves.push_back(curves);
      bsurfaces.push_back(surfaces);
      profiles.push_back(_profile);
   }
   
   //FLOOR::realign(_mesh->cur_mesh(), cmd);

   WORLD::add_command(cmd);

   return true;
}
Exemplo n.º 6
0
UVsurface*
SWEEP_DISK::build_revolve(
   CWpt_list&   apts,
   CWvec&       n,
   CWpt_list&   spts,
   MULTI_CMDptr cmd
   )
{
   static bool debug = Config::get_var_bool("DEBUG_BUILD_REVOLVE");

   // Editing or Creating
   bool is_editing = !(_surfs.empty());

   Bcurve* bcurve = Bcurve::get_curve(_boundary.edges());
   if (!bcurve) {
      err_adv(debug, "SWEEP_DISK::build_revolve: can't find curve");
      return nullptr;
   }
   if (!bcurve->is_control()) {
      err_adv(debug, "SWEEP_DISK::build_revolve: error: non-control curve");
      return nullptr;
   }

   Map1D3D* axis = new Wpt_listMap(apts, new WptMap(apts[0]), new WptMap(apts[1]), n);

   // XXX - Zachary: add SWEEP_CMD here:

   // Create/Edit the surface of revolution
   UVsurface* ret = nullptr;
   Panel* p = dynamic_cast<Panel*>(Bsurface::get_surface(_enclosed_faces));
   assert(p);
   if (is_editing) {
      assert(!_surfs.empty());
      ret = dynamic_cast<UVsurface*>(_surfs[0]);
      assert(ret);

      TubeMap* tmap = dynamic_cast<TubeMap*>(ret->map());
      assert(tmap);

      // reshape the axis
      Wpt_listMap* m = dynamic_cast<Wpt_listMap*>(tmap->axis());
      assert(m);
      WPT_LIST_RESHAPE_CMDptr a_cmd = make_shared<WPT_LIST_RESHAPE_CMD>(m,apts);
      if (a_cmd->doit())
         cmd->add(a_cmd);

      // reshape the top curve
      double s = spts.back()[2]/spts.front()[2];
      Wtransf M = tmap->axis()->F(1) * Wtransf::scaling(0,s,s) * tmap->axis()->Finv(0);
      WPT_LIST_RESHAPE_CMDptr c1_cmd = make_shared<WPT_LIST_RESHAPE_CMD>(((Wpt_listMap*)tmap->c1()), M*((Wpt_listMap*)tmap->c0())->get_wpts());
      if (c1_cmd->doit())
         cmd->add(c1_cmd);

      // reshape the profile
      cmd->add(make_shared<TUBE_MAP_RESHAPE_CMD>(tmap,spts));

      // change the record
      vector<Panel*>::iterator it = std::find(panels.begin(), panels.end(), p);
      assert(it != panels.end());
      int loc = it - panels.begin();
      profiles[loc] = _profile;

   } else {
      // for recording purposes
      Bpoint_list points;
      Bcurve_list curves;
      Bsurface_list surfs;

      ret =
         UVsurface::build_revolve(bcurve, axis, spts, _enclosed_faces, points, curves, surfs, cmd);
      if (ret) {
         //FLOOR::realign(ret->cur_mesh(), cmd);

         panels.push_back(p);
         bpoints.push_back(points);
         bcurves.push_back(curves);
         bsurfaces.push_back(surfs);
         profiles.push_back(_profile);
      }
   }

   WORLD::add_command(cmd);

   return ret;
}
Exemplo n.º 7
0
UVsurface*
SWEEP_DISK::build_revolve(
   CWpt_list&   apts,
   CWvec&       n,
   CWpt_list&   spts,
   MULTI_CMDptr cmd
   )
{
   static bool debug = Config::get_var_bool("DEBUG_BUILD_REVOLVE");

   // Editing or Creating
   bool is_editing = !(_surfs.empty());

   Bcurve* bcurve = Bcurve::get_curve(_boundary.edges());
   if (!bcurve) {
      err_adv(debug, "SWEEP_DISK::build_revolve: can't find curve");
      return 0;
   }
   if (!bcurve->is_control()) {
      err_adv(debug, "SWEEP_DISK::build_revolve: error: non-control curve");
      return 0;
   }

   Map1D3D* axis = new Wpt_listMap(apts, new WptMap(apts[0]), new WptMap(apts[1]), n);

   // XXX - Zachary: add SWEEP_CMD here:

   // Create/Edit the surface of revolution
   UVsurface* ret = NULL;
   Panel* p = Panel::upcast(Bsurface::get_surface(_enclosed_faces));
   assert(p);
   if (is_editing) {
      assert(!_surfs.empty());
      ret = UVsurface::upcast(_surfs[0]);
      assert(ret);

      TubeMap* tmap = TubeMap::upcast(ret->map());
      assert(tmap);

      // reshape the axis
      Wpt_listMap* m = Wpt_listMap::upcast(tmap->axis());
      assert(m);
      WPT_LIST_RESHAPE_CMDptr a_cmd = new WPT_LIST_RESHAPE_CMD(m,apts);
      if (a_cmd->doit())
         cmd->add(a_cmd);

      // reshape the top curve
      double s = spts.last()[2]/spts.first()[2];
      Wtransf M = tmap->axis()->F(1) * Wtransf::scaling(0,s,s) * tmap->axis()->Finv(0);
      WPT_LIST_RESHAPE_CMDptr c1_cmd = new WPT_LIST_RESHAPE_CMD(((Wpt_listMap*)tmap->c1()), M*((Wpt_listMap*)tmap->c0())->get_wpts());
      if (c1_cmd->doit())
         cmd->add(c1_cmd);

      // reshape the profile
      cmd->add(new TUBE_MAP_RESHAPE_CMD(tmap,spts));   

      // change the record
      int loc = panels.get_index(p);
      assert(loc >= 0);
      profiles[loc] = _profile;

   } else {
      // for recording purposes
      Bpoint_list points;
      Bcurve_list curves;
      Bsurface_list surfs;

      ret =
         UVsurface::build_revolve(bcurve, axis, spts, _enclosed_faces, points, curves, surfs, cmd);
      if (ret) {
         //FLOOR::realign(ret->cur_mesh(), cmd);

         panels += p;
         bpoints += points;
         bcurves += curves;
         bsurfaces += surfs;
         profiles += _profile;
      }
   }

   WORLD::add_command(cmd);

   return ret;
}