9 #include "GmshConfig.h"
24 #if defined(HAVE_FLTK)
25 #include <FL/Fl_JPEG_Image.H>
26 #include <FL/Fl_PNG_Image.H>
28 #include "openglWindow.h"
31 #if defined(HAVE_POPPLER)
46 : _transform(
transform), _openglWindow(window)
49 for(
int i = 0; i < 3; i++) {
54 for(
int i = 0; i < 4; i++) {
77 #if defined(HAVE_FLTK)
113 Msg::Error(
"Could not generate display lists");
164 double x =
r[0] * M_PI / 180.;
165 double y =
r[1] * M_PI / 180.;
166 double z =
r[2] * M_PI / 180.;
176 rot[1] = BD * E + A *
F;
177 rot[2] = -AD * E + B *
F;
180 rot[5] = -BD *
F + A * E;
181 rot[6] = AD *
F + B * E;
205 double a =
angle * M_PI / 180.;
221 double x =
r[0] * M_PI / 180.;
222 double y =
r[1] * M_PI / 180.;
223 double z =
r[2] * M_PI / 180.;
224 double xx[3] = {1., 0., 0.};
225 double yy[3] = {0., 1., 0.};
226 double zz[3] = {0., 0., 1.};
227 double q1[4], q2[4], q3[4], tmp[4];
238 double C = cos(
r[1]);
240 if(fabs(C) > 0.005) {
241 double tmpx =
rot[10] / C;
242 double tmpy = -
rot[9] / C;
243 r[0] = atan2(tmpy, tmpx) * 180. / M_PI;
246 r[2] = atan2(tmpy, tmpx) * 180. / M_PI;
250 double tmpx =
rot[5];
251 double tmpy =
rot[1];
252 r[2] = atan2(tmpy, tmpx) * 180. / M_PI;
255 if(
r[0] < 0.)
r[0] += 360.;
256 if(
r[1] < 0.)
r[1] += 360.;
257 if(
r[2] < 0.)
r[2] += 360.;
270 for(std::size_t i = 0; i <
PView::list.size(); i++) {
303 #if defined(HAVE_FLTK) && defined(__APPLE__)
306 numStrings = std::max(numStrings,
GModel::current()->getNumMeshVertices());
309 numStrings = std::max(numStrings,
GModel::current()->getNumMeshElements());
311 if(gl_texture_pile_height() < numStrings) gl_texture_pile_height(numStrings);
314 glDepthFunc(GL_LESS);
315 glEnable(GL_DEPTH_TEST);
331 glDisable(GL_DEPTH_TEST);
332 for(
int i = 0; i < 6; i++) glDisable((GLenum)(GL_CLIP_PLANE0 + i));
334 glMatrixMode(GL_PROJECTION);
346 glMatrixMode(GL_MODELVIEW);
382 glBegin(GL_TRIANGLE_FAN);
386 glVertex2d(cx +
r, cy);
388 for(
int i = 1; i < ntheta + 1; i++) {
389 double theta = i * 2 * M_PI / (double)ntheta;
390 glVertex2d(cx +
r * cos(theta), cy +
r * sin(theta));
403 GLuint &imageTexture, GLuint &imageW,
407 Msg::Error(
"Could not open file `%s'", name.c_str());
412 if(ext ==
".pdf" || ext ==
".PDF") {
413 #if defined(HAVE_POPPLER)
415 if(!gmshPopplerWrapper::instance()->loadFromFile(name)) {
416 Msg::Error(
"Could not load PDF file '%s'", name.c_str());
420 gmshPopplerWrapper::instance()->setCurrentPage(page);
421 imageTexture = gmshPopplerWrapper::instance()->getTextureForPage(300, 300);
422 imageW = gmshPopplerWrapper::instance()->width();
423 imageH = gmshPopplerWrapper::instance()->height();
425 Msg::Error(
"Gmsh must be compiled with Poppler support to load PDFs");
430 #if defined(HAVE_FLTK)
432 Fl_RGB_Image *img =
nullptr;
433 if(ext ==
".jpg" || ext ==
".JPG" || ext ==
".jpeg" || ext ==
".JPEG")
434 img =
new Fl_JPEG_Image(name.c_str());
435 else if(ext ==
".png" || ext ==
".PNG")
436 img =
new Fl_PNG_Image(name.c_str());
438 Msg::Error(
"Could not load background image '%s'", name.c_str());
441 Fl_RGB_Image *img2 = (Fl_RGB_Image *)img->copy(2048, 2048);
442 glPixelStorei(GL_UNPACK_ROW_LENGTH, img2->w());
443 glGenTextures(1, &imageTexture);
444 glBindTexture(GL_TEXTURE_2D, imageTexture);
445 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
446 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
447 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img2->w(), img2->h(), 0,
448 (img2->d() == 4) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE,
450 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
457 Msg::Error(
"Gmsh must be compiled with FLTK support to load JPEGs or PNGs");
491 else if(w < 0 && h == 0) {
498 else if(w == 0 && h < 0) {
505 else if(w == 0 && h == 0) {
516 Msg::Debug(
"Background image: x=%g y=%g w=%g h=%g", x, y, w, h);
519 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
520 glEnable(GL_TEXTURE_2D);
522 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
525 glTexCoord2f(1.0
f, 1.0
f);
526 glVertex2d(x + w, y);
527 glTexCoord2f(1.0
f, 0.0
f);
528 glVertex2d(x + w, y + h);
529 glTexCoord2f(0.0
f, 0.0
f);
530 glVertex2d(x, y + h);
531 glTexCoord2f(0.0
f, 1.0
f);
536 if(
c & 1) x -= w / 2.;
537 if(
c & 2) y += h / 2.;
540 glTexCoord2f(1.0
f, 1.0
f);
541 glVertex2d(x + w, y - h);
542 glTexCoord2f(1.0
f, 0.0
f);
543 glVertex2d(x + w, y);
544 glTexCoord2f(0.0
f, 0.0
f);
546 glTexCoord2f(0.0
f, 1.0
f);
547 glVertex2d(x, y - h);
550 glDisable(GL_TEXTURE_2D);
608 glDisable(GL_DEPTH_TEST);
613 double ratio = w / h;
616 double dz = -w * 1.25;
619 glVertex3i((
int)-dx, (
int)-dy, (
int)dz);
620 glVertex3i((
int)dx, (
int)-dy, (
int)dz);
622 glVertex3i((
int)dx, (
int)dy, (
int)dz);
623 glVertex3i((
int)-dx, (
int)dy, (
int)dz);
626 glEnable(GL_DEPTH_TEST);
630 double clip_near, clip_far;
633 clip_far = -clip_near;
640 glMatrixMode(GL_PROJECTION);
645 gluPickMatrix((GLdouble)xpick, (GLdouble)(
viewport[3] - ypick),
646 (GLdouble)wpick, (GLdouble)hpick, (GLint *)
viewport);
653 glDisable(GL_DEPTH_TEST);
660 (
double)
viewport[3], clip_near, clip_far);
661 glTranslated(0., 0., -0.99 * clip_far);
665 glTranslated(0., 0., 0.01 * clip_far);
668 glEnable(GL_DEPTH_TEST);
673 glMatrixMode(GL_MODELVIEW);
687 glMatrixMode(GL_MODELVIEW);
689 double coef = (clip_far / clip_near) / 3.;
690 glTranslated(-coef *
t_init[0], -coef *
t_init[1], -coef * clip_near);
691 glScaled(coef, coef, coef);
700 glScaled(
s[0],
s[1],
s[2]);
701 glTranslated(
t[0],
t[1],
t[2]);
703 for(
int i = 0; i < 6; i++) {
709 glLightfv((GLenum)(GL_LIGHT0 + i), GL_POSITION, position);
711 GLfloat
r = (GLfloat)(
714 GLfloat g = (GLfloat)(
717 GLfloat b = (GLfloat)(
720 GLfloat ambient[4] = {
r, g, b, 1.0F};
721 glLightfv((GLenum)(GL_LIGHT0 + i), GL_AMBIENT, ambient);
732 GLfloat diffuse[4] = {
r, g, b, 1.0F};
733 glLightfv((GLenum)(GL_LIGHT0 + i), GL_DIFFUSE, diffuse);
744 GLfloat specular[4] = {
r, g, b, 1.0F};
745 glLightfv((GLenum)(GL_LIGHT0 + i), GL_SPECULAR, specular);
747 glEnable((GLenum)(GL_LIGHT0 + i));
750 glDisable((GLenum)(GL_LIGHT0 + i));
757 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
758 glEnable(GL_COLOR_MATERIAL);
763 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
766 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS,
769 glShadeModel(GL_SMOOTH);
777 glEnable(GL_NORMALIZE);
779 glEnable(GL_RESCALE_NORMAL);
783 glDisable(GL_LIGHTING);
790 glScaled(
s[0],
s[1],
s[2]);
816 glGetDoublev(GL_PROJECTION_MATRIX,
proj);
817 glGetDoublev(GL_MODELVIEW_MATRIX,
model);
820 for(
int i = 0; i < 6; i++)
821 glClipPlane((GLenum)(GL_CLIP_PLANE0 + i),
CTX::instance()->clipPlane[i]);
835 glGetIntegerv(GL_VIEWPORT, vp);
839 GLdouble x0, y0, z0, x1, y1, z1;
844 if(!gluUnProject(winx, winy, 0.0,
model,
proj, vp, &x0, &y0, &z0))
846 if(!gluUnProject(winx, winy, 1.0,
model,
proj, vp, &x1, &y1, &z1))
855 double len = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
865 glGetIntegerv(GL_VIEWPORT,
viewport);
866 glGetDoublev(GL_PROJECTION_MATRIX,
proj);
867 glGetDoublev(GL_MODELVIEW_MATRIX,
model);
876 glGetIntegerv(GL_VIEWPORT,
viewport);
877 glGetDoublev(GL_PROJECTION_MATRIX,
proj);
878 glGetDoublev(GL_MODELVIEW_MATRIX,
model);
886 hit(GLuint t, GLuint i, GLuint d, GLuint t2 = 0, GLuint i2 = 0)
918 int y,
int w,
int h, std::vector<GVertex *> &vertices,
919 std::vector<GEdge *> &
edges,
920 std::vector<GFace *> &
faces,
921 std::vector<GRegion *> ®ions,
922 std::vector<MElement *> &elements,
923 std::vector<SPoint2> &points,
924 std::vector<PView *> &views)
943 if(!size)
return false;
947 GLuint *selectionBuffer =
new GLuint[size];
948 glSelectBuffer(size, selectionBuffer);
952 glRenderMode(GL_SELECT);
965 glMatrixMode(GL_PROJECTION);
967 gluPickMatrix((GLdouble)x, (GLdouble)(
viewport[3] - y), (GLdouble)w,
972 glMatrixMode(GL_MODELVIEW);
979 GLint numhits = glRenderMode(GL_RENDER);
983 delete[] selectionBuffer;
986 else if(numhits < 0) {
987 delete[] selectionBuffer;
993 std::vector<hit> hits;
994 GLuint *ptr = selectionBuffer;
995 for(
int i = 0; i < numhits; i++) {
1005 GLuint names = *ptr++;
1006 GLuint mindepth = *ptr++;
1007 GLuint maxdepth = *ptr++;
1010 maxdepth + 0 * mindepth;
1011 GLuint type = *ptr++;
1012 GLuint ient = *ptr++;
1013 hits.push_back(
hit(type, ient, depth));
1015 else if(names == 4) {
1017 maxdepth + 0 * mindepth;
1018 GLuint type = *ptr++;
1019 GLuint ient = *ptr++;
1020 GLuint type2 = *ptr++;
1021 GLuint ient2 = *ptr++;
1022 hits.push_back(
hit(type, ient, depth, type2, ient2));
1026 delete[] selectionBuffer;
1039 for(std::size_t i = 0; i < hits.size(); i++)
1040 typmin = std::min(typmin, hits[i].type);
1042 for(std::size_t i = 0; i < hits.size(); i++) {
1043 if((type ==
ENT_ALL) || (type ==
ENT_NONE && hits[i].type == typmin) ||
1044 (type ==
ENT_POINT && hits[i].type == 0) ||
1045 (type ==
ENT_CURVE && hits[i].type == 1) ||
1048 switch(hits[i].type) {
1052 Msg::Error(
"Problem in point selection processing");
1055 vertices.push_back(v);
1056 if(!multiple)
return true;
1061 Msg::Error(
"Problem in line selection processing");
1066 if(ele) elements.push_back(ele);
1069 if(!multiple)
return true;
1074 Msg::Error(
"Problem in surface selection processing");
1079 if(ele) elements.push_back(ele);
1082 if(!multiple)
return true;
1087 Msg::Error(
"Problem in volume selection processing");
1092 if(ele) elements.push_back(ele);
1094 regions.push_back(
r);
1095 if(!multiple)
return true;
1098 int tag = hits[i].ient;
1100 points.push_back(p);
1101 if(!multiple)
return true;
1104 int tag = hits[i].ient;
1107 if(!multiple)
return true;
1113 if(vertices.size() ||
edges.size() ||
faces.size() || regions.size() ||
1114 elements.size() || points.size() || views.size())
1122 SPoint3 &p = newRotationCenter;
1128 const double &height =
viewport[3];