]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/slopetool.cpp
Avoid crash in SlopeTool if nothing is selected
[r2c2.git] / source / designer / slopetool.cpp
index c38269f050886bdc9778d87685972928caf3978a..ef96e558d08f697dd9219c99629b2779583b517a 100644 (file)
@@ -1,71 +1,55 @@
+#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)
+       if(objects.empty())
        {
-               unsigned nls = (*i)->get_n_link_slots();
-               if(nls!=2 || !dynamic_cast<Track *>(*i))
+               set_status("Nothing selected");
+               set_done(false);
+               return;
+       }
+
+       for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++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)
@@ -78,57 +62,64 @@ void SlopeTool::even_slope(bool 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);
        }
 }