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; }
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; }