Skip to content
Snippets Groups Projects
Select Git revision
  • c03706069585080556848c1672ab858ceb5899e8
  • master default
  • cgnsUnstructured
  • partitioning
  • poppler
  • HighOrderBLCurving
  • gmsh_3_0_4
  • gmsh_3_0_3
  • gmsh_3_0_2
  • gmsh_3_0_1
  • gmsh_3_0_0
  • gmsh_2_16_0
  • gmsh_2_15_0
  • gmsh_2_14_1
  • gmsh_2_14_0
  • gmsh_2_13_2
  • gmsh_2_13_1
  • gmsh_2_12_0
  • gmsh_2_11_0
  • gmsh_2_10_1
  • gmsh_2_10_0
  • gmsh_2_9_3
  • gmsh_2_9_2
  • gmsh_2_9_1
  • gmsh_2_9_0
  • gmsh_2_8_6
26 results

Graph2D.cpp

Blame
  • Forked from gmsh / gmsh
    Source project has a limited visibility.
    Graph2D.cpp 12.69 KiB
    // $Id: Graph2D.cpp,v 1.62 2007-08-31 16:55:52 geuzaine Exp $
    //
    // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
    //
    // This program is free software; you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation; either version 2 of the License, or
    // (at your option) any later version.
    //
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    //
    // You should have received a copy of the GNU General Public License
    // along with this program; if not, write to the Free Software
    // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    // USA.
    // 
    // Please report all bugs and problems to <gmsh@geuz.org>.
    
    #include "GmshUI.h"
    #include "Draw.h"
    #include "PView.h"
    #include "gl2ps.h"
    #include "Context.h"
    
    extern Context_T CTX;
    
    void Draw_Text2D()
    {
      for(unsigned int i = 0; i < PView::list.size(); i++){
        PViewData *data = PView::list[i]->getData();
        PViewOptions *opt = PView::list[i]->getOptions();
        if(opt->Visible && opt->DrawStrings){
          glColor4ubv((GLubyte *) & opt->color.text2d);
          for(int j = 0; j < data->getNumStrings2D(); j++){
    	double x, y, style;
    	std::string str;
    	data->getString2D(j, opt->TimeStep, str, x, y, style);
    	Fix2DCoordinates(&x, &y);
    	glRasterPos2d(x, y);
    	Draw_String((char*)str.c_str(), style);
          }
        }
      }
    }
    
    static bool getGraphData(PView *p, std::vector<double> &x, double &xmin, 
    			 double &xmax, std::vector<std::vector<double> > &y, 
    			 double &ymin, double ymax) 
    {
      PViewData *data = p->getData();
      PViewOptions *opt = p->getOptions();
    
      int numy = 0;
      if(opt->Type == PViewOptions::Plot2DSpace){
        numy = 1;
      }
      else if(opt->Type == PViewOptions::Plot2DTime){
        numy = 0;
        for(int i = 0; i < data->getNumElements(); i++)
          if(data->getDimension(i) < 2) numy++;
      }
      
      if(!numy) return false;
      y.resize(numy);
    
      for(int i = 0; i < data->getNumElements(); i++){
        int dim = data->getDimension(i);
        if(dim < 2){
          int numNodes = data->getNumNodes(i);
          int numComp = data->getNumComponents(i);
          for(int ts = 0; ts < data->getNumTimeSteps(); ts++){
    	if(opt->Type == PViewOptions::Plot2DSpace) ts = opt->TimeStep;
    	for(int j = 0; j < numNodes; j++){
    	  double val[9], xyz[3];
    	  data->getNode(i, j, xyz[0], xyz[1], xyz[2]);
    	  for(int k = 0; k < numComp; k++)
    	    data->getValue(i, j, k, ts, val[k]);
    	  double vx = ComputeScalarRep(3, xyz);
    	  double vy = ComputeScalarRep(numComp, val);
    	  if(opt->Type == PViewOptions::Plot2DTime){
    	    x.push_back(ts);
    	    y[i].push_back(vy);
    	  }
    	  else if(opt->Type == PViewOptions::Plot2DSpace){
    	    x.push_back(vx);
    	    y[0].push_back(vy);
    	  }
    	}
    	if(opt->Type == PViewOptions::Plot2DSpace) break;
          }
        }
      }
    
      if(x.empty()) return false;
    
      xmin = xmax = x[0];
      ymin = ymax = y[0][0];
      for(unsigned int i = 1; i < x.size(); i++){
        xmin = std::min(xmin, x[i]);
        xmax = std::max(xmax, x[i]);
        for(unsigned int j = 0; j < y.size(); j++){
          ymin = std::min(ymin, y[j][i]);
          ymax = std::max(ymax, y[j][i]);
        }
      }
    
      return true;
    }
    
    static void drawGraphAxes(PView *p, double xleft, double ytop, double width,
    			  double height, double xmin, double xmax)
    {
      PViewData *data = p->getData();
      PViewOptions *opt = p->getOptions();
    
      if(!opt->Axes) return;
    
      char label[1024];    
      float font_h = gl_height() ? gl_height() : 1; // total font height
      float font_a = font_h - gl_descent(); // height above ref. point
    
      const double tic = 5.;
    
      glPointSize(CTX.point_size);
      gl2psPointSize(CTX.point_size * CTX.print.eps_point_size_factor);
    
      glLineWidth(CTX.line_width);
      gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
    
      glColor4ubv((GLubyte *) & opt->color.axes);
    
      // bare axes
      glBegin(GL_LINE_STRIP);
      glVertex2d(xleft, ytop);
      glVertex2d(xleft, ytop - height);
      glVertex2d(xleft + width, ytop - height);
      if(opt->Axes > 1) {
        glVertex2d(xleft + width, ytop);
        glVertex2d(xleft, ytop);
      }
      glEnd();
    
      // y label
      if(opt->Type == PViewOptions::Plot2DSpace && opt->ShowTime > 2){
        char tmp[256];
        sprintf(tmp, opt->Format, data->getTime(opt->TimeStep));
        sprintf(label, "%s (%s)", p->getName().c_str(), tmp);
      }
      else if(opt->Type == PViewOptions::Plot2DSpace && opt->ShowTime > 0){
        sprintf(label, "%s (%d)", p->getName().c_str(), opt->TimeStep);
      }
      else
        sprintf(label, "%s", p->getName().c_str());
      glRasterPos2d(xleft, ytop + font_h + tic);
      Draw_String_Center(label);
      
      // x label
      sprintf(label, "%s", opt->AxesLabel[0]);
      glRasterPos2d(xleft + width / 2, ytop - height - 2 * font_h - 2 * tic);
      Draw_String_Center(label);
    
      // y tics and horizontal grid
      if(opt->NbIso > 0){
        int nb = opt->NbIso;
        if(opt->ShowScale && (opt->NbIso * font_h > height))
          nb = (int)floor(height / font_h);
        double dy = height / (double)nb;
        double dv = (opt->TmpMax - opt->TmpMin) / (double)nb;
        for(int i = 0; i < nb + 1; i++){
          if(opt->Axes > 0){
    	glBegin(GL_LINES);
    	glVertex2d(xleft, ytop - i * dy);
    	glVertex2d(xleft + tic, ytop - i * dy);
    	if(opt->Axes > 1) {
    	  glVertex2d(xleft + width - tic, ytop - i * dy);
    	  glVertex2d(xleft + width, ytop - i * dy);
    	}
    	glEnd();
    	if(opt->Axes > 2 && i != 0 && i != nb) {
    	  glEnable(GL_LINE_STIPPLE);
    	  glLineStipple(1, 0x1111);
    	  gl2psEnable(GL2PS_LINE_STIPPLE);
    	  gl2psLineWidth(1. * CTX.print.eps_line_width_factor);
    	  glBegin(GL_LINES);
    	  glVertex2d(xleft, ytop - i * dy);
    	  glVertex2d(xleft + width, ytop - i * dy);
    	  glEnd();
    	  glDisable(GL_LINE_STIPPLE);
    	  gl2psDisable(GL2PS_LINE_STIPPLE);
    	  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
    	}
          }
          if(opt->ShowScale) {
    	sprintf(label, opt->Format, (i == nb) ? opt->TmpMin : (opt->TmpMax - i * dv));
    	glRasterPos2d(xleft - 2 * tic, ytop - i * dy - font_a / 3.);
    	Draw_String_Right(label);
          }
        }
      }
    
      // x tics and vertical grid
      if(opt->AxesTics[0] > 0){
        int nb = opt->AxesTics[0];
        if(opt->Axes) {
          sprintf(label, opt->AxesFormat[0], - M_PI * 1.e-4);
          if((nb - 1) * gl_width(label) > width)
    	nb = (int)(width / gl_width(label)) + 1;
        }
        if(nb == 1) nb++;
        
        double dx = width / (double)(nb - 1);
        double ybot = ytop - height;
        
        for(int i = 0; i < nb; i++) {
          if(opt->Axes) {
    	glBegin(GL_LINES);
    	glVertex2d(xleft + i * dx, ybot);
    	glVertex2d(xleft + i * dx, ybot + tic);
    	if(opt->Axes > 1) {
    	  glVertex2d(xleft + i * dx, ytop);
    	  glVertex2d(xleft + i * dx, ytop - tic);
    	}
    	glEnd();
    	if(opt->Axes > 2 && i != 0 && i != nb - 1) {
    	  glEnable(GL_LINE_STIPPLE);
    	  glLineStipple(1, 0x1111);
    	  gl2psEnable(GL2PS_LINE_STIPPLE);
    	  gl2psLineWidth(1. * CTX.print.eps_line_width_factor);
    	  glBegin(GL_LINES);
    	  glVertex2d(xleft + i * dx, ytop);
    	  glVertex2d(xleft + i * dx, ybot);
    	  glEnd();
    	  glDisable(GL_LINE_STIPPLE);
    	  gl2psDisable(GL2PS_LINE_STIPPLE);
    	  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
    	}
    	
    	if(nb == 1)
    	  sprintf(label, opt->AxesFormat[0], xmin);
    	else
    	  sprintf(label, opt->AxesFormat[0],
    		  xmin + i * (xmax - xmin) / (double)(nb - 1));
    	glRasterPos2d(xleft + i * dx, ybot - font_h - tic);
    	Draw_String_Center(label);
          }
        }
      }
      
    }
    
    static void addGraphPoint(PView *p, double xleft, double ytop, double width, 
    			  double height, double x, double y, double xmin, 
    			  double xmax, double ymin, double ymax)
    {
      PViewOptions *opt = p->getOptions();
    
      double px = xleft;
      if(xmin != xmax) px += (x - xmin) / (xmax - xmin) * width;
    
      if(opt->SaturateValues) {
        if(y > ymax)
          y = ymax;
        else if(y < ymin)
          y = ymin;
      }
      
      double ybot = ytop - height;
      double py = ybot;
      if(ymax != ymin) py += (y - ymin) / (ymax - ymin) * height;
    
      if(y >= ymin && y <= ymax) {
        unsigned int col = opt->getColor(y, ymin, ymax, true);
        glColor4ubv((GLubyte *) &col);
        if(opt->IntervalsType == PViewOptions::Numeric) {
          glRasterPos2d(px + 3, py + 3);
          char label[256];
          sprintf(label, opt->Format, y);
          Draw_String(label);
        }
        else
          glVertex2d(px, py);
      }
    }
    
    static void drawGraphCurves(PView *p, double xleft, double ytop, double width,
    			    double height, std::vector<double> &x, double xmin,
    			    double xmax, std::vector<std::vector<double> > &y)
    {
      PViewData *data = p->getData();
      PViewOptions *opt = p->getOptions();
    
      glPointSize(opt->PointSize);
      gl2psPointSize(opt->PointSize * CTX.print.eps_point_size_factor);
    
      glLineWidth(opt->LineWidth);
      gl2psLineWidth(opt->LineWidth * CTX.print.eps_line_width_factor);
    
      if(opt->IntervalsType == PViewOptions::Iso ||
         opt->IntervalsType == PViewOptions::Discrete ||
         opt->IntervalsType == PViewOptions::Numeric){
        glBegin(GL_POINTS);
        for(unsigned int i = 0; i < y.size(); i++)
          for(unsigned int j = 0; j < x.size(); j++)
    	addGraphPoint(p, xleft, ytop, width, height, x[j], y[i][j], 
    		      xmin, xmax, opt->TmpMin, opt->TmpMax);
        glEnd();    
      }
    
      if(opt->IntervalsType == PViewOptions::Discrete ||
         opt->IntervalsType == PViewOptions::Continuous){
        for(unsigned int i = 0; i < y.size(); i ++) {
          if(opt->UseStipple){
    	glEnable(GL_LINE_STIPPLE);
    	glLineStipple(opt->Stipple[i % 10][0], opt->Stipple[i % 10][1]);
    	gl2psEnable(GL2PS_LINE_STIPPLE);
          }
          glBegin(GL_LINE_STRIP);
          for(unsigned int j = 0; j < x.size(); j++)
    	addGraphPoint(p, xleft, ytop, width, height, x[j], y[i][j], 
    		      xmin, xmax, opt->TmpMin, opt->TmpMax);
          glEnd();
          if(opt->UseStipple){
    	glDisable(GL_LINE_STIPPLE);
    	gl2psDisable(GL2PS_LINE_STIPPLE);
          }
        }
      }
    }
    
    static void drawGraph(PView *p, double xleft, double ytop, double width, double height)
    {
      PViewData *data = p->getData();
      PViewOptions *opt = p->getOptions();
      
      if(opt->RangeType == PViewOptions::Custom){
        opt->TmpMin = opt->CustomMin;
        opt->TmpMax = opt->CustomMax;
      }
      else if(opt->RangeType == PViewOptions::PerTimeStep){
        opt->TmpMin = data->getMin(opt->TimeStep);
        opt->TmpMax = data->getMax(opt->TimeStep);
      }
      else{
        opt->TmpMin = data->getMin();
        opt->TmpMax = data->getMax();
      }
      
      std::vector<double> x;
      std::vector<std::vector<double> > y;
      double xmin, xmax, ymin, ymax;
      if(!getGraphData(p, x, xmin, xmax, y, ymin, ymax)) return;
      drawGraphAxes(p, xleft, ytop, width, height, xmin, xmax);
      drawGraphCurves(p, xleft, ytop, width, height, x, xmin, xmax, y);
    }
    
    void Draw_Graph2D()
    {
      std::vector<PView*> graphs;
      for(unsigned int i = 0; i < PView::list.size(); i++){
        PViewData *data = PView::list[i]->getData();
        PViewOptions *opt = PView::list[i]->getOptions();
        if(!data->getDirty() && opt->Visible && opt->Type != PViewOptions::Plot3D)
          graphs.push_back(PView::list[i]);
      }
      if(graphs.empty()) return;
    
      gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
      double xsep = 0., ysep = 5 * gl_height();
      char label[1024];
      for(unsigned int i = 0; i < graphs.size(); i++) {
        PViewOptions *opt = graphs[i]->getOptions();
        sprintf(label, opt->Format, -M_PI * 1.e-4);
        xsep = std::max(xsep, gl_width(label));
      }
      
      for(unsigned int i = 0; i < graphs.size(); i++) {
        PView *p = graphs[i];
        PViewOptions *opt = graphs[i]->getOptions();
        if(!opt->AutoPosition) {
          double x = opt->Position[0], y = opt->Position[1];
          int center = Fix2DCoordinates(&x, &y);
          drawGraph(p, x - (center & 1 ? opt->Size[0] / 2. : 0), 
    		y + (center & 2 ? opt->Size[1] / 2. : 0), 
    		opt->Size[0], opt->Size[1]);
        }
        else{
          double winw = CTX.viewport[2] - CTX.viewport[0];
          double winh = CTX.viewport[3] - CTX.viewport[1];
          if(graphs.size() == 1){
    	double fracw = 0.75, frach = 0.75;
    	double w = fracw * winw - xsep;
    	double h = frach * winh - ysep;
    	double x = CTX.viewport[0] + (1 - fracw) / 2. * winw;
    	double y = CTX.viewport[1] + (1 - frach) / 2. * winh;
    	drawGraph(p, x + 0.95 * xsep, CTX.viewport[3] - (y + 0.4 * ysep), w, h);
          }
          else if(graphs.size() == 2){
    	double fracw = 0.75, frach = 0.85;
    	double w = fracw * winw - xsep;
    	double h = frach * winh / 2. - ysep;
    	double x = CTX.viewport[0] + (1 - fracw) / 2. * winw;
    	double y = CTX.viewport[1] + (1 - frach) / 3. * winh;
    	if(i == 1) y += (h + ysep + (1 - frach) / 3. * winh);
    	drawGraph(p, x + 0.95 * xsep, CTX.viewport[3] - (y + 0.4 * ysep), w, h);
          }
          else{
    	double fracw = 0.85, frach = 0.85;
    	double w = fracw * winw / 2. - xsep;
    	double h = frach * winh / 2. - ysep;
    	double x = CTX.viewport[0] + (1 - fracw) / 3. * winw;
    	if(i == 1 || i == 3) x += (w + xsep + (1-fracw)/3. * winw);
    	double y = CTX.viewport[1] + (1 - frach) / 3. * winh;
    	if(i == 2 || i == 3) y += (h + ysep + (1 - frach) / 3. * winh);
    	drawGraph(p, x + 0.95 * xsep, CTX.viewport[3] - (y + 0.4 * ysep), w, h);
          }
        }
      }
    }