Forked from
gmsh / gmsh
9840 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
drawContext.cpp 25.84 KiB
#if !defined(BUILD_ANDROID)
#define BUILD_IOS 1
#endif
#include <map>
#if defined(BUILD_IOS)
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#include <Gmsh/Gmsh.h>
#include <Gmsh/OpenFile.h>
#include <Gmsh/GModel.h>
#include <Gmsh/MElement.h>
#include <Gmsh/VertexArray.h>
#include <Gmsh/onelab.h>
#include <Gmsh/onelabUtils.h>
#include <Gmsh/PView.h>
#include <Gmsh/PViewOptions.h>
#include <Gmsh/PViewData.h>
#include <Gmsh/Context.h>
#include <Gmsh/StringUtils.h>
#include <GetDP/GetDP.h>
#endif
#if defined(BUILD_ANDROID)
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <gmsh/Gmsh.h>
#include <gmsh/OpenFile.h>
#include <gmsh/GModel.h>
#include <gmsh/MElement.h>
#include <gmsh/VertexArray.h>
#include <gmsh/onelab.h>
#include <gmsh/onelabUtils.h>
#include <gmsh/PView.h>
#include <gmsh/PViewOptions.h>
#include <gmsh/PViewData.h>
#include <gmsh/Context.h>
#include <gmsh/StringUtils.h>
#include <getdp/GetDP.h>
#include "androidGModel.h"
#endif
#include "drawContext.h"
#include "drawString.h"
#include "Trackball.h"
static bool locked = false;
static bool onelabStop = false;
drawContext::drawContext(float fontFactor, bool retina)
{
GmshInitialize();
GmshSetOption("General", "Terminal", 1.0);
onelabUtils::setFirstComputationFlag(false);
for(int i = 0; i < 3; i++){
_translate[i] = 0.;
_scale[i] = 1.;
}
setQuaternion(0., 0., 0., 1.);
_fillMesh = false;
_gradiant = true;
_fontFactor = fontFactor;
_retina = retina;
}
static void checkGlError(const char* op)
{
for (GLint error = glGetError(); error; error = glGetError())
Msg::Error("%s: glError (0x%x)",op,error);
}
void drawContext::load(std::string filename)
{
if(locked) return;
// delete all models and post-processing views
GmshClearProject();
// reset onelab database
onelab::server::instance()->clear();
// restore default options
GmshRestoreDefaultOptions();
// open the file with Gmsh
GmshOpenProject(filename);
// reset openGL view
eventHandler(10);
// run onelab clients to populate the database
onelab_cb("check");
// mark all parameters as changed to force complete first run
onelab::server::instance()->setChanged(true, "Gmsh");
onelab::server::instance()->setChanged(true, "GetDP");
}
void drawContext::eventHandler(int event, float x, float y)
{
int width = _width, height = _height;
if(_retina){ // x,y for retina are still the same as for non-retina
width /= 2;
height /= 2;
}
_current.set(_scale, _translate, _right, _left,
_bottom, _top, width, height, x, y);
double xx[3] = {1.,0.,0.};
double yy[3] = {0.,1.,0.};
double q[4];
switch(event){
case 0: // finger(s) press the screen
// in this case x and y represent the start point
_start.set(_scale, _translate, _right, _left,
_bottom, _top, width, height, x, y);
_previous.set(_scale, _translate, _right, _left,
_bottom, _top, width, height, x, y);
break;
case 1: // finger move (translate)
// in this case x and y represent the current point
printf("currx=%g prevx=%g\n", _current.wnr[0],_previous.wnr[0]);
_translate[0] += (_current.wnr[0] - _previous.wnr[0]);
_translate[1] += (_current.wnr[1] - _previous.wnr[1]);
_translate[2] = 0.;
break;
case 2: // fingers move (scale)
// in this case we don't care about previous and current position, x
// represent the scale
_scale[0] = _scale[1] = _scale[2] = x;
_start.recenter(_scale, _translate);
break;
case 3: // fingers move (rotate)
addQuaternion((2. * _previous.win[0] - width) / width,
(height - 2. * _previous.win[1]) / height,
(2. * _current.win[0] - width) / width,
(height - 2. * _current.win[1]) / height);
break;
case 4: // release the finger(s)
// Do nothing ?
break;
case 5: // X view
axis_to_quat(xx, M_PI/2, q);
setQuaternion(q[0], q[1], q[2], q[3]);
break;
case 6: // Y view
axis_to_quat(yy, M_PI/2, q);
setQuaternion(q[0], q[1], q[2], q[3]);
break;
case 7: // Z view
setQuaternion(0., 0., 0., 1.);
break;
default: // all other reset the position
setQuaternion(0., 0., 0., 1.);
for(int i = 0; i < 3; i++){
_translate[i] = 0.;
_scale[i] = 1.;
}
break;
}
_previous.set(_scale, _translate, _right, _left,
_bottom, _top, width, height, x, y);
}
void drawContext::setQuaternion(double q0, double q1, double q2, double q3)
{
_quaternion[0] = q0;
_quaternion[1] = q1;
_quaternion[2] = q2;
_quaternion[3] = q3;
}
void drawContext::addQuaternion(double p1x, double p1y, double p2x, double p2y)
{
double quat[4];
trackball(quat, p1x, p1y, p2x, p2y);
add_quats(quat, _quaternion, _quaternion);
}
void drawContext::buildRotationMatrix()
{
build_rotmatrix(_rotate, _quaternion);
for(int i=0; i<16;i++)
_rotatef[i] = (float)_rotate[i];
}
void drawContext::OrthofFromGModel()
{
double Va = (double)_height / (double)_width;
double Wa = (CTX::instance()->max[1] - CTX::instance()->min[1]) /
(CTX::instance()->max[0] - CTX::instance()->min[0]);
double vxmin, vxmax, vymin, vymax;
if(Va > Wa) {
vxmin = CTX::instance()->min[0];
vxmax = CTX::instance()->max[0];
vymin = 0.5 * (CTX::instance()->min[1] + CTX::instance()->max[1] -
Va * (CTX::instance()->max[0] - CTX::instance()->min[0]));
vymax = 0.5 * (CTX::instance()->min[1] + CTX::instance()->max[1] +
Va * (CTX::instance()->max[0] - CTX::instance()->min[0]));
}
else {
vxmin = 0.5 * (CTX::instance()->min[0] + CTX::instance()->max[0] -
(CTX::instance()->max[1] - CTX::instance()->min[1]) / Va);
vxmax = 0.5 * (CTX::instance()->min[0] + CTX::instance()->max[0] +
(CTX::instance()->max[1] - CTX::instance()->min[1]) / Va);
vymin = CTX::instance()->min[1];
vymax = CTX::instance()->max[1];
}
double fact = CTX::instance()->displayBorderFactor;
double xborder = fact * (vxmax - vxmin), yborder = fact * (vymax - vymin);
vxmin -= xborder;
vxmax += xborder;
vymin -= yborder;
vymax += yborder;
// set up the near and far clipping planes so that the box is large enough to
// manipulate the model and zoom, but not too big (otherwise the z-buffer
// resolution e.g. with Mesa can become insufficient)
double zmax = std::max(fabs(CTX::instance()->min[2]),
fabs(CTX::instance()->max[2]));
if(zmax < CTX::instance()->lc) zmax = CTX::instance()->lc;
double clip_near = -zmax * _scale[2] * CTX::instance()->clipFactor;
double clip_far = -clip_near;
GLint matrixMode;
glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(vxmin, vxmax, vymin, vymax, clip_near, clip_far);
glMatrixMode(matrixMode);
_left = vxmin;
_right = vxmax;
_top = vymax;
_bottom = vymin;
_far = clip_far;
}
void drawContext::initView(int w, int h)
{
_height = h;
_width = w;
glViewport(0, 0, w, h);
OrthofFromGModel();
glClearColor(.83, .85, .98, 1.);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_LESS);
}
void drawArray(VertexArray *va, GLint type, bool useColorArray, bool useNormalArray)
{
if(!va) return;
glEnable(GL_BLEND);
glEnable(GL_RESCALE_NORMAL);
glShadeModel(GL_SMOOTH);
glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray());
glEnableClientState(GL_VERTEX_ARRAY);
if(useNormalArray){
glNormalPointer(GL_BYTE, 0, va->getNormalArray());
glEnableClientState(GL_NORMAL_ARRAY);
}
if(useColorArray){
glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
glEnableClientState(GL_COLOR_ARRAY);
}
glDrawArrays(type, 0, va->getNumVertices());
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_RESCALE_NORMAL);
glDisable(GL_BLEND);
}
void drawVector(double x, double y, double z, double dx, double dy, double dz)
{
double l = sqrt(dx * dx + dy * dy + dz * dz), lt;
double n[3], t[3], u[3];
if(l == 0.0) return;
GLfloat line[] = {
(GLfloat)x, (GLfloat)y, (GLfloat)z,
(GLfloat)(x+dx), (GLfloat)(y+dy), (GLfloat)(z+dz),
};
glVertexPointer(3, GL_FLOAT, 0, line);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
n[0] = dx / l;
n[1] = dy / l;
n[2] = dz / l;
if((fabs(n[0]) >= fabs(n[1]) && fabs(n[0]) >= fabs(n[2])) ||
(fabs(n[1]) >= fabs(n[0]) && fabs(n[1]) >= fabs(n[2]))) {
t[0] = n[1];
t[1] = -n[0];
t[2] = 0.;
}
else {
t[0] = 0.;
t[1] = n[2];
t[2] = -n[1];
}
lt = sqrt(t[0] * t[0] + t[1] * t[1] + t[2] * t[2]);
t[0] /= lt;
t[1] /= lt;
t[2] /= lt;
u[0] = n[1] * t[2] - n[2] * t[1];
u[1] = n[2] * t[0] - n[0] * t[2];
u[2] = n[0] * t[1] - n[1] * t[0];
lt = sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
u[0] /= lt;
u[1] /= lt;
u[2] /= lt;
double f1 = 0.75; // Stem lenght
double b = 0.1 * l;
GLfloat arrow[] = {
(GLfloat)(x + dx), (GLfloat)(y + dy), (GLfloat)(z + dz),
(GLfloat)(x + f1 * dx + b * (t[0])), (GLfloat)(y + f1 * dy + b * (t[1])),
(GLfloat)(z + f1 * dz + b * (t[2])),
(GLfloat)(x + f1 * dx + b * (-t[0])), (GLfloat)(y + f1 * dy + b * (-t[1])),
(GLfloat)(z + f1 * dz + b * (-t[2])),
(GLfloat)(x + dx), (GLfloat)(y + dy), (GLfloat)(z + dz),
(GLfloat)(x + f1 * dx + b * (-u[0])), (GLfloat)(y + f1 * dy + b * (-u[1])),
(GLfloat)(z + f1 * dz + b * (-u[2])),
(GLfloat)(x + f1 * dx + b * (u[0])), (GLfloat)(y + f1 * dy + b * (u[1])),
(GLfloat)(z + f1 * dz + b * (u[2])),
};
glVertexPointer(3, GL_FLOAT, 0, arrow);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_LINE_SMOOTH);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_LINE_SMOOTH);
}
void drawContext::drawVectorArray(PViewOptions *opt, VertexArray *va)
{
if(!va || va->getNumVerticesPerElement() != 2) return;
for(int i = 0; i < va->getNumVertices(); i += 2){
float *s = va->getVertexArray(3 * i);
float *v = va->getVertexArray(3 * (i + 1));
double l = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
double lmax = opt->tmpMax;
if((l && opt->vectorType) && lmax){
double scale = (opt->arrowSizeMax - opt->arrowSizeMin) / lmax;
if(opt->arrowSizeMin && l) scale += opt->arrowSizeMin / l;
double dx = scale * v[0];
double dy = scale * v[1];
double dz = scale * v[2];
GLubyte *color = (GLubyte *)va->getColorArray(4 * i);
glColor4ub(*(color), *(color+1), *(color+2), *(color+3));
if(fabs(dx) > 1. || fabs(dy) > 1. || fabs(dz) > 1.){
double d = (_right - _left) / _width / _scale[0];
dx *= d; dy *= d; dz *= d;
double x = s[0], y = s[1], z = s[2];
drawVector(x,y,z,dx,dy,dz);
}
}
}
}
void drawContext::drawPView(PView *p)
{
PViewOptions *opt = p->getOptions();
if(!opt->visible) return;
glPointSize((GLfloat)opt->pointSize);
glLineWidth((GLfloat)opt->lineWidth);
drawArray(p->va_points, GL_POINTS, true);
drawArray(p->va_lines, GL_LINES, true);
drawArray(p->va_triangles, GL_TRIANGLES, true, true);
glLineWidth(1);
glPointSize(1);
drawVectorArray(p->getOptions(), p->va_vectors);
}
void drawContext::drawScale()
{
glPushMatrix();
glLoadIdentity();
// Draw the scale bar
int nPview = 0;
for(int i=0; i<PView::list.size();i++){
PView *p = PView::list[i];
PViewOptions *opt = p->getOptions();
if(!opt->visible) continue;
PViewData *data = p->getData();
double width = (_right -_left) / 2.;
double height = (_top - _bottom) / 10.;
double dh = height / 5;
double box = width / (opt->nbIso ? opt->nbIso : 1);
double xmin = _left + (_right - _left -width)/2.;
double ymin = _bottom + 0.8 * height + height * nPview;
std::vector<GLfloat> vertex(opt->nbIso*3*4);
std::vector<GLubyte> color(opt->nbIso*4*4);
for(int i = 0; i < opt->nbIso; i++){
if(opt->intervalsType == PViewOptions::Discrete ||
opt->intervalsType == PViewOptions::Numeric){
unsigned int col = opt->getColor(i, opt->nbIso);
color[i*4*4+0] = color[i*4*4+4] = color[i*4*4+8] = color[i*4*4+12] =
(GLubyte)CTX::instance()->unpackRed(col);
color[i*4*4+1] = color[i*4*4+5] = color[i*4*4+9] = color[i*4*4+13] =
(GLubyte)CTX::instance()->unpackGreen(col);
color[i*4*4+2] = color[i*4*4+6] = color[i*4*4+10] = color[i*4*4+14] =
(GLubyte)CTX::instance()->unpackBlue(col);
color[i*4*4+3] = color[i*4*4+7] = color[i*4*4+11] = color[i*4*4+15] =
(GLubyte)CTX::instance()->unpackAlpha(col);
vertex[i*3*4+0] = xmin + i * box;
vertex[i*3*4+1] = ymin;
vertex[i*3*4+2] = 0.;
vertex[i*3*4+3] = xmin + i * box;
vertex[i*3*4+4] = ymin + dh;
vertex[i*3*4+5] = 0.;
vertex[i*3*4+6] = xmin + (i + 1) * box;
vertex[i*3*4+7] = ymin;
vertex[i*3*4+8] = 0.;
vertex[i*3*4+9] = xmin + (i + 1) * box;
vertex[i*3*4+10] = ymin + dh;
vertex[i*3*4+11] = 0.;
}
else if(opt->intervalsType == PViewOptions::Continuous){
double dv = (opt->tmpMax - opt->tmpMin) / (opt->nbIso ? opt->nbIso : 1);
double v1 = opt->tmpMin + i * dv;
unsigned int col1 = opt->getColor(v1, opt->tmpMin, opt->tmpMax, true);
color[i*4*4+0] = color[i*4*4+4] = (GLubyte)CTX::instance()->unpackRed(col1);
color[i*4*4+1] = color[i*4*4+5] = (GLubyte)CTX::instance()->unpackGreen(col1);
color[i*4*4+2] = color[i*4*4+6] = (GLubyte)CTX::instance()->unpackBlue(col1);
color[i*4*4+3] = color[i*4*4+7] = (GLubyte)CTX::instance()->unpackAlpha(col1);
vertex[i*3*4+0] = xmin + i * box;
vertex[i*3*4+1] = ymin;
vertex[i*3*4+2] = 0.;
vertex[i*3*4+3] = xmin + i * box;
vertex[i*3*4+4] = ymin + dh;
vertex[i*3*4+5] = 0.;
double v2 = opt->tmpMin + (i + 1) * dv;
unsigned int col2 = opt->getColor(v2, opt->tmpMin, opt->tmpMax, true);
color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col2);
color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col2);
color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col2);
color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col2);
vertex[i*3*4+6] = xmin + (i + 1) * box;
vertex[i*3*4+7] = ymin;
vertex[i*3*4+8] = 0.;
vertex[i*3*4+9] = xmin + (i + 1) * box;
vertex[i*3*4+10] = ymin + dh;
vertex[i*3*4+11] = 0.;
}
else{
unsigned int col = opt->getColor(i, opt->nbIso);
color[i*4*4+0] = color[i*4*4+4] = color[i*4*4+8] = color[i*4*4+12] =
(GLubyte)CTX::instance()->unpackRed(col);
color[i*4*4+1] = color[i*4*4+5] = color[i*4*4+9] = color[i*4*4+13] =
(GLubyte)CTX::instance()->unpackGreen(col);
color[i*4*4+2] = color[i*4*4+6] = color[i*4*4+10] = color[i*4*4+14] =
(GLubyte)CTX::instance()->unpackBlue(col);
color[i*4*4+3] = color[i*4*4+7] = color[i*4*4+11] = color[i*4*4+15] =
(GLubyte)CTX::instance()->unpackAlpha(col);
vertex[i*3*4+0] = xmin + i * box;
vertex[i*3*4+1] = ymin;
vertex[i*3*4+2] = 0.;
vertex[i*3*4+3] = xmin + i * box;
vertex[i*3*4+4] = ymin + dh;
vertex[i*3*4+5] = 0.;
vertex[i*3*4+6] = xmin + (i + 1) * box;
vertex[i*3*4+7] = ymin;
vertex[i*3*4+8] = 0.;
vertex[i*3*4+9] = xmin + (i + 1) * box;
vertex[i*3*4+10] = ymin + dh;
vertex[i*3*4+11] = 0.;
}
}
glVertexPointer(3, GL_FLOAT, 0, &vertex[0]);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, &color[0]);
glEnableClientState(GL_COLOR_ARRAY);
if(opt->intervalsType == PViewOptions::Discrete ||
opt->intervalsType == PViewOptions::Numeric ||
opt->intervalsType == PViewOptions::Continuous)
glDrawArrays(GL_TRIANGLE_STRIP, 0, opt->nbIso*4);
else
glDrawArrays(GL_LINES, 0, opt->nbIso*4);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
char label[1024];
int nt = data->getNumTimeSteps();
if((opt->showTime == 1 && nt > 1) || opt->showTime == 2){
char tmp[256];
sprintf(tmp, opt->format.c_str(), data->getTime(opt->timeStep));
sprintf(label, "%s (%s)", data->getName().c_str(), tmp);
}
else if((opt->showTime == 3 && nt > 1) || opt->showTime == 4){
sprintf(label, "%s (%d/%d)", data->getName().c_str(), opt->timeStep,
data->getNumTimeSteps() - 1);
}
else{
sprintf(label, "%s", data->getName().c_str());
}
drawString lbl(label, 20 * _fontFactor);
lbl.draw(xmin + width / 2, ymin + 2.75 * dh, 0.,
_width/(_right-_left), _height/(_top-_bottom));
drawString val(data->getName().c_str(), 15 * _fontFactor);
for(int i = 0; i < 3; i++) {
double v = opt->getScaleValue(i, 3, opt->tmpMin, opt->tmpMax);
sprintf(label, opt->format.c_str(), v);
val.setText(label);
val.draw(xmin + i * width/ 2, ymin + 1.5 * dh, 0.,
_width/(_right-_left), _height/(_top-_bottom));
}
nPview++;
}
glPopMatrix();
}
void drawContext::drawPost()
{
if(PView::list.empty()) return ;
for(unsigned int i = 0; i < PView::list.size(); i++){
PView::list[i]->fillVertexArrays();
drawPView(PView::list[i]);
}
}
void drawContext::drawAxes(float x0, float y0, float z0, float h)
{
glLineWidth(1.);
glPushMatrix();
glLoadIdentity();
glTranslatef(x0, y0, z0);
glMultMatrixf(_rotatef);
glTranslatef(-x0, -y0, -z0);
const GLfloat axes[] = {
(GLfloat)x0, (GLfloat)y0, (GLfloat)z0,
(GLfloat)(x0+h), (GLfloat)y0, (GLfloat)z0,
(GLfloat)x0, (GLfloat)y0, (GLfloat)z0,
(GLfloat)x0, (GLfloat)(y0+h), (GLfloat)z0,
(GLfloat)x0, (GLfloat)y0, (GLfloat)z0,
(GLfloat)x0, (GLfloat)y0, (GLfloat)(z0+h),
};
GLfloat colors[] = {
0., 0, 0, 1.,
0., 0, 0, 1.,
0, 0, 0., 1.,
0, 0, 0., 1.,
0, 0., 0, 1.,
0, 0., 0, 1.,
};
glVertexPointer(3, GL_FLOAT, 0, axes);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_LINES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
double dx = h / 10;
drawString x("X", 15 * _fontFactor, colors);
x.draw(x0+h+dx, y0+dx, z0+dx, _width/(_right-_left), _height/(_top-_bottom), false);
drawString y("Y", 15 * _fontFactor, colors+8);
y.draw(x0+dx, y0+h+dx, z0+dx, _width/(_right-_left), _height/(_top-_bottom), false);
drawString z("Z", 15 * _fontFactor, colors+16);
z.draw(x0+dx, y0+dx, z0+h+dx, _width/(_right-_left), _height/(_top-_bottom), false);
glPopMatrix();
glLineWidth(1);
}
void drawContext::drawView()
{
OrthofFromGModel();
glMatrixMode(GL_MODELVIEW);
// fill the background
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(_gradiant){
glPushMatrix();
glLoadIdentity();
const GLfloat squareVertices[] = {
(GLfloat)_top, (GLfloat)_left, 2*_far,
(GLfloat)_top, (GLfloat)_right, 2*_far,
(GLfloat)_bottom, (GLfloat)_left, 2*_far,
(GLfloat)_bottom, (GLfloat)_right, 2*_far,
};
const GLubyte squareColors[] = {
255, 255, 255, 255,
255, 255, 255, 255,
190, 200, 255, 255,
190, 200, 255, 255,
};
glVertexPointer(3, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
checkGlError("Draw background");
glLoadIdentity();
glScalef(_scale[0], _scale[1], _scale[2]);
glTranslatef(_translate[0], _translate[1], _translate[2]);
if(CTX::instance()->rotationCenterCg)
glTranslatef(CTX::instance()->cg[0],
CTX::instance()->cg[1],
CTX::instance()->cg[2]);
else
glTranslatef(CTX::instance()->rotationCenter[0],
CTX::instance()->rotationCenter[1],
CTX::instance()->rotationCenter[2]);
buildRotationMatrix();
glMultMatrixf(_rotatef);
if(CTX::instance()->rotationCenterCg)
glTranslatef(-CTX::instance()->cg[0],
-CTX::instance()->cg[1],
-CTX::instance()->cg[2]);
else
glTranslatef(-CTX::instance()->rotationCenter[0],
-CTX::instance()->rotationCenter[1],
-CTX::instance()->rotationCenter[2]);
checkGlError("Initialize position");
glEnable(GL_DEPTH_TEST);
drawMesh();
checkGlError("Draw mesh");
drawGeom();
checkGlError("Draw geometry");
drawPost();
checkGlError("Draw post-pro");
glDisable(GL_DEPTH_TEST);
drawScale();
checkGlError("Draw scales");
drawAxes(_right - (_top - _bottom)/15.0,
_bottom + (_top - _bottom)/15.0,
0, (_top - _bottom)/25.);
checkGlError("Draw axes");
}
std::vector<std::string> commandToVector(const std::string cmd)
{
std::vector<std::string> ret;
int pos=0, last=0;
while((pos = cmd.find("-", last+1)) != std::string::npos){
ret.push_back(cmd.substr(last,pos-1-last));
last = pos;
}
ret.push_back(cmd.substr(last,cmd.size()-1));
return ret;
}
int onelab_cb(std::string action)
{
Msg::Debug("Ask onlab to %s", action.c_str());
if(action == "stop"){
onelab::string o("GetDP/Action", "stop");
o.setVisible(false);
o.setNeverChanged(true);
onelab::server::instance()->set(o);
onelabStop = true;
return 0;
}
if(locked) return -1;
locked = true;
int redraw = 0;
if(action == "reset"){
onelab::server::instance()->clear();
onelabUtils::runGmshClient(action, true);
action = "check";
}
Msg::ResetErrorCounter();
if(action == "compute"){
onelabUtils::initializeLoop("1");
onelabUtils::initializeLoop("2");
onelabUtils::initializeLoop("3");
}
do{
if(onelabUtils::runGmshClient(action, true))
redraw = 1;
if(redraw == 0 && !onelab::server::instance()->getChanged("GetDP"))continue;
std::vector<onelab::string> ps;
onelab::server::instance()->get(ps, "GetDP/1ModelName");
if(ps.empty()){
std::vector<std::string> split = SplitFileName(GModel::current()->getFileName());
std::string name(split[0] + split[1]);
onelab::string o("GetDP/1ModelName", name, "Model name");
o.setKind("file");
onelab::server::instance()->set(o);
}
onelab::string o("GetDP/Action", action);
o.setVisible(false);
o.setNeverChanged(true);
onelab::server::instance()->set(o);
if(action == "compute" && (onelab::server::instance()->getChanged("Gmsh") ||
onelab::server::instance()->getChanged("GetDP"))){
std::string filename = GModel::current()->getFileName();
std::vector<std::string> args;
args.push_back("getdp");
std::vector<onelab::string> onelabArgs;
onelab::server::instance()->get(onelabArgs, "GetDP/1ModelName");
args.push_back((onelabArgs.empty())? SplitFileName(filename)[0] +
SplitFileName(filename)[1] : onelabArgs[0].getValue());
onelab::server::instance()->get(onelabArgs, "GetDP/9ComputeCommand");
std::vector<std::string> compute = commandToVector((onelabArgs.empty())? "" :
onelabArgs[0].getValue().c_str());
args.insert( args.end(), compute.begin(), compute.end() );
args.push_back("-onelab");
args.push_back("GetDP");
GetDP(args, onelab::server::instance());
}
if(action == "check" && (onelab::server::instance()->getChanged("Gmsh") ||
onelab::server::instance()->getChanged("GetDP"))){
std::string filename = GModel::current()->getFileName();
std::vector<std::string> args;
args.push_back("getdp");
std::vector<onelab::string> onelabArgs;
args.push_back(SplitFileName(filename)[0] + SplitFileName(filename)[1]);
onelab::server::instance()->get(onelabArgs, "GetDP/9CheckCommand");
args.push_back((onelabArgs.empty())? "" : onelabArgs[0].getValue());
args.push_back("-onelab");
args.push_back("GetDP");
GetDP(args, onelab::server::instance());
}
} while(action == "compute" && !onelabStop && (onelabUtils::incrementLoop("3") ||
onelabUtils::incrementLoop("2") ||
onelabUtils::incrementLoop("1")));
locked = false;
return redraw;
}
int number_of_animation()
{
int ret = 0;
for(unsigned int i = 0; i < PView::list.size(); i++){
PView * p = PView::list[i];
if(p->getOptions()->visible){
int numSteps = (int)p->getData()->getNumTimeSteps();
if(numSteps > ret) ret = numSteps;
}
}
return ret;
}
void set_animation(int step)
{
for(unsigned int i = 0; i < PView::list.size(); i++){
PView * p = PView::list[i];
if(p->getOptions()->visible){
p->getOptions()->timeStep = step;
p->setChanged(true);
}
}
}
int animation_next()
{
int ret = 0;
for(unsigned int i = 0; i < PView::list.size(); i++){
PView * p = PView::list[i];
if(p->getOptions()->visible){
int step = (int)p->getOptions()->timeStep + 1;
int numSteps = (int)p->getData()->getNumTimeSteps();
if(step < 0) step = numSteps - 1;
if(step > numSteps - 1) step = 0;
p->getOptions()->timeStep = step;
p->setChanged(true);
ret = step;
}
}
return ret;
}
int animation_prev()
{
int ret = 0;
for(unsigned int i = 0; i < PView::list.size(); i++){
PView * p = PView::list[i];
if(p->getOptions()->visible){
// skip empty steps
int step = (int)p->getOptions()->timeStep - 1;
int numSteps = (int)p->getData()->getNumTimeSteps();
if(step < 0) step = numSteps - 1;
if(step > numSteps - 1) step = 0;
p->getOptions()->timeStep = step;
p->setChanged(true);
ret = step;
}
}
return ret;
}