diff --git a/Common/Context.h b/Common/Context.h index 017f4f8f37661ad9f667ff33b3edb1b90b7074d0..1449d1c042d3690abdd2f78f25d1e848a7ab2676 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -105,6 +105,9 @@ class CTX { double zoomFactor; // draw background gradient? int bgGradient; + // draw background image? + std::string bgImageFileName; + double bgImagePosition[2]; // fltk font size (and delta for palette windows) int fontSize, deltaFontSize; // font name, FLTK enum and size for opengl graphics @@ -201,6 +204,7 @@ class CTX { int jpegQuality, jpegSmoothing, geoLabels, text, texAsEquation; int gifDither, gifSort, gifInterlace, gifTransparent; int posElementary, posElement, posGamma, posEta, posRho, posDisto; + int compositeWindows; } print; // color options struct{ diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp index 293cab2a6348696f6542fa92bd311cbd852ce79a..c4321ec5ead11f038957e75095903a5f96b96970 100644 --- a/Common/CreateFile.cpp +++ b/Common/CreateFile.cpp @@ -14,6 +14,8 @@ #if defined(HAVE_FLTK) #include <FL/gl.h> +#include "GUI.h" +#include "graphicWindow.h" #include "gl2ps.h" #include "gl2gif.h" #include "gl2jpeg.h" @@ -101,6 +103,48 @@ std::string GetDefaultFileName(int format) return name; } +#if defined(HAVE_FLTK) +static PixelBuffer *GetCompositePixelBuffer(GLenum format, GLenum type) +{ + PixelBuffer *buffer; + if(!CTX::instance()->print.compositeWindows){ + GLint width = GUI::instance()->getCurrentOpenglWindow()->w(); + GLint height = GUI::instance()->getCurrentOpenglWindow()->h(); + buffer = new PixelBuffer(width, height, format, type); + buffer->fill(CTX::instance()->batch); + } + else{ + graphicWindow *g = GUI::instance()->graph[0]; + for(unsigned int i = 1; i < GUI::instance()->graph.size(); i++){ + for(unsigned int j = 0; j < GUI::instance()->graph[i]->gl.size(); j++){ + if(GUI::instance()->graph[i]->gl[j] == + GUI::instance()->getCurrentOpenglWindow()){ + g = GUI::instance()->graph[i]; + break; + } + } + } + int ww = 0, hh = 0; + std::vector<PixelBuffer*> buffers; + for(unsigned int i = 0; i < g->gl.size(); i++){ + openglWindow::setLastHandled(g->gl[i]); + buffer = new PixelBuffer(g->gl[i]->w(), g->gl[i]->h(), format, type); + buffer->fill(CTX::instance()->batch); + buffers.push_back(buffer); + ww = std::max(ww, g->gl[i]->x() + g->gl[i]->w()); + hh = std::max(hh, g->gl[i]->y() + g->gl[i]->h()); + } + buffer = new PixelBuffer(ww, hh, format, type); + for(unsigned int i = 0; i < g->gl.size(); i++){ + buffer->copyPixels(g->gl[i]->x(), hh - g->gl[i]->h() - g->gl[i]->y(), + buffers[i]); + delete buffers[i]; + } + } + return buffer; +} +#endif + void CreateOutputFile(std::string fileName, int format) { if(fileName.empty()) @@ -113,15 +157,6 @@ void CreateOutputFile(std::string fileName, int format) CTX::instance()->print.format = format; CTX::instance()->printing = 1; -#if defined(HAVE_FLTK) - int vp[4]; - GetCurrentOpenglWindowViewport(vp); - GLint viewport[4]; - for(int i = 0; i < 4; i++) viewport[i] = vp[i]; - GLint width = viewport[2] - viewport[0]; - GLint height = viewport[3] - viewport[1]; -#endif - bool printEndMessage = true; if(format != FORMAT_AUTO) Msg::StatusBar(2, true, "Writing '%s'", fileName.c_str()); @@ -221,28 +256,28 @@ void CreateOutputFile(std::string fileName, int format) case FORMAT_JPEG: case FORMAT_PNG: { + if(!GUI::available()) break; + FILE *fp = fopen(fileName.c_str(), "wb"); if(!fp){ Msg::Error("Unable to open file '%s'", fileName.c_str()); break; } - PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE); - int old_gradient = CTX::instance()->bgGradient; if(format == FORMAT_GIF && CTX::instance()->print.gifTransparent) CTX::instance()->bgGradient = 0; - buffer.Fill(CTX::instance()->batch); + + PixelBuffer *buffer = GetCompositePixelBuffer(GL_RGB, GL_UNSIGNED_BYTE); + CTX::instance()->bgGradient = old_gradient; - if(format == FORMAT_PPM){ - create_ppm(fp, &buffer); - } - else if(format == FORMAT_YUV){ - create_yuv(fp, &buffer); - } - else if(format == FORMAT_GIF){ - create_gif(fp, &buffer, + if(format == FORMAT_PPM) + create_ppm(fp, buffer); + else if(format == FORMAT_YUV) + create_yuv(fp, buffer); + else if(format == FORMAT_GIF) + create_gif(fp, buffer, CTX::instance()->print.gifDither, CTX::instance()->print.gifSort, CTX::instance()->print.gifInterlace, @@ -250,14 +285,13 @@ void CreateOutputFile(std::string fileName, int format) CTX::instance()->unpackRed(CTX::instance()->color.bg), CTX::instance()->unpackGreen(CTX::instance()->color.bg), CTX::instance()->unpackBlue(CTX::instance()->color.bg)); - } - else if(format == FORMAT_JPEG){ - create_jpeg(fp, &buffer, CTX::instance()->print.jpegQuality, + else if(format == FORMAT_JPEG) + create_jpeg(fp, buffer, CTX::instance()->print.jpegQuality, CTX::instance()->print.jpegSmoothing); - } - else{ - create_png(fp, &buffer, 100); - } + else + create_png(fp, buffer, 100); + + delete buffer; fclose(fp); } break; @@ -267,27 +301,17 @@ void CreateOutputFile(std::string fileName, int format) case FORMAT_PDF: case FORMAT_SVG: { + if(!GUI::available()) break; + FILE *fp = fopen(fileName.c_str(), "wb"); if(!fp){ Msg::Error("Unable to open file '%s'", fileName.c_str()); break; } - - int psformat; - switch(format){ - case FORMAT_PDF: - psformat = GL2PS_PDF; - break; - case FORMAT_PS: - psformat = GL2PS_PS; - break; - case FORMAT_SVG: - psformat = GL2PS_SVG; - break; - default: - psformat = GL2PS_EPS; - break; - } + + GLint width = GUI::instance()->getCurrentOpenglWindow()->w(); + GLint height = GUI::instance()->getCurrentOpenglWindow()->h(); + GLint viewport[4] = {0, 0, width, height}; int old_gradient = CTX::instance()->bgGradient; if(!CTX::instance()->print.epsBackground) CTX::instance()->bgGradient = 0; @@ -295,8 +319,13 @@ void CreateOutputFile(std::string fileName, int format) PixelBuffer buffer(width, height, GL_RGB, GL_FLOAT); if(CTX::instance()->print.epsQuality == 0) - buffer.Fill(CTX::instance()->batch); + buffer.fill(CTX::instance()->batch); + int psformat = + (format == FORMAT_PDF) ? GL2PS_PDF : + (format == FORMAT_PS) ? GL2PS_PS : + (format == FORMAT_SVG) ? GL2PS_SVG : + GL2PS_EPS; int pssort = (CTX::instance()->print.epsQuality == 3) ? GL2PS_NO_SORT : (CTX::instance()->print.epsQuality == 2) ? GL2PS_BSP_SORT : @@ -327,14 +356,14 @@ void CreateOutputFile(std::string fileName, int format) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRasterPos2d(0, 0); - gl2psDrawPixels(width, height, 0, 0, GL_RGB, GL_FLOAT, buffer.GetPixels()); + gl2psDrawPixels(width, height, 0, 0, GL_RGB, GL_FLOAT, buffer.getPixels()); glMatrixMode(GL_PROJECTION); glLoadMatrixd(projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixd(modelview); } else{ - buffer.Fill(CTX::instance()->batch); + buffer.fill(CTX::instance()->batch); } res = gl2psEndPage(); } @@ -346,11 +375,16 @@ void CreateOutputFile(std::string fileName, int format) case FORMAT_TEX: { + if(!GUI::available()) break; + FILE *fp = fopen(fileName.c_str(), "w"); if(!fp){ Msg::Error("Unable to open file '%s'", fileName.c_str()); break; } + GLint width = GUI::instance()->getCurrentOpenglWindow()->w(); + GLint height = GUI::instance()->getCurrentOpenglWindow()->h(); + GLint viewport[4] = {0, 0, width, height}; GLint buffsize = 0; int res = GL2PS_OVERFLOW; while(res == GL2PS_OVERFLOW) { @@ -361,7 +395,7 @@ void CreateOutputFile(std::string fileName, int format) PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE); int oldtext = CTX::instance()->print.text; CTX::instance()->print.text = 1; - buffer.Fill(CTX::instance()->batch); + buffer.fill(CTX::instance()->batch); CTX::instance()->print.text = oldtext; res = gl2psEndPage(); } diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index c8d6785bb75c7f6ed503163cf596b58d1cdee869..50b4e6ea01ccee479bd1aafbc0da1dae4d11557a 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -38,6 +38,9 @@ StringXString GeneralOptions_String[] = { { F|O, "AxesLabelZ" , opt_general_axes_label2 , "" , "Z-axis label" }, + { F|O, "BackgroundImageFileName" , opt_general_background_image_filename , "" , + "Background image file in JPEG or PNG format" }, + { F|O, "DefaultFileName" , opt_general_default_filename , "untitled.geo" , "Default project file name" }, { F, "Display" , opt_general_display , "" , @@ -459,6 +462,10 @@ StringXNumber GeneralOptions_Number[] = { { F|O, "BackgroundGradient" , opt_general_background_gradient , 1. , "Draw background gradient (0=none, 1=vertical, 2=horizontal, 3=radial)" }, + { F|O, "BackgroundImagePositionX" , opt_general_background_image_position0 , 1.e5 , + "X position (in pixels) of background image (< 0: right alignment; > 1e5: centered)" }, + { F|O, "BackgroundImagePositionY" , opt_general_background_image_position1 , 1.e5 , + "Y position (in pixels) of background image (< 0: right alignment; > 1e5: centered)" }, { F, "Clip0A" , opt_general_clip0a , 1.0 , "First coefficient in equation for clipping plane 0 (`A' in `AX+BY+CZ+D=0')" }, @@ -468,23 +475,23 @@ StringXNumber GeneralOptions_Number[] = { "Third coefficient in equation for clipping plane 0 (`C' in `AX+BY+CZ+D=0')" }, { F, "Clip0D" , opt_general_clip0d , 0.0 , "Fourth coefficient in equation for clipping plane 0 (`D' in `AX+BY+CZ+D=0')" }, - { F, "Clip1A" , opt_general_clip1a , 1.0 , + { F, "Clip1A" , opt_general_clip1a , 0.0 , "First coefficient in equation for clipping plane 1" }, - { F, "Clip1B" , opt_general_clip1b , 0.0 , + { F, "Clip1B" , opt_general_clip1b , 1.0 , "Second coefficient in equation for clipping plane 1" }, { F, "Clip1C" , opt_general_clip1c , 0.0 , "Third coefficient in equation for clipping plane 1" }, { F, "Clip1D" , opt_general_clip1d , 0.0 , "Fourth coefficient in equation for clipping plane 1" }, - { F, "Clip2A" , opt_general_clip2a , 1.0 , + { F, "Clip2A" , opt_general_clip2a , 0.0 , "First coefficient in equation for clipping plane 2" }, { F, "Clip2B" , opt_general_clip2b , 0.0 , "Second coefficient in equation for clipping plane 2" }, - { F, "Clip2C" , opt_general_clip2c , 0.0 , + { F, "Clip2C" , opt_general_clip2c , 1.0 , "Third coefficient in equation for clipping plane 2" }, { F, "Clip2D" , opt_general_clip2d , 0.0 , "Fourth coefficient in equation for clipping plane 2" }, - { F, "Clip3A" , opt_general_clip3a , 1.0 , + { F, "Clip3A" , opt_general_clip3a , -1.0 , "First coefficient in equation for clipping plane 3" }, { F, "Clip3B" , opt_general_clip3b , 0.0 , "Second coefficient in equation for clipping plane 3" }, @@ -492,19 +499,19 @@ StringXNumber GeneralOptions_Number[] = { "Third coefficient in equation for clipping plane 3" }, { F, "Clip3D" , opt_general_clip3d , 0.0 , "Fourth coefficient in equation for clipping plane 3" }, - { F, "Clip4A" , opt_general_clip4a , 1.0 , + { F, "Clip4A" , opt_general_clip4a , 0.0 , "First coefficient in equation for clipping plane 4" }, - { F, "Clip4B" , opt_general_clip4b , 0.0 , + { F, "Clip4B" , opt_general_clip4b , -1.0 , "Second coefficient in equation for clipping plane 4" }, { F, "Clip4C" , opt_general_clip4c , 0.0 , "Third coefficient in equation for clipping plane 4" }, { F, "Clip4D" , opt_general_clip4d , 0.0 , "Fourth coefficient in equation for clipping plane 4" }, - { F, "Clip5A" , opt_general_clip5a , 1.0 , + { F, "Clip5A" , opt_general_clip5a , 0.0 , "First coefficient in equation for clipping plane 5" }, { F, "Clip5B" , opt_general_clip5b , 0.0 , "Second coefficient in equation for clipping plane 5" }, - { F, "Clip5C" , opt_general_clip5c , 0.0 , + { F, "Clip5C" , opt_general_clip5c , -1.0 , "Third coefficient in equation for clipping plane 5" }, { F, "Clip5D" , opt_general_clip5d , 0.0 , "Fourth coefficient in equation for clipping plane 5" }, @@ -736,9 +743,9 @@ StringXNumber GeneralOptions_Number[] = { { F|O, "SmallAxes" , opt_general_small_axes , 1. , "Display the small axes" }, { F|O, "SmallAxesPositionX" , opt_general_small_axes_position0 , -60. , - "X position of small axes (use negative values for right alignment)" }, + "X position (in pixels) of small axes (< 0: right alignment; > 1e5: centered)" }, { F|O, "SmallAxesPositionY" , opt_general_small_axes_position1 , -40. , - "Y position of small axes (use negative values for bottom alignment)" }, + "Y position (in pixels) of small axes (< 0: right alignment; > 1e5: centered)" }, { F|O, "SmallAxesSize" , opt_general_small_axes_size , 30. , "Size (in pixels) of small axes" }, { F|S, "SolverPositionX" , opt_general_solver_position0 , 650. , @@ -1378,9 +1385,9 @@ StringXNumber ViewOptions_Number[] = { { F|O, "PointType" , opt_view_point_type , 0. , "Display points as solid color dots (0), 3D spheres (1), scaled dots (2) or scaled spheres (3)" }, { F|O, "PositionX" , opt_view_position0 , 100. , - "Horizontal position (in pixels) of the upper left corner of the scale or 2D plot" }, + "X position (in pixels) of the scale or 2D plot (< 0: right alignment; > 1e5: centered)" }, { F|O, "PositionY" , opt_view_position1 , 50. , - "Vertical position (in pixels) of the upper left corner of the scale or 2D plot" }, + "Y position (in pixels) of the scale or 2D plot (< 0: right alignment; > 1e5: centered)" }, { F, "RaiseX" , opt_view_raise0 , 0. , "Elevation of the view along X-axis (in model coordinates)" }, @@ -1450,6 +1457,9 @@ StringXNumber ViewOptions_Number[] = { } ; StringXNumber PrintOptions_Number[] = { + { F|O, "CompositeWindows" , opt_print_composite_windows , 0. , + "Composite all window tiles in the same output image (for bitmap output only)" }, + { F|O, "EpsBackground" , opt_print_eps_background , 1. , "Save image background in PostScript/PDF output" }, { F|O, "EpsBestRoot" , opt_print_eps_best_root , 1. , diff --git a/Common/Makefile b/Common/Makefile index 76d0e6f3126471de32bef99d078d2519a15bcdb2..407bc019d1943e36f291895c477ac6454be22041 100644 --- a/Common/Makefile +++ b/Common/Makefile @@ -141,9 +141,10 @@ CreateFile${OBJEXT}: CreateFile.cpp GmshConfig.h GmshMessage.h ../Geo/GModel.h \ ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \ ../Geo/SBoundingBox3d.h GmshDefines.h StringUtils.h Context.h \ ../Geo/CGNSOptions.h ../Mesh/meshPartitionOptions.h Options.h \ - ../Post/ColorTable.h ../Graphics/gl2ps.h ../Common/GmshConfig.h \ - ../Graphics/gl2gif.h ../Graphics/PixelBuffer.h ../Common/GmshMessage.h \ - ../Fltk/Draw.h ../Common/MallocUtils.h ../Graphics/gl2jpeg.h \ + ../Post/ColorTable.h ../Fltk/GUI.h ../Fltk/graphicWindow.h \ + ../Fltk/openglWindow.h ../Graphics/drawContext.h ../Graphics/gl2ps.h \ + ../Common/GmshConfig.h ../Graphics/gl2gif.h ../Graphics/PixelBuffer.h \ + ../Common/GmshMessage.h ../Fltk/Draw.h ../Graphics/gl2jpeg.h \ ../Graphics/PixelBuffer.h ../Graphics/gl2png.h \ ../Graphics/PixelBuffer.h ../Graphics/gl2ppm.h \ ../Graphics/PixelBuffer.h ../Graphics/gl2yuv.h \ diff --git a/Common/Options.cpp b/Common/Options.cpp index 3b96d68f4f827735b4039147151bcecaa47b243b..5d0582fd052f6e1c48330725081c262433177103 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -931,6 +931,13 @@ std::string opt_general_display(OPT_ARGS_STR) return CTX::instance()->display; } +std::string opt_general_background_image_filename(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX::instance()->bgImageFileName = val; + return CTX::instance()->bgImageFileName; +} + std::string opt_general_filename(OPT_ARGS_STR) { return GModel::current()->getFileName(); @@ -3530,6 +3537,20 @@ double opt_general_background_gradient(OPT_ARGS_NUM) return CTX::instance()->bgGradient; } +double opt_general_background_image_position0(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX::instance()->bgImagePosition[0] = val; + return CTX::instance()->bgImagePosition[0]; +} + +double opt_general_background_image_position1(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX::instance()->bgImagePosition[1] = val; + return CTX::instance()->bgImagePosition[1]; +} + double opt_general_trackball(OPT_ARGS_NUM) { if(action & GMSH_SET) @@ -8280,6 +8301,13 @@ double opt_print_tex_as_equation(OPT_ARGS_NUM) return CTX::instance()->print.texAsEquation; } +double opt_print_composite_windows(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX::instance()->print.compositeWindows = (int)val; + return CTX::instance()->print.compositeWindows; +} + // Color option routines #if defined(HAVE_FLTK) diff --git a/Common/Options.h b/Common/Options.h index bbe99a21e1cffb0e004872d5ef3ade965dcf7020..d164e4ffb5f1e41258a5708ddd522c7417980ad7 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -31,6 +31,7 @@ std::string opt_general_axes_label2(OPT_ARGS_STR); std::string opt_general_axes_format0(OPT_ARGS_STR); std::string opt_general_axes_format1(OPT_ARGS_STR); std::string opt_general_axes_format2(OPT_ARGS_STR); +std::string opt_general_background_image_filename(OPT_ARGS_STR); std::string opt_general_display(OPT_ARGS_STR); std::string opt_general_filename(OPT_ARGS_STR); std::string opt_general_default_filename(OPT_ARGS_STR); @@ -279,6 +280,8 @@ double opt_general_shine(OPT_ARGS_NUM); double opt_general_shine_exponent(OPT_ARGS_NUM); double opt_general_color_scheme(OPT_ARGS_NUM); double opt_general_background_gradient(OPT_ARGS_NUM); +double opt_general_background_image_position0(OPT_ARGS_NUM); +double opt_general_background_image_position1(OPT_ARGS_NUM); double opt_general_verbosity(OPT_ARGS_NUM); double opt_general_nopopup(OPT_ARGS_NUM); double opt_general_non_modal_windows(OPT_ARGS_NUM); @@ -693,6 +696,7 @@ double opt_print_gif_interlace(OPT_ARGS_NUM); double opt_print_gif_transparent(OPT_ARGS_NUM); double opt_print_text(OPT_ARGS_NUM); double opt_print_tex_as_equation(OPT_ARGS_NUM); +double opt_print_composite_windows(OPT_ARGS_NUM); // COLORS diff --git a/Fltk/Draw.cpp b/Fltk/Draw.cpp index 6107cb186d46fc6aab9e462f111ceae278dc469a..ba21c826a2ac99588bc4e1f9f0cb4b31c5114c49 100644 --- a/Fltk/Draw.cpp +++ b/Fltk/Draw.cpp @@ -56,14 +56,6 @@ void DrawCurrentOpenglWindow(bool make_current) gl->getDrawContext()->draw2d(); } -void GetCurrentOpenglWindowViewport(int viewport[4]) -{ - if(!GUI::available()) return; - openglWindow *gl = GUI::instance()->getCurrentOpenglWindow(); - for(int i = 0; i < 4; i++) - viewport[i] = gl->getDrawContext()->viewport[i]; -} - int GetFontIndex(const char *fontname) { if(fontname){ diff --git a/Fltk/Draw.h b/Fltk/Draw.h index defebfd35d16052d5c467970a0b5d0e4c40ebbaf..6206230767da154fd1e0ea1736eb186a2cacd826 100644 --- a/Fltk/Draw.h +++ b/Fltk/Draw.h @@ -11,7 +11,6 @@ void Draw(); void DrawPlugin(void (*draw)(void *context)); void DrawCurrentOpenglWindow(bool make_current); -void GetCurrentOpenglWindowViewport(int viewport[4]); int GetFontIndex(const char *fontname); int GetFontEnum(int index); const char *GetFontName(int index); diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp index 1ecbb9f25bb0fcecb56da12fa74a87a7ce36f0e3..5d4aaeff6784ea4663d6ff215223f11368d87cb8 100644 --- a/Fltk/fileDialogs.cpp +++ b/Fltk/fileDialogs.cpp @@ -133,20 +133,23 @@ int generic_bitmap_dialog(const char *name, const char *title, int format) { struct _generic_bitmap_dialog{ Fl_Window *window; - Fl_Check_Button *b; + Fl_Check_Button *b[2]; Fl_Button *ok, *cancel; }; static _generic_bitmap_dialog *dialog = NULL; if(!dialog){ dialog = new _generic_bitmap_dialog; - int h = 3 * WB + 2 * BH, w = 2 * BB + 3 * WB, y = WB; + int h = 3 * WB + 3 * BH, w = 2 * BB + 3 * WB, y = WB; dialog->window = new Fl_Double_Window(w, h); dialog->window->box(GMSH_WINDOW_BOX); dialog->window->set_modal(); - dialog->b = new Fl_Check_Button + dialog->b[0] = new Fl_Check_Button (WB, y, 2 * BB + WB, BH, "Print text strings"); y += BH; - dialog->b->type(FL_TOGGLE_BUTTON); + dialog->b[0]->type(FL_TOGGLE_BUTTON); + dialog->b[1] = new Fl_Check_Button + (WB, y, 2 * BB + WB, BH, "Composite all window tiles"); y += BH; + dialog->b[1]->type(FL_TOGGLE_BUTTON); dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK"); dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel"); dialog->window->end(); @@ -154,7 +157,8 @@ int generic_bitmap_dialog(const char *name, const char *title, int format) } dialog->window->label(title); - dialog->b->value(CTX::instance()->print.text); + dialog->b[0]->value(CTX::instance()->print.text); + dialog->b[1]->value(CTX::instance()->print.compositeWindows); dialog->window->show(); while(dialog->window->shown()){ @@ -163,7 +167,8 @@ int generic_bitmap_dialog(const char *name, const char *title, int format) Fl_Widget* o = Fl::readqueue(); if (!o) break; if (o == dialog->ok) { - opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b->value()); + opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b[0]->value()); + opt_print_composite_windows(0, GMSH_SET | GMSH_GUI, (int)dialog->b[1]->value()); CreateOutputFile(name, format); dialog->window->hide(); return 1; @@ -233,14 +238,14 @@ int jpeg_dialog(const char *name) struct _jpeg_dialog{ Fl_Window *window; Fl_Value_Slider *s[2]; - Fl_Check_Button *b; + Fl_Check_Button *b[2]; Fl_Button *ok, *cancel; }; static _jpeg_dialog *dialog = NULL; if(!dialog){ dialog = new _jpeg_dialog; - int h = 3 * WB + 4 * BH, w = 2 * BB + 3 * WB, y = WB; + int h = 3 * WB + 5 * BH, w = 2 * BB + 3 * WB, y = WB; dialog->window = new Fl_Double_Window(w, h, "JPEG Options"); dialog->window->box(GMSH_WINDOW_BOX); dialog->window->set_modal(); @@ -256,9 +261,12 @@ int jpeg_dialog(const char *name) dialog->s[1]->minimum(0); dialog->s[1]->maximum(100); dialog->s[1]->step(1); - dialog->b = new Fl_Check_Button + dialog->b[0] = new Fl_Check_Button (WB, y, 2 * BB + WB, BH, "Print text strings"); y += BH; - dialog->b->type(FL_TOGGLE_BUTTON); + dialog->b[0]->type(FL_TOGGLE_BUTTON); + dialog->b[1] = new Fl_Check_Button + (WB, y, 2 * BB + WB, BH, "Composite all window tiles"); y += BH; + dialog->b[1]->type(FL_TOGGLE_BUTTON); dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK"); dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel"); dialog->window->end(); @@ -267,7 +275,8 @@ int jpeg_dialog(const char *name) dialog->s[0]->value(CTX::instance()->print.jpegQuality); dialog->s[1]->value(CTX::instance()->print.jpegSmoothing); - dialog->b->value(CTX::instance()->print.text); + dialog->b[0]->value(CTX::instance()->print.text); + dialog->b[1]->value(CTX::instance()->print.compositeWindows); dialog->window->show(); while(dialog->window->shown()){ @@ -278,7 +287,8 @@ int jpeg_dialog(const char *name) if (o == dialog->ok) { opt_print_jpeg_quality(0, GMSH_SET | GMSH_GUI, (int)dialog->s[0]->value()); opt_print_jpeg_smoothing(0, GMSH_SET | GMSH_GUI, (int)dialog->s[1]->value()); - opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b->value()); + opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b[0]->value()); + opt_print_composite_windows(0, GMSH_SET | GMSH_GUI, (int)dialog->b[1]->value()); CreateOutputFile(name, FORMAT_JPEG); dialog->window->hide(); return 1; @@ -298,14 +308,14 @@ int gif_dialog(const char *name) { struct _gif_dialog{ Fl_Window *window; - Fl_Check_Button *b[5]; + Fl_Check_Button *b[6]; Fl_Button *ok, *cancel; }; static _gif_dialog *dialog = NULL; if(!dialog){ dialog = new _gif_dialog; - int h = 3 * WB + 6 * BH, w = 2 * BB + 3 * WB, y = WB; + int h = 3 * WB + 7 * BH, w = 2 * BB + 3 * WB, y = WB; dialog->window = new Fl_Double_Window(w, h, "GIF Options"); dialog->window->box(GMSH_WINDOW_BOX); dialog->window->set_modal(); @@ -319,7 +329,9 @@ int gif_dialog(const char *name) (WB, y, 2 * BB + WB, BH, "Transparent background"); y += BH; dialog->b[4] = new Fl_Check_Button (WB, y, 2 * BB + WB, BH, "Print text strings"); y += BH; - for(int i = 0; i < 5; i++){ + dialog->b[5] = new Fl_Check_Button + (WB, y, 2 * BB + WB, BH, "Composite all window tiles"); y += BH; + for(int i = 0; i < 6; i++){ dialog->b[i]->type(FL_TOGGLE_BUTTON); } dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK"); @@ -333,6 +345,7 @@ int gif_dialog(const char *name) dialog->b[2]->value(CTX::instance()->print.gifSort); dialog->b[3]->value(CTX::instance()->print.gifTransparent); dialog->b[4]->value(CTX::instance()->print.text); + dialog->b[5]->value(CTX::instance()->print.compositeWindows); dialog->window->show(); while(dialog->window->shown()){ @@ -346,6 +359,7 @@ int gif_dialog(const char *name) opt_print_gif_sort(0, GMSH_SET | GMSH_GUI, dialog->b[2]->value()); opt_print_gif_transparent(0, GMSH_SET | GMSH_GUI, dialog->b[3]->value()); opt_print_text(0, GMSH_SET | GMSH_GUI, dialog->b[4]->value()); + opt_print_composite_windows(0, GMSH_SET | GMSH_GUI, dialog->b[5]->value()); CreateOutputFile(name, FORMAT_GIF); dialog->window->hide(); return 1; diff --git a/Fltk/partitionDialog.cpp b/Fltk/partitionDialog.cpp index 988b9715bc24867e05c0bdacbdaa1e001ce74d67..58734d7c409d01b2611435933b9b2c4ab2732131 100644 --- a/Fltk/partitionDialog.cpp +++ b/Fltk/partitionDialog.cpp @@ -776,7 +776,7 @@ void partition_dialog() void partition_dialog() { - Msg::Error("Gmsh has to be compiled with METIS or CHACO support to partition meshes"); + Msg::Error("Gmsh must be compiled with METIS or CHACO support to partition meshes"); } #endif diff --git a/Geo/GModelIO_Fourier.cpp b/Geo/GModelIO_Fourier.cpp index 83f9fa43617f44736219e606cb1878d53fbb81d1..db25e3f2807728501e26d94988527bf0ed99d70b 100644 --- a/Geo/GModelIO_Fourier.cpp +++ b/Geo/GModelIO_Fourier.cpp @@ -144,14 +144,14 @@ void GModel::_deleteFMInternals() int GModel::readFourier(const std::string &fn) { - Msg::Error("Gmsh has to be compiled with Fourier Model support to load '%s'", + Msg::Error("Gmsh must be compiled with Fourier Model support to load '%s'", fn.c_str()); return 0; } int GModel::writeFourier(const std::string &fn) { - Msg::Error("Gmsh has to be compiled with Fourier Model support to load '%s'", + Msg::Error("Gmsh must be compiled with Fourier Model support to load '%s'", fn.c_str()); return 0; } diff --git a/Geo/GModelIO_MED.cpp b/Geo/GModelIO_MED.cpp index a64173cf779209062776dad2ea726221328226ac..3a75713fe2e9d21a7035e5f979bbebbc2cd22073 100644 --- a/Geo/GModelIO_MED.cpp +++ b/Geo/GModelIO_MED.cpp @@ -526,21 +526,21 @@ int GModel::writeMED(const std::string &name, bool saveAll, double scalingFactor int GModel::readMED(const std::string &name) { - Msg::Error("Gmsh has to be compiled with MED support to read '%s'", + Msg::Error("Gmsh must be compiled with MED support to read '%s'", name.c_str()); return 0; } int GModel::readMED(const std::string &name, int meshIndex) { - Msg::Error("Gmsh has to be compiled with MED support to read '%s'", + Msg::Error("Gmsh must be compiled with MED support to read '%s'", name.c_str()); return 0; } int GModel::writeMED(const std::string &name, bool saveAll, double scalingFactor) { - Msg::Error("Gmsh has to be compiled with MED support to write '%s'", + Msg::Error("Gmsh must be compiled with MED support to write '%s'", name.c_str()); return 0; } diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp index 71133a89f2951ef5d11c68a9f845a5c860446872..76ce32ffa4b4d2930f0044b523fadd734ba8804a 100644 --- a/Geo/GModelIO_OCC.cpp +++ b/Geo/GModelIO_OCC.cpp @@ -699,28 +699,28 @@ void GModel::_deleteOCCInternals() int GModel::readOCCSTEP(const std::string &fn) { - Msg::Error("Gmsh has to be compiled with OpenCascade support to load '%s'", + Msg::Error("Gmsh must be compiled with OpenCascade support to load '%s'", fn.c_str()); return 0; } int GModel::readOCCIGES(const std::string &fn) { - Msg::Error("Gmsh has to be compiled with OpenCascade support to load '%s'", + Msg::Error("Gmsh must be compiled with OpenCascade support to load '%s'", fn.c_str()); return 0; } int GModel::readOCCBREP(const std::string &fn) { - Msg::Error("Gmsh has to be compiled with OpenCascade support to load '%s'", + Msg::Error("Gmsh must be compiled with OpenCascade support to load '%s'", fn.c_str()); return 0; } int GModel::importOCCShape(const void *shape, const void *options) { - Msg::Error("Gmsh has to be compiled with OpenCascade support to import " + Msg::Error("Gmsh must be compiled with OpenCascade support to import " "a TopoDS_Shape"); return 0; } diff --git a/Graphics/Makefile b/Graphics/Makefile index b9ba433e4f1ef4a00f41ff6e15fd6e8e18bff139..3e5c659c2315c148d9a456518c19512849fba54b 100644 --- a/Graphics/Makefile +++ b/Graphics/Makefile @@ -145,10 +145,10 @@ gl2ps${OBJEXT}: gl2ps.cpp gl2ps.h ../Common/GmshConfig.h gl2gif${OBJEXT}: gl2gif.cpp ../Common/MallocUtils.h gl2gif.h PixelBuffer.h \ ../Common/GmshConfig.h ../Common/GmshMessage.h ../Fltk/Draw.h gl2jpeg${OBJEXT}: gl2jpeg.cpp ../Common/GmshConfig.h gl2jpeg.h PixelBuffer.h \ - ../Common/GmshMessage.h ../Fltk/Draw.h ../Common/MallocUtils.h + ../Common/GmshMessage.h ../Fltk/Draw.h gl2png${OBJEXT}: gl2png.cpp ../Common/GmshConfig.h gl2png.h PixelBuffer.h \ - ../Common/GmshMessage.h ../Fltk/Draw.h ../Common/MallocUtils.h + ../Common/GmshMessage.h ../Fltk/Draw.h gl2ppm${OBJEXT}: gl2ppm.cpp gl2ppm.h PixelBuffer.h ../Common/GmshConfig.h \ - ../Common/GmshMessage.h ../Fltk/Draw.h ../Common/MallocUtils.h + ../Common/GmshMessage.h ../Fltk/Draw.h gl2yuv${OBJEXT}: gl2yuv.cpp ../Common/MallocUtils.h gl2yuv.h PixelBuffer.h \ ../Common/GmshConfig.h ../Common/GmshMessage.h ../Fltk/Draw.h diff --git a/Graphics/PixelBuffer.h b/Graphics/PixelBuffer.h index a00e2e26217ed4fa1c303798c39df8461a90b0bd..1b69d882214334184a56553e8345f4a86958a164 100644 --- a/Graphics/PixelBuffer.h +++ b/Graphics/PixelBuffer.h @@ -6,11 +6,11 @@ #ifndef _PIXEL_BUFFER_H_ #define _PIXEL_BUFFER_H_ +#include <string.h> #include <FL/gl.h> #include "GmshConfig.h" #include "GmshMessage.h" #include "Draw.h" -#include "MallocUtils.h" #if defined(HAVE_OSMESA) #include <GL/osmesa.h> @@ -20,7 +20,7 @@ class PixelBuffer{ private: int _width, _height, _numComp, _dataSize; GLenum _format, _type; - void *_pixels; + unsigned char *_pixels; public: PixelBuffer(int width, int height, GLenum format, GLenum type) : _width(width), _height(height), _format(format), _type(type) @@ -48,27 +48,46 @@ class PixelBuffer{ _type = GL_UNSIGNED_BYTE; _dataSize = sizeof(unsigned char); } - _pixels = Calloc(_numComp * _width * _height, _dataSize); + int n = _numComp * _width * _height * _dataSize; + _pixels = new unsigned char[n]; + for(int i = 0; i < n; i++) _pixels[i] = 0; } ~PixelBuffer() { - Free(_pixels); + delete [] _pixels; } - int GetWidth(){ return _width; } - int GetHeight(){ return _height; } - int GetNumComp(){ return _numComp; } - int GetDataSize(){ return _dataSize; } - GLenum GetFormat(){ return _format; } - GLenum GetType(){ return _type; } - void *GetPixels(){ return _pixels; } - void Fill(int offscreen) + int getWidth(){ return _width; } + int getHeight(){ return _height; } + int getNumComp(){ return _numComp; } + int getDataSize(){ return _dataSize; } + GLenum getFormat(){ return _format; } + GLenum getType(){ return _type; } + void *getPixels(){ return (void*)_pixels; } + void copyPixels(int x, int y, PixelBuffer *buffer) + { + if(x + buffer->getWidth() > _width || y + buffer->getHeight() > _height){ + Msg::Error("Destination pixel buffer too small for holding copy"); + return; + } + if(buffer->getNumComp() != _numComp || buffer->getDataSize() != _dataSize || + buffer->getFormat() != _format || buffer->getType() != _type){ + Msg::Error("Pixel buffer type mismatch: impossible to copy"); + return; + } + for(int i = 0; i < buffer->getWidth(); i++) + for(int j = 0; j < buffer->getHeight(); j++) + memcpy(_pixels + ((j + y) * _width + (i + x)) * _dataSize * _numComp, + (unsigned char*)buffer->getPixels() + (j * buffer->getWidth() + i) * + _dataSize * _numComp, _dataSize * _numComp); + } + void fill(int offscreen) { if(!offscreen){ DrawCurrentOpenglWindow(true); glFinish(); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glReadPixels(0, 0, _width, _height, _format, _type, _pixels); + glReadPixels(0, 0, _width, _height, _format, _type, (void*)_pixels); } else{ #if defined(HAVE_OSMESA) @@ -81,14 +100,14 @@ class PixelBuffer{ Msg::Error("OSMesaCreateContext failed"); return; } - if(!OSMesaMakeCurrent(ctx, _pixels, GL_UNSIGNED_BYTE, _width, _height)){ + if(!OSMesaMakeCurrent(ctx, (void*)_pixels, GL_UNSIGNED_BYTE, _width, _height)){ Msg::Error("OSMesaMakeCurrent failed"); } DrawCurrentOpenglWindow(false); glFinish(); OSMesaDestroyContext(ctx); #else - Msg::Warning("Offscreen rendering not available in this version"); + Msg::Warning("Gmsh must be compiled with OSMesa to support offscreen rendering"); #endif } } diff --git a/Graphics/ReadImg.cpp b/Graphics/ReadImg.cpp index b52e60e62a073d9f1a902f20aefd5341893da3a0..68d97ea87c5c6e110d254c54c020666a57cbc23c 100644 --- a/Graphics/ReadImg.cpp +++ b/Graphics/ReadImg.cpp @@ -21,13 +21,13 @@ static PViewDataList *Img2Data(Fl_RGB_Image &img_init, int quads=1, img_init.desaturate(); // convert to grayscale // resize if necessary - Fl_RGB_Image * img; + Fl_RGB_Image *img; if(!resizex || !resizey) - img = (Fl_RGB_Image *) img_init.copy(); + img = (Fl_RGB_Image*)img_init.copy(); else - img = (Fl_RGB_Image *) img_init.copy(resizex, resizey); + img = (Fl_RGB_Image*)img_init.copy(resizex, resizey); - const uchar *data = img->array; + const unsigned char *data = img->array; int height = img->h(); int width = img->w(); int dim = img->d(); @@ -41,8 +41,8 @@ static PViewDataList *Img2Data(Fl_RGB_Image &img_init, int quads=1, double z = 0.; for(int i = 0; i < height - 1; i++) { - const uchar *a = data + i * width * dim; - const uchar *a1 = data + (i + 1) * width * dim; + const unsigned char *a = data + i * width * dim; + const unsigned char *a1 = data + (i + 1) * width * dim; double y = height - i - 1; double y1 = height - i - 2; for(int j = 0; j < width - 1; j++) { diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp index 834d94b890abafc721ed851cfe2878fb9c7f1826..10e18ce5ccf356c2fc3400603b01e475d0cf3c53 100644 --- a/Graphics/drawContext.cpp +++ b/Graphics/drawContext.cpp @@ -3,7 +3,10 @@ // See the LICENSE.txt file for license information. Please report all // bugs and problems to <gmsh@geuz.org>. +#include <string> #include <FL/gl.h> +#include <FL/Fl_JPEG_Image.H> +#include <FL/Fl_PNG_Image.H> #include "GmshMessage.h" #include "drawContext.h" #include "Trackball.h" @@ -12,6 +15,7 @@ #include "GModel.h" #include "PView.h" #include "PViewOptions.h" +#include "gl2ps.h" drawContext::drawContext(drawTransform *transform) : _transform(transform) @@ -33,6 +37,8 @@ drawContext::drawContext(drawTransform *transform) vxmin = vymin = vxmax = vymax = 0.; pixel_equiv_x = pixel_equiv_y = 0.; + _bgImageSize[0] = _bgImageSize[1] = 0; + _quadric = 0; // cannot create it here: needs valid opengl context _displayLists = 0; } @@ -247,6 +253,7 @@ void drawContext::draw2d() glLoadIdentity(); glOrtho((double)viewport[0], (double)viewport[2], (double)viewport[1], (double)viewport[3], -1., 1.); + // hack to make the 2D primitives appear "in front" in GL2PS glTranslated(0., 0., CTX::instance()->clipFactor > 1. ? 1. / CTX::instance()->clipFactor : CTX::instance()->clipFactor); @@ -298,95 +305,164 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick) // no initial translation of the model t_init[0] = t_init[1] = t_init[2] = 0.; - // setup ortho or perspective projection matrix - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // restrict picking to a rectangular region around xpick,ypick in SELECT mode - if(render_mode == GMSH_SELECT) - gluPickMatrix((GLdouble)xpick, (GLdouble)(viewport[3] - ypick), - (GLdouble)wpick, (GLdouble)hpick, (GLint *)viewport); - - double grad_z, grad_xy; - double zmax = std::max(fabs(CTX::instance()->min[2]), fabs(CTX::instance()->max[2])); + // 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, clip_far; if(CTX::instance()->ortho) { - // setting up the near and far clipping planes so that the box is - // large enough to manipulate the model and zoom, but not too big - // (the z-buffer resolution, e.g., on software Mesa can become - // insufficient) - double clip = zmax * s[2] * CTX::instance()->clipFactor; - glOrtho(vxmin, vxmax, vymin, vymax, -clip, clip); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - grad_z = 0.99 * clip; - grad_xy = 1.; + clip_near = -zmax * s[2] * CTX::instance()->clipFactor; + clip_far = -clip_near; } else { - double clip_near = 0.75 * CTX::instance()->clipFactor * zmax; - double clip_far = 75. * CTX::instance()->clipFactor * zmax; - double coef = (75./0.75) / 3.; - // recenter the model such that the perspective is always at the - // center of gravity (we should maybe add an option to choose - // this, as we do for the rotation center) - t_init[0] = CTX::instance()->cg[0]; - t_init[1] = CTX::instance()->cg[1]; - vxmin -= t_init[0]; - vxmax -= t_init[0]; - vymin -= t_init[1]; - vymax -= t_init[1]; - glFrustum(vxmin, vxmax, vymin, vymax, clip_near, clip_far); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslated(-coef * t_init[0], -coef * t_init[1], -coef * clip_near); - glScaled(coef, coef, coef); - grad_z = 0.99 * clip_far; - grad_xy = clip_far / clip_near; + clip_near = 0.75 * CTX::instance()->clipFactor * zmax; + clip_far = 75. * CTX::instance()->clipFactor * zmax; } - // draw background gradient - if(render_mode != GMSH_SELECT && CTX::instance()->bgGradient){ + // setup projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // restrict picking to a rectangular region around xpick,ypick + if(render_mode == GMSH_SELECT){ + gluPickMatrix((GLdouble)xpick, (GLdouble)(viewport[3] - ypick), + (GLdouble)wpick, (GLdouble)hpick, (GLint *)viewport); + } + + // draw background if not in selection mode + if(render_mode != GMSH_SELECT && (CTX::instance()->bgGradient || + CTX::instance()->bgImageFileName.size())){ + glDisable(GL_DEPTH_TEST); glPushMatrix(); glLoadIdentity(); - glTranslated(0., 0., -grad_z); + // the z values and the translation are only needed for GL2PS, + // which does not understand "no depth test" (hence we must make + // sure that we draw the background behing the rest of the scene) + glOrtho((double)viewport[0], (double)viewport[2], + (double)viewport[1], (double)viewport[3], + clip_near, clip_far); + glTranslated(0., 0., -0.99 * clip_far); + + // background gradient if(CTX::instance()->bgGradient == 1){ // vertical glBegin(GL_QUADS); glColor4ubv((GLubyte *) & CTX::instance()->color.bg); - glVertex3d(grad_xy * vxmin, grad_xy * vymin, 0.); - glVertex3d(grad_xy * vxmax, grad_xy * vymin, 0.); + glVertex2i(viewport[0], viewport[1]); + glVertex2i(viewport[2], viewport[1]); glColor4ubv((GLubyte *) & CTX::instance()->color.bgGrad); - glVertex3d(grad_xy * vxmax, grad_xy * vymax, 0.); - glVertex3d(grad_xy * vxmin, grad_xy * vymax, 0.); + glVertex2i(viewport[2], viewport[3]); + glVertex2i(viewport[0], viewport[3]); glEnd(); } else if(CTX::instance()->bgGradient == 2){ // horizontal glBegin(GL_QUADS); glColor4ubv((GLubyte *) & CTX::instance()->color.bg); - glVertex3d(grad_xy * vxmax, grad_xy * vymin, 0.); - glVertex3d(grad_xy * vxmax, grad_xy * vymax, 0.); + glVertex2i(viewport[2], viewport[1]); + glVertex2i(viewport[2], viewport[3]); glColor4ubv((GLubyte *) & CTX::instance()->color.bgGrad); - glVertex3d(grad_xy * vxmin, grad_xy * vymax, 0.); - glVertex3d(grad_xy * vxmin, grad_xy * vymin, 0.); + glVertex2i(viewport[0], viewport[3]); + glVertex2i(viewport[0], viewport[1]); glEnd(); } - else{ // radial - double cx = grad_xy * (vxmin + vxmax) / 2.; - double cy = grad_xy * (vymin + vymax) / 2.; - double r = grad_xy * std::max(vxmax - vxmin, vymax - vymin) / 2.; + else if(CTX::instance()->bgGradient == 3){ // radial + double cx = 0.5 * (viewport[0] + viewport[2]); + double cy = 0.5 * (viewport[1] + viewport[3]); + double r = 0.5 * std::max(viewport[2] - viewport[0], + viewport[3] - viewport[1]); glBegin(GL_TRIANGLE_FAN); glColor4ubv((GLubyte *) & CTX::instance()->color.bgGrad); - glVertex3d(cx, cy, 0.); + glVertex2d(cx, cy); glColor4ubv((GLubyte *) & CTX::instance()->color.bg); - glVertex3d(cx + r, cy, 0.); + glVertex2d(cx + r, cy); int ntheta = 36; for(int i = 1; i < ntheta + 1; i ++){ double theta = i * 2 * M_PI / (double)ntheta; - glVertex3d(cx + r * cos(theta), cy + r * sin(theta), 0.); + glVertex2d(cx + r * cos(theta), cy + r * sin(theta)); } glEnd(); } + + // hack for GL2PS (to make sure that the image is in front of the + // gradient) + glTranslated(0., 0., 0.01 * clip_far); + + // background image + if(CTX::instance()->bgImageFileName.size()){ + if(_bgImage.empty()){ + int idot = CTX::instance()->bgImageFileName.find_last_of('.'); + std::string ext; + if(idot > 0 && idot < CTX::instance()->bgImageFileName.size()) + ext = CTX::instance()->bgImageFileName.substr(idot + 1); + Fl_RGB_Image *img = 0; + if(ext == "jpg" || ext == "JPG" || ext == "jpeg" || ext == "JPEG") + img = new Fl_JPEG_Image(CTX::instance()->bgImageFileName.c_str()); + else if(ext == "png" || ext == "PNG") + img = new Fl_PNG_Image(CTX::instance()->bgImageFileName.c_str()); + if(img && img->d() >= 3){ + const unsigned char *data = img->array; + for(int j = img->h() - 1; j >= 0; j--) { + for(int i = 0; i < img->w(); i++) { + int idx = j * img->w() * img->d() + i * img->d(); + _bgImage.push_back((GLfloat)data[idx] / 255.); + _bgImage.push_back((GLfloat)data[idx + 1] / 255.); + _bgImage.push_back((GLfloat)data[idx + 2] / 255.); + } + } + _bgImageSize[0] = img->w(); + _bgImageSize[1] = img->h(); + } + if(!_bgImageSize[0] || !_bgImageSize[1]){ + Msg::Error("Could not load valid background image"); + for(int i = 0; i < 3; i++) _bgImage.push_back(0); + _bgImageSize[0] = _bgImageSize[1] = 1.; + } + } + double x = CTX::instance()->bgImagePosition[0]; + double y = CTX::instance()->bgImagePosition[1]; + int c = fix2dCoordinates(&x, &y); + if(c & 1) x -= _bgImageSize[0] / 2.; + if(c & 2) y -= _bgImageSize[1] / 2.; + if(x < viewport[0]) x = viewport[0]; + if(y < viewport[1]) y = viewport[1]; + glRasterPos2d(x, y); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glDrawPixels(_bgImageSize[0], _bgImageSize[1], GL_RGB, GL_FLOAT, + (void*)&_bgImage[0]); + gl2psDrawPixels(_bgImageSize[0], _bgImageSize[1], 0, 0, GL_RGB, GL_FLOAT, + (void*)&_bgImage[0]); + } + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + } + + + if(CTX::instance()->ortho) { + glOrtho(vxmin, vxmax, vymin, vymax, clip_near, clip_far); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + else { + // recenter the model such that the perspective is always at the + // center of gravity (we should maybe add an option to choose + // this, as we do for the rotation center) + t_init[0] = CTX::instance()->cg[0]; + t_init[1] = CTX::instance()->cg[1]; + vxmin -= t_init[0]; + vxmax -= t_init[0]; + vymin -= t_init[1]; + vymax -= t_init[1]; + glFrustum(vxmin, vxmax, vymin, vymax, clip_near, clip_far); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + double coef = (clip_far / clip_near) / 3.; + glTranslated(-coef * t_init[0], -coef * t_init[1], -coef * clip_near); + glScaled(coef, coef, coef); } } diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h index 6ffcb864f465c2a7910452bb54beb48c5a5e7e38..f8d62fbab5bdf22b40e4d4d87c855592cfd53b4a 100644 --- a/Graphics/drawContext.h +++ b/Graphics/drawContext.h @@ -7,6 +7,7 @@ #define _DRAW_CONTEXT_H_ #include <string> +#include <vector> #include <set> #include <FL/gl.h> @@ -74,6 +75,8 @@ class drawContext { GLuint _displayLists; std::set<GModel*> _hiddenModels; std::set<PView*> _hiddenViews; + std::vector<GLfloat> _bgImage; + int _bgImageSize[2]; public: double r[3]; // current Euler angles (in degrees!) diff --git a/Graphics/gl2gif.cpp b/Graphics/gl2gif.cpp index 2d7f15323bbb08392cfcf6c84fb827382e2fc7bf..7f94fa6b4115d1bf2cd362ccecda4b8cb17c875f 100644 --- a/Graphics/gl2gif.cpp +++ b/Graphics/gl2gif.cpp @@ -1164,9 +1164,9 @@ void create_gif(FILE * outfile, PixelBuffer *buffer, register long sr = 0, sg = 0, sb = 0, err = 0; int fs_direction = 0; - int width = buffer->GetWidth(); - int height = buffer->GetHeight(); - int numcomp = buffer->GetNumComp(); + int width = buffer->getWidth(); + int height = buffer->getHeight(); + int numcomp = buffer->getNumComp(); if(numcomp != 3){ Msg::Error("GIF only implemented for GL_RGB"); @@ -1177,7 +1177,7 @@ void create_gif(FILE * outfile, PixelBuffer *buffer, for(i = 0; i < height; i++) static_pixels[i] = (pixel *) Malloc(3 * width * sizeof(pixel)); - unsigned char *pixels = (unsigned char*)buffer->GetPixels(); + unsigned char *pixels = (unsigned char*)buffer->getPixels(); for(i = 0; i < height; i++) for(j = 0; j < width; j++) PPM_ASSIGN(static_pixels[height - 1 - i][j], diff --git a/Graphics/gl2jpeg.cpp b/Graphics/gl2jpeg.cpp index 9db30b79fb8077989751ba49826712e2fb747d13..190796d6be061546606c08609646bd82b8a3ff58 100644 --- a/Graphics/gl2jpeg.cpp +++ b/Graphics/gl2jpeg.cpp @@ -43,7 +43,7 @@ static void my_output_message(j_common_ptr cinfo) void create_jpeg(FILE *outfile, PixelBuffer *buffer, int quality, int smoothing) { - if(buffer->GetFormat() != GL_RGB || buffer->GetType() != GL_UNSIGNED_BYTE){ + if(buffer->getFormat() != GL_RGB || buffer->getType() != GL_UNSIGNED_BYTE){ Msg::Error("JPEG only implemented for GL_RGB and GL_UNSIGNED_BYTE"); return; } @@ -55,8 +55,8 @@ void create_jpeg(FILE *outfile, PixelBuffer *buffer, int quality, int smoothing) jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, outfile); - cinfo.image_width = buffer->GetWidth(); - cinfo.image_height = buffer->GetHeight(); + cinfo.image_width = buffer->getWidth(); + cinfo.image_height = buffer->getHeight(); cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); @@ -65,7 +65,7 @@ void create_jpeg(FILE *outfile, PixelBuffer *buffer, int quality, int smoothing) cinfo.smoothing_factor = smoothing; jpeg_start_compress(&cinfo, TRUE); - unsigned char *pixels = (unsigned char*)buffer->GetPixels(); + unsigned char *pixels = (unsigned char*)buffer->getPixels(); JSAMPROW row_pointer[1]; int row_stride = cinfo.image_width * cinfo.input_components; int i = cinfo.image_height - 1; diff --git a/Graphics/gl2png.cpp b/Graphics/gl2png.cpp index 2af7102195786874dc5568d30f6a33f4bef22938..e462fe5fee4e1a17e357925bdb5632dcc08a7b92 100644 --- a/Graphics/gl2png.cpp +++ b/Graphics/gl2png.cpp @@ -23,8 +23,8 @@ void create_png(FILE *file, PixelBuffer *buffer, int quality) void create_png(FILE *file, PixelBuffer *buffer, int quality) { - if((buffer->GetFormat() != GL_RGB && buffer->GetFormat() != GL_RGBA) || - buffer->GetType() != GL_UNSIGNED_BYTE){ + if((buffer->getFormat() != GL_RGB && buffer->getFormat() != GL_RGBA) || + buffer->getType() != GL_UNSIGNED_BYTE){ Msg::Error("PNG only implemented for GL_RGB/GL_RGBA and GL_UNSIGNED_BYTE"); return; } @@ -52,9 +52,9 @@ void create_png(FILE *file, PixelBuffer *buffer, int quality) png_init_io(png_ptr, file); - int height = buffer->GetHeight(); - int width = buffer->GetWidth(); - int numcomp = buffer->GetNumComp(); + int height = buffer->getHeight(); + int width = buffer->getWidth(); + int numcomp = buffer->getNumComp(); // Z_DEFAULT_COMPRESSION, Z_BEST_SPEED, Z_BEST_COMPRESSION, Z_NO_COMPRESSION png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION); @@ -73,7 +73,7 @@ void create_png(FILE *file, PixelBuffer *buffer, int quality) png_set_text(png_ptr, info_ptr, text_ptr, 2); png_write_info(png_ptr, info_ptr); - unsigned char *pixels = (unsigned char *)buffer->GetPixels(); + unsigned char *pixels = (unsigned char *)buffer->getPixels(); for(int row = height - 1; row >= 0; row--) { unsigned char *row_pointer = &pixels[row * width * numcomp]; png_write_row(png_ptr, (png_bytep)row_pointer); diff --git a/Graphics/gl2ppm.cpp b/Graphics/gl2ppm.cpp index df67b697744b5b12b18b7cf7b9bfae214d5a53d3..0a52c5b753e759018ccf5af46518388beb3f894b 100644 --- a/Graphics/gl2ppm.cpp +++ b/Graphics/gl2ppm.cpp @@ -7,14 +7,14 @@ void create_ppm(FILE *outfile, PixelBuffer *buffer) { - if(buffer->GetFormat() != GL_RGB || buffer->GetType() != GL_UNSIGNED_BYTE){ + if(buffer->getFormat() != GL_RGB || buffer->getType() != GL_UNSIGNED_BYTE){ Msg::Error("PPM only implemented for GL_RGB and GL_UNSIGNED_BYTE"); return; } - int width = buffer->GetWidth(); - int height = buffer->GetHeight(); - unsigned char *pixels = (unsigned char*)buffer->GetPixels(); + int width = buffer->getWidth(); + int height = buffer->getHeight(); + unsigned char *pixels = (unsigned char*)buffer->getPixels(); fprintf(outfile, "P6\n"); fprintf(outfile, "%d %d\n", width, height); diff --git a/Graphics/gl2ps.cpp b/Graphics/gl2ps.cpp index da66f4903348186b25ef61dea4383b82e3e8fe07..86f632117b9e2983f54dd8c82bd186ce2e77bd83 100644 --- a/Graphics/gl2ps.cpp +++ b/Graphics/gl2ps.cpp @@ -1465,7 +1465,8 @@ static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root) } } -static void gl2psFreeImagemap(GL2PSimagemap *list){ +static void gl2psFreeImagemap(GL2PSimagemap *list) +{ GL2PSimagemap *next; while(list != NULL){ next = list->next; @@ -5028,7 +5029,7 @@ static void gl2psPrintSVGPixmap(GLfloat x, GLfloat y, GL2PSimage *pixmap) gl2psPrintf("\"/>\n"); gl2psListDelete(png); #else - gl2psMsg(GL2PS_WARNING, "GL2PS has to be compiled with PNG support in " + gl2psMsg(GL2PS_WARNING, "GL2PS must be compiled with PNG support in " "order to embed images in SVG streams"); #endif } diff --git a/Graphics/gl2ps.h b/Graphics/gl2ps.h index 20b1caf831bcfaa134cad91e3ab0ad03f560ef67..c9803c15b9ea6e049cb603a298f4ab5cd90b182a 100644 --- a/Graphics/gl2ps.h +++ b/Graphics/gl2ps.h @@ -36,6 +36,7 @@ #include <stdio.h> #include <stdlib.h> +#include "GmshConfig.h" /* Define GL2PSDLL at compile time to build a Windows DLL */ diff --git a/Graphics/gl2yuv.cpp b/Graphics/gl2yuv.cpp index f62caf9fdcea116b29e3d590d45d49a9b0fb7075..552882188db77f8a107cb4824180ed3cd8ffc565 100644 --- a/Graphics/gl2yuv.cpp +++ b/Graphics/gl2yuv.cpp @@ -34,7 +34,7 @@ void create_yuv(FILE * outfile, PixelBuffer *buffer) { - if(buffer->GetFormat() != GL_RGB || buffer->GetType() != GL_UNSIGNED_BYTE){ + if(buffer->getFormat() != GL_RGB || buffer->getType() != GL_UNSIGNED_BYTE){ Msg::Error("YUV only implemented for GL_RGB and GL_UNSIGNED_BYTE"); return; } @@ -72,9 +72,9 @@ void create_yuv(FILE * outfile, PixelBuffer *buffer) first = 0; } - int width = buffer->GetWidth(); - int height = buffer->GetHeight(); - unsigned char *pixels = (unsigned char *)buffer->GetPixels(); + int width = buffer->getWidth(); + int height = buffer->getHeight(); + unsigned char *pixels = (unsigned char *)buffer->getPixels(); // yuv format assumes even number of rows and columns height -= height % 2; diff --git a/Plugin/Evaluate.cpp b/Plugin/Evaluate.cpp index a6fa85999469af2772a180389f0458ed09b5c023..21a166298f0e01b74569bbfd22505c2d97626e05 100644 --- a/Plugin/Evaluate.cpp +++ b/Plugin/Evaluate.cpp @@ -163,6 +163,7 @@ void GMSH_EvaluatePlugin::evaluate(PView *v1, List_T *list1, int nbElm1, double tmp[9]; val2 = tmp; if(_octree->searchScalar(x[j], y[j], z[j], val2, timeStep2)){ + //if(_octree->searchScalarWithTol(x[j], y[j], z[j], val2, timeStep2, 0, 0.1)){ w[0] = val2[0]; } else if(_octree->searchVector(x[j], y[j], z[j], val2, timeStep2)){ diff --git a/Post/OctreePost.cpp b/Post/OctreePost.cpp index 310c05305d9e7889af8f329e8b7f15c920e6cb31..4c28078c4b04d5b50840b5983cb2f30df65ebf9b 100644 --- a/Post/OctreePost.cpp +++ b/Post/OctreePost.cpp @@ -417,7 +417,7 @@ bool OctreePost::searchScalarWithTol(double x, double y, double z, double *value int step, double *size, double tol) { bool a = searchScalar(x, y, z, values, step, size); - if(!a){ + if(!a && tol != 0.){ double oldtol1 = element::getTolerance(); double oldtol2 = MElement::getTolerance(); element::setTolerance(tol); diff --git a/doc/TODO.txt b/doc/TODO.txt index 19ea4e51ba64bb1071f99310c65084bfb449b125..f820dd55bdccc1226fb32d202692c9e883d72d4b 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -1,4 +1,8 @@ -$Id: TODO.txt,v 1.18 2009-03-01 18:27:01 geuzaine Exp $ +$Id: TODO.txt,v 1.19 2009-03-08 19:12:34 geuzaine Exp $ + +******************************************************************** + +Should we take embedded vertices into account in extrusions? ******************************************************************** @@ -164,12 +168,6 @@ disable all replacements) ******************************************************************** -Add a "bitmap" object in the views, e.g. to add a logo. Maybe would -be good enough to add another mode in the "background gradient" stuff -to display an image in the background - -******************************************************************** - keep a table (stack) with the N last file positions when add_infile() is called; we could then easily implement a simple (but real) UNDO strategy diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt index 0d0df4c2574422c485274c639db9b7e1eb8eaed7..d508689debd2c95c114166eed40024ec3ae4cf78 100644 --- a/doc/VERSIONS.txt +++ b/doc/VERSIONS.txt @@ -1,8 +1,8 @@ -$Id: VERSIONS.txt,v 1.36 2009-02-07 17:14:49 geuzaine Exp $ +$Id: VERSIONS.txt,v 1.37 2009-03-08 19:12:34 geuzaine Exp $ (?): removed GSL dependency (Gmsh now simply requires Blas and -Lapack); new per-window visibility; fixes for string options in -parser. +Lapack); new per-window visibility; added support for composite window +printing and background image; fixes for string options in parser. 2.3.0 (Jan 23, 2009): major graphics and GUI code refactoring; new full-quad/hexa subdivision algorithm (removed Mesh.RecombineAlgo); diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi index 4fa4750aa4a57ad5fabe1ea46dc7c4799b5a3a2d..8af6a22708fc5eaa13631dbb260fbc7a011f8016 100644 --- a/doc/texinfo/gmsh.texi +++ b/doc/texinfo/gmsh.texi @@ -929,7 +929,7 @@ meaning and syntax as in the C or C++ programming languages. Floating point expressions (or, more simply, ``expressions'') are denoted by the metasyntactic variable @var{expression} (remember the definition of the syntactic rules in @ref{Syntactic rules}), and are evaluated during the -parsing of the data file: +parsing of the script file: @example @var{expression}: @@ -1069,11 +1069,11 @@ Colors expressions are hybrids between fixed-length braced @noindent The first case permits to use the X Windows names to refer to colors, e.g., @code{Red}, @code{SpringGreen}, @code{LavenderBlush3}, @dots{} -(see @file{Common/Colors.h} in Gmsh's source tree for a complete -list). The second case permits to define colors by using three -expressions to specify their red, green and blue components (with values -comprised between 0 and 255). The third case permits to define colors by -using their red, green and blue color components as well as their alpha +(see @file{Common/Colors.h} in the source code for a complete list). The +second case permits to define colors by using three expressions to +specify their red, green and blue components (with values comprised +between 0 and 255). The third case permits to define colors by using +their red, green and blue color components as well as their alpha channel. The last case permits to use the value of a @var{color-option} as a @var{color-expression}. The various @w{@var{color-option}s} are listed in @ref{Options}. @@ -1402,7 +1402,7 @@ The following commands can be used anywhere in a Gmsh script: @item @var{string} = @var{expression}; Creates a new expression identifier @var{string}, or affects -@var{expression} to an existing expression identifier. Eleven expression +@var{expression} to an existing expression identifier. Thirteen expression identifiers are predefined (hardcoded in Gmsh's parser): @ftable @code @@ -1451,11 +1451,11 @@ Returns the next available surface loop number. @item newreg Returns the next available region number. That is, @code{newreg} returns -the maximum of @code{newp}, @code{newl}, @code{news}, @code{newv} and -all physical entity numbers@footnote{For compatibility purposes, the -behavior of @code{newl}, @code{news}, @code{newv} and @code{newreg} can -be modified with the @code{Geometry.OldNewReg} option (@pxref{Geometry -options list}).}. +the maximum of @code{newp}, @code{newl}, @code{news}, @code{newv}, +@code{newll}, @code{newsl} and all physical entity numbers@footnote{For +compatibility purposes, the behavior of @code{newl}, @code{news}, +@code{newv} and @code{newreg} can be modified with the +@code{Geometry.OldNewReg} option (@pxref{Geometry options list}).}. @end ftable @item @var{string} [ ] = @{ @}; @@ -1634,13 +1634,14 @@ the same time. @cindex Geometry, module @cindex Module, geometry -Gmsh's geometry module provides a simple CAD engine, using a bottom-up -(boundary representation) approach: you need to first define points (using -the @code{Point} command: see below), then lines (using @code{Line}, -@code{Circle}, @code{Spline}, @dots{}, commands or by extruding points), -then surfaces (using for example the @code{Plane Surface} or @code{Ruled -Surface} commands, or by extruding lines), and finally volumes (using the -@code{Volume} command or by extruding surfaces). +Gmsh's geometry module provides a simple CAD engine, using a boundary +representation (``BRep'') approach: you need to first define points +(using the @code{Point} command: see below), then lines (using +@code{Line}, @code{Circle}, @code{Spline}, @dots{}, commands or by +extruding points), then surfaces (using for example the @code{Plane +Surface} or @code{Ruled Surface} commands, or by extruding lines), and +finally volumes (using the @code{Volume} command or by extruding +surfaces). These geometrical entities are called ``elementary'' in Gmsh's jargon, and are assigned identification numbers when they are created: @@ -1653,8 +1654,10 @@ are assigned identification numbers when they are created: @end enumerate @noindent Elementary geometrical entities can then be manipulated in various -ways, for example using the @code{Translate}, @code{Rotate}, @code{Scale} or -@code{Symmetry} commands. +ways, for example using the @code{Translate}, @code{Rotate}, +@code{Scale} or @code{Symmetry} commands. They can be deleted with the +@code{Delete} command, provided that no higher-dimension entity +references them. Compound groups of elementary geometrical entities can also be defined and are called ``physical'' entities. These physical entities cannot be modified @@ -2070,7 +2073,10 @@ transformation, unless @code{Geometry.AutoCoherence} is set to zero @item Delete @{ Point | Line | Surface | Volume @{ @var{expression-list} @}; @dots{} @} Deletes all elementary entities whose identification numbers are given -in @var{expression-list}. +in @var{expression-list}. If an entity is linked to another entity (for +example, if a point is used as a control point of a curve), +@code{Delete} has no effect (the line will have to be deleted before the +point can). @item Hide @{ Point | Line | Surface | Volume @{ @var{expression-list} @}; @dots{} @} Hide the entities listed in @var{expression-list}, if @@ -2160,13 +2166,13 @@ algorithm can be quite poor. If only elementary geometrical entities are defined (or if the @code{Mesh.SaveAll} option is set; see @ref{Mesh options list}), the grid produced by the mesh module will be saved ``as is''. That is, all -the elements in the grid will be saved to disk using the identification -number of the elementary entities they discretize as their elementary -region number (and 0 as their physical region number@footnote{This -behaviour was introduced in Gmsh 2.0. In older versions, both the -elementary and the physical region numbers would be set to the -identification number of the elementary region.}; @ref{File -formats}). This can sometimes be inconvenient: +the elements in the grid will be saved using the identification number +of the elementary entities they discretize as their elementary region +number (and 0 as their physical region number@footnote{This behaviour +was introduced in Gmsh 2.0. In older versions, both the elementary and +the physical region numbers would be set to the identification number of +the elementary region.}; @ref{File formats}). This can sometimes be +inconvenient: @itemize @bullet @item diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi index aa181881850c8170356f6e9abaa50dc58e5014a6..02e8bb1c45915fafa3a6b42e765cf062772d9877 100644 --- a/doc/texinfo/opt_general.texi +++ b/doc/texinfo/opt_general.texi @@ -34,6 +34,11 @@ Z-axis label@* Default value: @code{""}@* Saved in: @code{General.OptionsFileName} +@item General.BackgroundImageFileName +Background image file in JPEG or PNG format@* +Default value: @code{""}@* +Saved in: @code{General.OptionsFileName} + @item General.DefaultFileName Default project file name@* Default value: @code{"untitled.geo"}@* @@ -179,6 +184,16 @@ Draw background gradient (0=none, 1=vertical, 2=horizontal, 3=radial)@* Default value: @code{1}@* Saved in: @code{General.OptionsFileName} +@item General.BackgroundImagePositionX +X position (in pixels) of background image (< 0: right alignment; > 1e5: centered)@* +Default value: @code{100000}@* +Saved in: @code{General.OptionsFileName} + +@item General.BackgroundImagePositionY +Y position (in pixels) of background image (< 0: right alignment; > 1e5: centered)@* +Default value: @code{100000}@* +Saved in: @code{General.OptionsFileName} + @item General.Clip0A First coefficient in equation for clipping plane 0 (`A' in `AX+BY+CZ+D=0')@* Default value: @code{1}@* @@ -201,12 +216,12 @@ Saved in: @code{-} @item General.Clip1A First coefficient in equation for clipping plane 1@* -Default value: @code{1}@* +Default value: @code{0}@* Saved in: @code{-} @item General.Clip1B Second coefficient in equation for clipping plane 1@* -Default value: @code{0}@* +Default value: @code{1}@* Saved in: @code{-} @item General.Clip1C @@ -221,7 +236,7 @@ Saved in: @code{-} @item General.Clip2A First coefficient in equation for clipping plane 2@* -Default value: @code{1}@* +Default value: @code{0}@* Saved in: @code{-} @item General.Clip2B @@ -231,7 +246,7 @@ Saved in: @code{-} @item General.Clip2C Third coefficient in equation for clipping plane 2@* -Default value: @code{0}@* +Default value: @code{1}@* Saved in: @code{-} @item General.Clip2D @@ -241,7 +256,7 @@ Saved in: @code{-} @item General.Clip3A First coefficient in equation for clipping plane 3@* -Default value: @code{1}@* +Default value: @code{-1}@* Saved in: @code{-} @item General.Clip3B @@ -261,12 +276,12 @@ Saved in: @code{-} @item General.Clip4A First coefficient in equation for clipping plane 4@* -Default value: @code{1}@* +Default value: @code{0}@* Saved in: @code{-} @item General.Clip4B Second coefficient in equation for clipping plane 4@* -Default value: @code{0}@* +Default value: @code{-1}@* Saved in: @code{-} @item General.Clip4C @@ -281,7 +296,7 @@ Saved in: @code{-} @item General.Clip5A First coefficient in equation for clipping plane 5@* -Default value: @code{1}@* +Default value: @code{0}@* Saved in: @code{-} @item General.Clip5B @@ -291,7 +306,7 @@ Saved in: @code{-} @item General.Clip5C Third coefficient in equation for clipping plane 5@* -Default value: @code{0}@* +Default value: @code{-1}@* Saved in: @code{-} @item General.Clip5D @@ -820,12 +835,12 @@ Default value: @code{1}@* Saved in: @code{General.OptionsFileName} @item General.SmallAxesPositionX -X position of small axes (use negative values for right alignment)@* +X position (in pixels) of small axes (< 0: right alignment; > 1e5: centered)@* Default value: @code{-60}@* Saved in: @code{General.OptionsFileName} @item General.SmallAxesPositionY -Y position of small axes (use negative values for bottom alignment)@* +Y position (in pixels) of small axes (< 0: right alignment; > 1e5: centered)@* Default value: @code{-40}@* Saved in: @code{General.OptionsFileName} diff --git a/doc/texinfo/opt_print.texi b/doc/texinfo/opt_print.texi index 30e6e046a6ac040378a892a2e2673e5e476791d4..baa3295eb9c2953df9e5ff365874f7a79db6a4f2 100644 --- a/doc/texinfo/opt_print.texi +++ b/doc/texinfo/opt_print.texi @@ -4,6 +4,11 @@ @c @ftable @code +@item Print.CompositeWindows +Composite all window tiles in the same output image (for bitmap output only)@* +Default value: @code{0}@* +Saved in: @code{General.OptionsFileName} + @item Print.EpsBackground Save image background in PostScript/PDF output@* Default value: @code{1}@* diff --git a/doc/texinfo/opt_view.texi b/doc/texinfo/opt_view.texi index 899bd12bff6f3b7a7fdf0b8993cf146b29b0d083..4eab4d51210f38e3e2bcad3cb24ccc1d87c8751c 100644 --- a/doc/texinfo/opt_view.texi +++ b/doc/texinfo/opt_view.texi @@ -495,12 +495,12 @@ Default value: @code{0}@* Saved in: @code{General.OptionsFileName} @item View.PositionX -Horizontal position (in pixels) of the upper left corner of the scale or 2D plot@* +X position (in pixels) of the scale or 2D plot (< 0: right alignment; > 1e5: centered)@* Default value: @code{100}@* Saved in: @code{General.OptionsFileName} @item View.PositionY -Vertical position (in pixels) of the upper left corner of the scale or 2D plot@* +Y position (in pixels) of the scale or 2D plot (< 0: right alignment; > 1e5: centered)@* Default value: @code{50}@* Saved in: @code{General.OptionsFileName}