Blob Blame Raw

#include <iostream>

#include <GL/gl.h>

#include "simulator.h"


void SimulatorXYZA::simulate(const Track &track, Real tool_radius) {
    points.clear();
    simu_index = 0;
    x0 = x1 = 0;

    if (!raster.get_data() || track.points.empty()) return;
    
    std::cout << "SimulatorXYZA::simulate" << std::endl;
    
    x0 = x1 = track.points.front().position.x;
    Real max_radius = 0;
    for(PointList::const_iterator i = track.points.begin(); i != track.points.end(); ++i) {
        Real radius = sqrt(i->position.y*i->position.y + i->position.z*i->position.z);
        if (max_radius < radius) max_radius = radius;
        if (x0 > i->position.x) x0 = i->position.x;
        if (x1 < i->position.x) x1 = i->position.x;
    }
    raster.fill(max_radius);
    
    if (x1 + 1e-5 < x0) {
        std::cout << "SimulatorXYZA::simulate: zero bound" << std::endl;
        return;
    }
    
    Real h = raster.get_height();
    Real kx = raster.get_width()/(x1 - x0);
    Real ka = 1/360.0;
    Real kr = h/(2*M_PI);

    Real dx = fabs(tool_radius*kx);
    int index = 0;
    for(PointList::const_iterator i = track.points.begin(); i != track.points.end(); ++i, ++index) {
        Real radius = sqrt(i->position.y*i->position.y + i->position.z*i->position.z);
        if (radius < 1e-5) radius = 1e-5;
        Real dy = fabs(tool_radius/radius*kr);
        
        Real x = (i->position.x - x0)*kx;
        Real y = i->angle*ka;
        y = (y - floor(y))*h;

        raster.touch(index, radius, x, y, dx, dy, points);
        if (y - dy < 0)
            raster.touch(index, radius, x, y + h, dx, dy, points);
        if (y + dy > h)
            raster.touch(index, radius, x, y - h, dx, dy, points);
        
        if (index % 1000 == 0)
            std::cout << "." << std::flush;
        if (index % 100000 == 0)
            std::cout << std::endl << std::flush;
    }
    simu_index = (int)points.size();

    std::cout << "SimulatorXYZA::simulate: done" << std::endl;
}
    
void SimulatorXYZA::scroll_to(int index) {
    while(simu_index < (int)points.size() && points[simu_index].index <= index)
        points[simu_index++].apply_next(raster);
    while(simu_index > 0 && points[simu_index-1].index > index)
        points[--simu_index].apply_prev(raster);
}
    
void SimulatorXYZA::draw() const {
    int w = raster.get_width();
    int h = raster.get_height();
    if (w < 2 || h < 2) return;

    Vector3 v, v0, v1;
    
    Real kx = (x1 - x0)/w;
    Real ka = 2*M_PI/h;

    glEnable(GL_LIGHTING);
    
    glColor4d(0, 0, 1, 0.5);
    
    glBegin(GL_TRIANGLE_STRIP);
    for(int r = 0; r < h; ++r) {
        int rr = r ? r-1 : h-1;
        Real a0 = rr*ka;
        Real a1 = r*ka;
        Real s0 = sin(a0), s1 = sin(a1);
        Real c0 = cos(a0), c1 = cos(a1);
        for(int c = 0; c < w; ++c) {
            v0.x = v1.x = x0 + c*kx;
            Real r0 = raster[rr][c];
            Real r1 = raster[r][c];
            v0.y = -s0*r0, v0.z = c0*r0;
            v1.y = -s1*r1, v1.z = c1*r1;
            
            Vector3 dv0(v0.x - v.x, v0.y - v.y, v0.z - v.z);
            Vector3 dv1(v1.x - v.x, v1.y - v.y, v1.z - v.z);
            Vector3 norm(
                dv0.y*dv1.z - dv0.z*dv1.y,
                dv0.z*dv1.x - dv0.x*dv1.z,
                dv0.x*dv1.y - dv0.y*dv1.x );
            Real l = sqrt(norm.x*norm.x + norm.y*norm.y + norm.z*norm.z);
            l = l > 1e-5 ? 1/l : 0;
            glNormal3d(norm.x*l, norm.y*l, norm.z*l);

            if (!c) glVertex3dv(v0.c);
            glVertex3dv(v0.c);
            glVertex3dv(v1.c);
            v = v1;
        }
        glVertex3dv(v.c);
    }
    glEnd();

    glDisable(GL_LIGHTING);
}