Forked from
gmsh / gmsh
15791 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
CreateFile.cpp 12.28 KiB
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#include <string.h>
#include "GmshConfig.h"
#include "GmshMessage.h"
#include "GModel.h"
#include "GmshDefines.h"
#include "StringUtils.h"
#include "Context.h"
#include "Options.h"
#if defined(HAVE_FLTK)
#include <FL/gl.h>
#include "gl2ps.h"
#include "gl2gif.h"
#include "gl2jpeg.h"
#include "gl2png.h"
#include "gl2ppm.h"
#include "gl2yuv.h"
#endif
int GuessFileFormatFromFileName(std::string fileName)
{
int len;
char ext[256];
const char *name = fileName.c_str();
for(len = strlen(name) - 1; len >= 0; len--) {
if(name[len] == '.') {
strcpy(ext, &name[len]);
break;
}
}
if(len <= 0)
strcpy(ext, "");
if (!strcmp(ext, ".geo")) return FORMAT_GEO;
else if(!strcmp(ext, ".msh")) return FORMAT_MSH;
else if(!strcmp(ext, ".pos")) return FORMAT_POS;
else if(!strcmp(ext, ".opt")) return FORMAT_OPT;
else if(!strcmp(ext, ".unv")) return FORMAT_UNV;
else if(!strcmp(ext, ".vtk")) return FORMAT_VTK;
else if(!strcmp(ext, ".stl")) return FORMAT_STL;
else if(!strcmp(ext, ".cgns")) return FORMAT_CGNS;
else if(!strcmp(ext, ".med")) return FORMAT_MED;
else if(!strcmp(ext, ".mesh")) return FORMAT_MESH;
else if(!strcmp(ext, ".bdf")) return FORMAT_BDF;
else if(!strcmp(ext, ".diff")) return FORMAT_DIFF;
else if(!strcmp(ext, ".nas")) return FORMAT_BDF;
else if(!strcmp(ext, ".p3d")) return FORMAT_P3D;
else if(!strcmp(ext, ".wrl")) return FORMAT_VRML;
else if(!strcmp(ext, ".vrml")) return FORMAT_VRML;
else if(!strcmp(ext, ".gif")) return FORMAT_GIF;
else if(!strcmp(ext, ".jpg")) return FORMAT_JPEG;
else if(!strcmp(ext, ".jpeg")) return FORMAT_JPEG;
else if(!strcmp(ext, ".png")) return FORMAT_PNG;
else if(!strcmp(ext, ".ps")) return FORMAT_PS;
else if(!strcmp(ext, ".eps")) return FORMAT_EPS;
else if(!strcmp(ext, ".pdf")) return FORMAT_PDF;
else if(!strcmp(ext, ".tex")) return FORMAT_TEX;
else if(!strcmp(ext, ".svg")) return FORMAT_SVG;
else if(!strcmp(ext, ".ppm")) return FORMAT_PPM;
else if(!strcmp(ext, ".yuv")) return FORMAT_YUV;
else return -1;
}
std::string GetDefaultFileName(int format)
{
char no_ext[256], ext[256], base[256];
SplitFileName(GModel::current()->getFileName().c_str(), no_ext, ext, base);
std::string name(no_ext);
switch(format){
case FORMAT_GEO: name += ".geo_unrolled"; break;
case FORMAT_MSH: name += ".msh"; break;
case FORMAT_POS: name += ".pos"; break;
case FORMAT_OPT: name += ".opt"; break;
case FORMAT_UNV: name += ".unv"; break;
case FORMAT_VTK: name += ".vtk"; break;
case FORMAT_STL: name += ".stl"; break;
case FORMAT_CGNS: name += ".cgns"; break;
case FORMAT_MED: name += ".med"; break;
case FORMAT_MESH: name += ".mesh"; break;
case FORMAT_BDF: name += ".bdf"; break;
case FORMAT_DIFF: name += ".diff"; break;
case FORMAT_P3D: name += ".p3d"; break;
case FORMAT_VRML: name += ".wrl"; break;
case FORMAT_GIF: name += ".gif"; break;
case FORMAT_JPEG: name += ".jpg"; break;
case FORMAT_PNG: name += ".png"; break;
case FORMAT_PS: name += ".ps"; break;
case FORMAT_EPS: name += ".eps"; break;
case FORMAT_PDF: name += ".pdf"; break;
case FORMAT_TEX: name += ".tex"; break;
case FORMAT_SVG: name += ".svg"; break;
case FORMAT_PPM: name += ".ppm"; break;
case FORMAT_YUV: name += ".yuv"; break;
default: break;
}
return name;
}
void CreateOutputFile(std::string fileName, int format)
{
if(fileName.empty())
fileName = GetDefaultFileName(format);
char no_ext[256], ext[256], base[256];
SplitFileName(fileName.c_str(), no_ext, ext, base);
int oldformat = CTX::instance()->print.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());
switch (format) {
case FORMAT_AUTO:
CreateOutputFile(fileName, GuessFileFormatFromFileName(fileName));
printEndMessage = false;
break;
case FORMAT_OPT:
Print_Options(0, GMSH_FULLRC, 1, 1, fileName.c_str());
break;
case FORMAT_MSH:
GModel::current()->writeMSH
(fileName, CTX::instance()->mesh.msh_file_version,
CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
CTX::instance()->mesh.save_parametric, CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_STL:
GModel::current()->writeSTL
(fileName, CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_VRML:
GModel::current()->writeVRML
(fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_UNV:
GModel::current()->writeUNV
(fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.save_groups_of_nodes,
CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_VTK:
GModel::current()->writeVTK
(fileName, CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
CTX::instance()->mesh.scaling_factor,
CTX::instance()->big_endian);
break;
case FORMAT_MESH:
GModel::current()->writeMESH
(fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_BDF:
GModel::current()->writeBDF
(fileName, CTX::instance()->mesh.bdf_field_format, CTX::instance()->mesh.save_all,
CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_DIFF:
GModel::current()->writeDIFF
(fileName, CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_P3D:
GModel::current()->writeP3D
(fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_CGNS:
GModel::current()->writeCGNS
(fileName, CTX::instance()->mesh.zone_definition, CTX::instance()->mesh.cgns_options,
CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_MED:
GModel::current()->writeMED
(fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_POS:
GModel::current()->writePOS
(fileName, CTX::instance()->print.pos_elementary,
CTX::instance()->print.pos_element, CTX::instance()->print.pos_gamma,
CTX::instance()->print.pos_eta, CTX::instance()->print.pos_rho,
CTX::instance()->print.pos_disto, CTX::instance()->mesh.save_all,
CTX::instance()->mesh.scaling_factor);
break;
case FORMAT_GEO:
GModel::current()->writeGEO(fileName, CTX::instance()->print.geo_labels);
break;
#if defined(HAVE_FLTK)
case FORMAT_PPM:
case FORMAT_YUV:
case FORMAT_GIF:
case FORMAT_JPEG:
case FORMAT_PNG:
{
FILE *fp;
if(!(fp = fopen(fileName.c_str(), "wb"))) {
Msg::Error("Unable to open file '%s'", fileName.c_str());
break;
}
PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE);
int old_bg_gradient = CTX::instance()->bg_gradient;
if(format == FORMAT_GIF && CTX::instance()->print.gif_transparent)
CTX::instance()->bg_gradient = 0;
buffer.Fill(CTX::instance()->batch);
CTX::instance()->bg_gradient = old_bg_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,
CTX::instance()->print.gif_dither,
CTX::instance()->print.gif_sort,
CTX::instance()->print.gif_interlace,
CTX::instance()->print.gif_transparent,
CTX::instance()->unpack_red(CTX::instance()->color.bg),
CTX::instance()->unpack_green(CTX::instance()->color.bg),
CTX::instance()->unpack_blue(CTX::instance()->color.bg));
}
else if(format == FORMAT_JPEG){
create_jpeg(fp, &buffer, CTX::instance()->print.jpeg_quality,
CTX::instance()->print.jpeg_smoothing);
}
else{
create_png(fp, &buffer, 100);
}
fclose(fp);
}
break;
case FORMAT_PS:
case FORMAT_EPS:
case FORMAT_PDF:
case FORMAT_SVG:
{
FILE *fp;
if(!(fp = fopen(fileName.c_str(), "wb"))) {
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;
}
int old_bg_gradient = CTX::instance()->bg_gradient;
if(!CTX::instance()->print.eps_background) CTX::instance()->bg_gradient = 0;
PixelBuffer buffer(width, height, GL_RGB, GL_FLOAT);
if(CTX::instance()->print.eps_quality == 0)
buffer.Fill(CTX::instance()->batch);
int pssort =
(CTX::instance()->print.eps_quality == 3) ? GL2PS_NO_SORT :
(CTX::instance()->print.eps_quality == 2) ? GL2PS_BSP_SORT :
GL2PS_SIMPLE_SORT;
int psoptions =
GL2PS_SIMPLE_LINE_OFFSET | GL2PS_SILENT |
(CTX::instance()->print.eps_occlusion_culling ? GL2PS_OCCLUSION_CULL : 0) |
(CTX::instance()->print.eps_best_root ? GL2PS_BEST_ROOT : 0) |
(CTX::instance()->print.eps_background ? GL2PS_DRAW_BACKGROUND : 0) |
(CTX::instance()->print.eps_compress ? GL2PS_COMPRESS : 0) |
(CTX::instance()->print.eps_ps3shading ? 0 : GL2PS_NO_PS3_SHADING);
GLint buffsize = 0;
int res = GL2PS_OVERFLOW;
while(res == GL2PS_OVERFLOW) {
buffsize += 2048 * 2048;
gl2psBeginPage(base, "Gmsh", viewport,
psformat, pssort, psoptions, GL_RGBA, 0, NULL,
15, 20, 10, buffsize, fp, base);
if(CTX::instance()->print.eps_quality == 0){
double modelview[16], projection[16];
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((double)viewport[0], (double)viewport[2],
(double)viewport[1], (double)viewport[3], -1., 1.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRasterPos2d(0, 0);
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);
}
res = gl2psEndPage();
}
CTX::instance()->bg_gradient = old_bg_gradient;
fclose(fp);
}
break;
case FORMAT_TEX:
{
FILE *fp;
if(!(fp = fopen(fileName.c_str(), "w"))) {
Msg::Error("Unable to open file '%s'", fileName.c_str());
break;
}
GLint buffsize = 0;
int res = GL2PS_OVERFLOW;
while(res == GL2PS_OVERFLOW) {
buffsize += 2048 * 2048;
gl2psBeginPage(base, "Gmsh", viewport,
GL2PS_TEX, GL2PS_NO_SORT, GL2PS_NONE, GL_RGBA, 0, NULL,
0, 0, 0, buffsize, fp, base);
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);
CTX::instance()->print.text = oldtext;
res = gl2psEndPage();
}
fclose(fp);
}
break;
#endif
default:
Msg::Error("Unknown output file format");
printEndMessage = false;
break;
}
if(printEndMessage) Msg::StatusBar(2, true, "Wrote '%s'", fileName.c_str());
CTX::instance()->print.format = oldformat;
CTX::instance()->printing = 0;
#if defined(HAVE_FLTK)
Draw();
#endif
}