Exemplo n.º 1
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.º 2
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;
}