Пример #1
0
inline ARRAY<Wline>
bundle_lines(CWpt_list& a, CWpt_list& b)
{
   assert(a.num() == b.num());
   ARRAY<Wline> ret(a.num());
   for (int i=0; i<a.num(); i++)
      ret += Wline(a[i], b[i]);
   return ret;
}
Пример #2
0
inline double
min_dist(CWpt_list& pts, CWpt_list& path)
{
   if (pts.empty())
      return 0;
   double ret = path.dist(pts[0]);
   for (Wpt_list::size_type i=1; i<pts.size(); i++)
      ret = min(ret, path.dist(pts[i]));
   return ret;
}
Пример #3
0
Wtransf
compute_xf(CWpt_list& p)
{
   Wpt    c = p.average();
   double s = p.spread();

   ARRAY<Wvec> v(p.num());
   for (int i=0; i<p.num(); i++) {
      v += (p[i] - c)/s;
   }
   assert(v.num() == p.num());
   return Wtransf::translation(c) * compute_xf(v) * Wtransf::translation(-c);
}
Пример #4
0
Wtransf
compute_xf(CWpt_list& p)
{
   Wpt    c = p.average();
   double s = p.spread();

   vector<Wvec> v(p.size());
   for (Wpt_list::size_type i=0; i<p.size(); i++) {
      v[i] = (p[i] - c)/s;
   }
   assert(v.size() == p.size());
   return Wtransf::translation(c) * compute_xf(v) * Wtransf::translation(-c);
}
Пример #5
0
//! Project Wpt_list to PIXELs and compute length:
//! If projection fails return -1.
inline double
pix_len(CWpt_list& pts)
{

   PIXEL_list pix;
   return pts.project(pix) ? pix.length() : -1;
}
Пример #6
0
GELptr 
WORLD::show_pts(
   CWpt_list& pts, double width, CCOLOR& col, double alpha, bool depth_test
   )
{
   // XXX - Should have dedicated GEL class for this.
   //       This is done in a hurry to get something that
   //       works but is not efficient.

   for (Wpt_list::size_type i=0; i<pts.size(); i++)
      show(pts[i], width, col, alpha, depth_test);

   return nullptr;
}
Пример #7
0
Wpt_list
fold_points(CWpt_list& pts, CWvec& n, bool is_closed)
{
   if (pts.size() < 2)
      return Wpt_list();
   Wpt_list ret(2);

   // Handle first point specially
   if (!is_closed || is_fold(pts.back(), pts[0], pts[1], n) )
      ret.push_back(pts.front());

   // Interior points
   for (Wpt_list::size_type i=1; i<pts.size()-1; i++)
      if (is_fold(pts[i-1], pts[i], pts[i+1], n))
         ret.push_back(pts[i]);

   // Handle last point specially
   if (!is_closed || is_fold(pts[pts.size()-2], pts.back(), pts.front(), n) )
      ret.push_back(pts.back());

   return ret;
}
Пример #8
0
Wpt_list
fold_points(CWpt_list& pts, CWvec& n, bool is_closed)
{
   if (pts.num() < 2)
      return Wpt_list();
   Wpt_list ret(2);

   // Handle first point specially
   if (!is_closed || is_fold(pts.last(), pts[0], pts[1], n) )
      ret += pts.first();

   // Interior points
   for (int i=1; i<pts.num()-1; i++)
      if (is_fold(pts[i-1], pts[i], pts[i+1], n))
         ret += pts[i];

   // Handle last point specially
   if (!is_closed || is_fold(pts[pts.num()-2], pts.last(), pts.first(), n) )
      ret += pts.last();

   return ret;
}
Пример #9
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;
}
Пример #10
0
inline double
get_param( CWpt_list& pts, int k )
{
   return pts.partial_length(k)/pts.length();
}