diff --git a/.gitignore b/.gitignore index 7accb76..5a81950 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.kdev4 /input +/output /simu diff --git a/build.sh b/build.sh index 1002176..03640f6 100755 --- a/build.sh +++ b/build.sh @@ -11,7 +11,7 @@ if [ -z "$TARGET" ]; then fi LIBS="sdl2" -FLAGS="-Wall -lm -lGL -lGLU" +FLAGS="-Wall -lm -lGL" FLAGS="`pkg-config --cflags --libs $LIBS` $FLAGS " if [ "$1" == "debug" ]; then diff --git a/generator.cpp b/generator.cpp index 06c6622..78dbcd9 100644 --- a/generator.cpp +++ b/generator.cpp @@ -5,6 +5,20 @@ #include "generator.h" +void GeneratorRowsZAX::tool_point(Track &track, const TrackPoint &p) const { + if (!track.points.empty()) { + TrackPoint &last = track.points.back(); + if ( (last.position - p.position).len() <= precision + && fabs(last.angle - p.angle) <= precision ) + { + last.speed = p.speed; + return; + } + } + + track.points.push_back(p); +} + void GeneratorRowsZAX::tool_up(Track &track, Real safe_z) const { if (track.points.empty()) return; @@ -17,7 +31,7 @@ void GeneratorRowsZAX::tool_up(Track &track, Real safe_z) const { p.angle = prev.angle; p.speed = move_speed/60.0; - track.points.push_back(p); + tool_point(track, p); } void GeneratorRowsZAX::tool_feed(Track &track, Real safe_z, Real z1, Real z, Real a, Real x) const { @@ -27,17 +41,17 @@ void GeneratorRowsZAX::tool_feed(Track &track, Real safe_z, Real z1, Real z, Rea if (track.points.empty() || track.points.back().position.z == safe_z) { p.speed = move_speed/60.0; - track.points.push_back(p); + tool_point(track, p); if (safe_z > z1 && z1 > z) { p.position.z = z1; - track.points.push_back(p); + tool_point(track, p); } } p.position.z = z; p.speed = feed_speed/60.0; - track.points.push_back(p); + tool_point(track, p); } diff --git a/generator.h b/generator.h index b48d84a..a696034 100644 --- a/generator.h +++ b/generator.h @@ -41,6 +41,7 @@ public: move_speed(1500) { } + void tool_point(Track &track, const TrackPoint &p) const; void tool_up(Track &track, Real safe_z) const; void tool_feed(Track &track, Real safe_z, Real z1, Real z, Real a, Real x) const; void touch(const Collider &collider, Track &track, Real safe_z, Real z1, Real z0, Real a, Real x) const; diff --git a/geometry.cpp b/geometry.cpp index d5932d8..1e847f8 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -99,3 +99,19 @@ Matrix4 Matrix4::rotation(const Vector3 &axis, Real angle) { a.x*ac.z + a.y*s, a.y*ac.z - a.x*s, a.z*ac.z + c , 0, 0 , 0 , 0 , 1 ); } + +Matrix4 Matrix4::perspective(Real fovy, Real aspect, Real z_near, Real z_far) { + if (fabs(fovy) <= precision) return zero(); + if (fabs(fovy) >= 180.0-precision) return zero(); + if (fabs(aspect) <= precision) return zero(); + if (fabs(z_near - z_far) <= precision) return zero(); + + Real f = 1/tan(0.5*fovy/180.0*M_PI); + Real d = 1/(z_near - z_far); + return Matrix4( + f/aspect, 0, 0 , 0, + 0 , f, 0 , 0, + 0 , 0, (z_near + z_far)*d, -1, + 0 , 0, 2*z_near*z_far*d , 0 ); +} + diff --git a/geometry.h b/geometry.h index a6d4924..3e687d0 100644 --- a/geometry.h +++ b/geometry.h @@ -156,6 +156,7 @@ public: static Matrix4 translation(const Vector3 &translate); static Matrix4 scaling(const Vector3 &scale); static Matrix4 rotation(const Vector3 &axis, Real angle); + static Matrix4 perspective(Real fovy, Real aspect, Real z_near, Real z_far); }; #endif diff --git a/loader.cpp b/loader.cpp index c0caa2c..ce41ebc 100644 --- a/loader.cpp +++ b/loader.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "loader.h" @@ -70,12 +71,13 @@ public: if (mode == 0 && c == '-') { sign = -1; mode = 1; } else if (mode == 0 && c == '+') { sign = +1; mode = 1; } else if (mode <= 1 && c == '.') { mode = 2; } - else if (mode <= 1 && isdigit(c)) { number = number*10 + (c - '0')*sign; sign = 1; mode = 1; } - else if (mode == 2 && isdigit(c)) { number += (c - '0')*(frac *= 0.1); } + else if (mode <= 1 && c >= '0' && c <= '9') { number = number*10 + (c - '0'); mode = 1; } + else if (mode == 2 && c >= '0' && c <= '9') { number += (c - '0')*(frac *= 0.1); } else if (mode == 0) { error("expected number"); return c >= 0; } else { break; } get(); } + number *= sign; while(std::isspace(f.peek())) get(); return true; @@ -104,6 +106,7 @@ public: point.speed = 600/60.0; while(read_pair(command, number)) { int inumber = (int)round(number); + //debug: std::cout << std::string(1, command) << " " << number << std::endl; bool arg = true; if (command == 'X') { read_point_data(point.position.x, command, number); @@ -144,6 +147,7 @@ public: track.split(1, 0, 0); track.calc_length(); track.split(0, 1, 0); + track.calc_length(); std::cout << "track length: " << ((track.points.empty() ? 0.0 : track.points.back().time)/60.0) << " min" << std::endl; @@ -235,6 +239,7 @@ public: } // namespace + bool Loader::load(Track &track, const std::string &filename) { return LoaderTrack(track, filename).load(); } @@ -243,3 +248,35 @@ bool Loader::load(Model &model, const std::string &filename) { return LoaderModel(model, filename).load(); } +bool Loader::save(const Track &track, const std::string &filename) { + std::cout << "saving: " << filename << std::endl; + + std::ofstream f(filename); + if (!f) { + std::cerr << "cannot open file for write: " << filename << std::endl; + return false; + } + + for(TrackPointList::const_iterator i = track.points.begin(); i != track.points.end(); ++i) { + f << std::fixed + << std::setprecision(8) + << "G01" + << " X" << i->position.x + << " Y" << i->position.y + << " Z" << i->position.z + << " A" << i->angle + << " F" << (int)round(i->speed*60.0) + << std::endl; + } + + f.flush(); + if (!f) { + std::cerr << "write error" << std::endl; + return false; + } + + f.close(); + std::cerr << "saved: " << filename << std::endl; + return true; +} + diff --git a/loader.h b/loader.h index 0375d57..ab8f869 100644 --- a/loader.h +++ b/loader.h @@ -11,6 +11,8 @@ class Loader { public: static bool load(Track &track, const std::string &filename); static bool load(Model &model, const std::string &filename); + + static bool save(const Track &track, const std::string &filename); }; diff --git a/main.cpp b/main.cpp index 2b8e5d8..8831df0 100644 --- a/main.cpp +++ b/main.cpp @@ -3,9 +3,9 @@ #include #include -#include #include +#include "geometry.h" #include "scene.h" #include "simulator.h" #include "tool.h" @@ -102,8 +102,7 @@ public: void resize(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(90.0, (Real)width/height, 1, 1000); + glLoadMatrixd( Matrix4::perspective(90.0, (Real)width/height, 1, 1000).a ); glMatrixMode(GL_MODELVIEW); } @@ -190,6 +189,7 @@ int main(int argc, char **argv) if (!app.init()) return -1; bool load_track = false; + bool load_model = false; Model model; SimulatorXYZA simulator_xyza(400, 360); @@ -208,8 +208,13 @@ int main(int argc, char **argv) if (argc > 2 && std::string(argv[2]) != ".") { Loader::load(model, argv[2]); + Loader::save(app.scene->track, "output/tmp.tap"); app.scene->model = &model; - if (!load_track) { + load_model = true; + } + + if (argc > 3 && std::string(argv[3]) != ".") { + if (!load_track && load_model) { GeneratorRowsZAX generator; generator.step_z = 1.5; generator.step_a = 2*0.9*tool.radius; @@ -217,10 +222,11 @@ int main(int argc, char **argv) generator.generate(collider, app.scene->track); app.scene->simulator = &simulator_xyza; app.scene->simulator->simulate(app.scene->track, tool); - //app.scene->model = 0; + Loader::save(app.scene->track, argv[3]); } } + app.scene->tool = &tool; app.scene->tool_dir = dir; app.scene->collider = &collider; diff --git a/scene.cpp b/scene.cpp index a5212f1..e236072 100644 --- a/scene.cpp +++ b/scene.cpp @@ -1,5 +1,6 @@ #include +#include #include @@ -15,12 +16,15 @@ Scene::Scene(): time(), time_forward(0.0), time_backward(20.0), - time_speed(30.0), + time_speed(1.0), + model_angle(), model(), simulator(), tool_dir(0, 0, -1), tool(), - collider() + collider(), + move_tool(true), + rotate_model(true) { } Scene::~Scene() { } @@ -73,18 +77,22 @@ void Scene::update(Real dt) { int index = track.index_by_time(time); if (index > 0) { - /* const TrackPoint &p0 = track.points[index-1]; const TrackPoint &p1 = track.points[index]; Real l = p1.duration > 1e-5 ? (p0.time - time)/p1.duration : 0.5; TrackPoint p = TrackPoint::median(l, p0, p1); - - Real a = p.angle*(M_PI/180); - Real s = sin(a); - Real c = cos(a); - tool_pos = p.real_pos; - tool_dir = Vector3(0, p.position.z*s, -p.position.z*c).norm(); - */ + //std::cout << p.angle << std::endl; + + if (move_tool) { + Real a = p.angle*(M_PI/180); + Real s = sin(a); + Real c = cos(a); + tool_pos = p.real_pos; + tool_dir = Vector3(0, p.position.z*s, -p.position.z*c).norm(); + } + + if (rotate_model) model_angle = p.angle; + if (simulator) simulator->scroll_to(index); } @@ -174,10 +182,14 @@ void Scene::draw() { draw_stars(); draw_axes(); - if (model) model->draw(); - if (simulator) simulator->draw(); - if (tool) tool->draw(tool_pos, tool_dir); - draw_track(); + + glPushMatrix(); + glRotated(-model_angle, 1, 0, 0); + if (model) model->draw(); + if (simulator) simulator->draw(); + if (tool) tool->draw(tool_pos, tool_dir); + draw_track(); + glPopMatrix(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); diff --git a/scene.h b/scene.h index 3534fdd..9b54156 100644 --- a/scene.h +++ b/scene.h @@ -21,6 +21,8 @@ public: Real time_forward; Real time_backward; Real time_speed; + + Real model_angle; Model *model; Simulator *simulator; @@ -31,6 +33,9 @@ public: Collider *collider; + bool move_tool; + bool rotate_model; + Scene(); ~Scene(); diff --git a/simulator.cpp b/simulator.cpp index 22614f6..3e88df9 100644 --- a/simulator.cpp +++ b/simulator.cpp @@ -12,6 +12,7 @@ void SimulatorXYZA::simulate(const Track &track, const Tool &tool) { if (!raster.raster.get_data() || track.points.empty()) return; std::cout << "SimulatorXYZA::simulate" << std::endl; + std::cout << "SimulatorXYZA::simulate: track points: " << track.points.size() << std::endl; raster.x0 = raster.x1 = track.points.front().position.x; for(TrackPointList::const_iterator i = track.points.begin(); i != track.points.end(); ++i) { diff --git a/track.cpp b/track.cpp index 6900214..ea8f289 100644 --- a/track.cpp +++ b/track.cpp @@ -40,12 +40,17 @@ void Track::calc_length() { Real l = 0, time = 0; for(TrackPointList::iterator i = points.begin(); i != points.end(); ++i) { if (i->speed < 1e-3) i->speed = 1e-3; - const Vector3 &p = i->real_pos = TrackPoint::calc_real_pos(*i); - Vector3 d(p.x - prev.x, p.y - prev.y, p.y - prev.y); - prev = p; + i->real_pos = TrackPoint::calc_real_pos(*i); + Vector3 d = i->real_pos - prev; + prev = i->real_pos; - i->l = l += i->length = sqrt(d.x*d.x + d.y*d.y + d.z*d.z); - i->time = time += i->duration = i->length/i->speed; + i->length = d.len(); + l += i->length; + i->l = l; + + i->duration = i->length/i->speed; + time += i->duration; + i->time = time; } } diff --git a/track.h b/track.h index 0d67586..2c5916a 100644 --- a/track.h +++ b/track.h @@ -4,6 +4,7 @@ #include +#include #include #include @@ -35,6 +36,7 @@ public: } static TrackPoint median(Real l, const TrackPoint &p0, const TrackPoint &p1) { + //assert(l >= - precision && l <= 1 + precision); Real k = 1 - l; TrackPoint p; p.position.x = p0.position.x*k + p1.position.x*l;