+#include "libr2c2/track.h"
#include "slopetool.h"
using namespace std;
using namespace Msp;
using namespace R2C2;
-SlopeTool::SlopeTool(Designer &d, Input::Mouse &m, const set<Object *> &objects):
- Tool(d, m),
+SlopeTool::SlopeTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, const set<Object *> &objects):
+ Tool(d, k, m),
total_length(0)
{
for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
- {
- unsigned nls = (*i)->get_n_link_slots();
- if(nls!=2 || !dynamic_cast<Track *>(*i))
+ if(!dynamic_cast<Track *>(*i) || (*i)->get_n_link_slots()!=2)
{
set_status("Must have linear tracks only");
+ set_done(false);
return;
}
- }
-
- for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
- {
- unsigned nls = (*i)->get_n_link_slots();
- for(unsigned j=0; j<nls; ++j)
- if(Track *link = dynamic_cast<Track *>((*i)->get_link(j)))
- if(!objects.count(link))
- neighbors.push_back(link);
- }
-
- list<Track *> tmp_tracks;
- for(set<Object *>::iterator i=objects.begin(); i!=objects.end(); ++i)
- if(Track *track = dynamic_cast<Track *>(*i))
- tmp_tracks.push_back(track);
- Track *cur = neighbors.front();
- while(!tmp_tracks.empty())
- {
- bool rev = false;
- for(list<Track *>::iterator i=tmp_tracks.begin(); i!=tmp_tracks.end(); ++i)
+ TrackIter track;
+ for(set<Object *>::const_iterator i=objects.begin(); (!track && i!=objects.end()); ++i)
+ if(Track *t = dynamic_cast<Track *>(*i))
{
- const vector<Track *> &links = (*i)->get_links();
- if(links[0]==cur)
- {
- cur = *i;
- tmp_tracks.erase(i);
- break;
- }
- else if(links[1]==cur)
- {
- cur = *i;
- rev = true;
- tmp_tracks.erase(i);
- break;
- }
+ unsigned nls = t->get_n_link_slots();
+ for(unsigned j=0; (!track && j<nls); ++j)
+ if(!objects.count((*i)->get_link(j)))
+ track = TrackIter(t, j);
}
- tracks.push_back(TrackOrder(cur, rev));
- total_length += cur->get_type().get_total_length();
+
+ total_length = 0;
+ while(track && objects.count(track.track()))
+ {
+ tracks.push_back(track);
+ total_length += track->get_type().get_path_length(0);
+ track = track.next();
}
}
void SlopeTool::even_slope(bool smooth)
{
- list<Track *>::iterator nb = neighbors.begin();
- int epi = (*nb)->get_link_slot(*tracks.front().track);
- float start_z = (*nb)->get_snap_node(epi).position.z;
- ++nb;
- epi = (*nb)->get_link_slot(*tracks.back().track);
- float end_z = (*nb)->get_snap_node(epi).position.z;
+ if(done)
+ return;
+
+ float start_z = tracks.front()->get_snap_node(tracks.front().entry()).position.z;
+ float end_z = tracks.back()->get_snap_node(tracks.back().reverse().entry()).position.z;
float length = total_length;
if(smooth)
Angle tilt = Geometry::atan(cur_slope);
set_slope(tracks.front(), start_z, tilt);
- start_z += tracks.front().track->get_type().get_path_length(0)*dir*cur_slope;
- length -= tracks.front().track->get_type().get_path_length(0);
+ start_z += tracks.front()->get_type().get_path_length(0)*dir*cur_slope;
+ length -= tracks.front()->get_type().get_path_length(0);
tracks.pop_front();
- end_z -= tracks.back().track->get_type().get_path_length(0)*dir*cur_slope;
+ end_z -= tracks.back()->get_type().get_path_length(0)*dir*cur_slope;
set_slope(tracks.back(), end_z, tilt);
- length -= tracks.back().track->get_type().get_path_length(0);
+ length -= tracks.back()->get_type().get_path_length(0);
tracks.pop_back();
}
}
float cur_z = start_z;
Angle tilt = Geometry::atan((end_z-start_z)/length);
- for(list<TrackOrder>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
set_slope(*i, cur_z, tilt);
- cur_z += i->track->get_type().get_path_length(0)*(end_z-start_z)/length;
+ cur_z += (*i)->get_type().get_path_length(0)*(end_z-start_z)/length;
}
+
+ set_done(true);
}
void SlopeTool::flatten()
{
+ if(done)
+ return;
+
float z = 0;
- for(list<TrackOrder>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
- unsigned nsn = i->track->get_n_snap_nodes();
+ unsigned nsn = (*i)->get_n_snap_nodes();
for(unsigned j=0; j<nsn; ++j)
- z += i->track->get_snap_node(j).position.z/nsn;
+ z += (*i)->get_snap_node(j).position.z/nsn;
}
z /= static_cast<int>(tracks.size());
- for(list<TrackOrder>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
- Vector p = i->track->get_position();
- i->track->set_position(Vector(p.x, p.y, z));
- i->track->set_tilt(Angle::zero());
+ Vector p = (*i)->get_position();
+ (*i)->set_position(Vector(p.x, p.y, z));
+ (*i)->set_tilt(Angle::zero());
}
+
+ set_done(true);
}
-void SlopeTool::set_slope(TrackOrder &track, float z, const Angle &tilt)
+void SlopeTool::set_slope(const TrackIter &track, float z, const Angle &tilt)
{
- const Vector &p = track.track->get_position();
- float dz = tan(tilt)*track.track->get_type().get_path_length(0);
- if(track.rev)
+ const Vector &p = track->get_position();
+ float dz = tan(tilt)*track->get_type().get_path_length(0);
+ if(track.entry()==1)
{
- track.track->set_position(Vector(p.x, p.y, z+dz));
- track.track->set_tilt(-tilt);
+ track->set_position(Vector(p.x, p.y, z+dz));
+ track->set_tilt(-tilt);
}
else
{
- track.track->set_position(Vector(p.x, p.y, z));
- track.track->set_tilt(tilt);
+ track->set_position(Vector(p.x, p.y, z));
+ track->set_tilt(tilt);
}
}