Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/plotter is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_sg_plotter
0005 #define tools_sg_plotter
0006 
0007 #include "../lina/vec2f"
0008 
0009 #include "render_action"
0010 #include "plottables"
0011 #include "style"
0012 #include "rep"
0013 #include "colormap"
0014 #include "noderef"
0015 #include "atb_vertices"
0016 #include "cube" //for lego
0017 #include "matrix"
0018 #include "normal"
0019 #include "holder"
0020 #include "tex_rect" //for plottable_img.
0021 
0022 #include "axis"
0023 #include "infos_box"
0024 #include "legend"
0025 #include "text"
0026 #include "torche"
0027 #include "ellipse"
0028 
0029 #include "../data_axis"
0030 #include "../hatcher"
0031 #include "../clist_contour"
0032 #include "../tess_contour"
0033 #include "../lina/geom3"
0034 #include "../spline"
0035 #include "../rtausmef"
0036 
0037 #include <utility>
0038 
0039 namespace tools {
0040 namespace sg {
0041 
0042 class plotter : public node {
0043   TOOLS_NODE(plotter,tools::sg::plotter,node)
0044 private:
0045   static const std::string& s_infos_what_def() {
0046     static const std::string s_v("name entries mean rms fit_quality fit_ndf fit_parameters fit_errors");
0047     return s_v;
0048   }
0049   static float default_infos_margin() {return 0.005f;}
0050   static float default_title_box_width()    {return 0.3f;}
0051   static float default_title_box_height()   {return 0.05f;}
0052   static float default_title_box_x_margin() {return 0.01f;}
0053   static float default_title_box_y_margin() {return 0.005f;}
0054 public:
0055   sf<float> width;          //PAW XSIZ
0056   sf<float> height;         //PAW YSIZ
0057   sf<float> left_margin;    //PAW XMGL
0058   sf<float> right_margin;   //PAW XMGR
0059   sf<float> bottom_margin;  //PAW YMGL
0060   sf<float> top_margin;     //PAW YMGU
0061 
0062   sf<float> depth;
0063   sf<float> down_margin;
0064   sf<float> up_margin;
0065 
0066   sf<bool> title_up;
0067   sf<float> title_to_axis;
0068   sf<float> title_height;
0069   sf<bool> title_automated;
0070   sf_enum<hjust> title_hjust;
0071   sf_string title; //output if title_automated.
0072 
0073   sf<bool> colormap_visible;
0074   enum colormap_axis_labeling_type {
0075     cells = 0,
0076     min_max
0077   };
0078   sf_enum<colormap_axis_labeling_type> colormap_axis_labeling;
0079   sf<bool> colormap_attached;
0080   sf<bool> colormap_axis_visible;
0081 
0082   // Wanted axes parameters.
0083   // They are not necessary realized on the sg::axis nodes.
0084   sf<bool> x_axis_enforced;
0085   sf<bool> x_axis_automated;
0086   sf<float> x_axis_min;
0087   sf<float> x_axis_max;
0088   sf<bool> x_axis_is_log;
0089 
0090   sf<bool> y_axis_enforced;
0091   sf<bool> y_axis_automated;
0092   sf<float> y_axis_min;
0093   sf<float> y_axis_max;
0094   sf<bool> y_axis_is_log;
0095 
0096   sf<bool> z_axis_enforced;
0097   sf<bool> z_axis_automated;
0098   sf<float> z_axis_min;
0099   sf<float> z_axis_max;
0100   sf<bool> z_axis_is_log;
0101 
0102   sf<float> value_top_margin;
0103   sf<float> value_bottom_margin;
0104   sf<bool> value_bins_with_entries;
0105 
0106   sf<float> infos_width; //in percent of width.
0107   sf<float> infos_x_margin; //in percent of width. From right.
0108   sf<float> infos_y_margin; //in percent of height. From top.
0109   sf_string infos_what;
0110 
0111   sf<float> title_box_width;    //in percent of width.
0112   sf<float> title_box_height;   //in percent of height.
0113   sf<float> title_box_x_margin; //in percent of width. From left.
0114   sf<float> title_box_y_margin; //in percent of height. From top.
0115 
0116   sf<bool> func2D_borders_visible;
0117 
0118   // used with shape xyz
0119   sf<float> theta;  //in degrees.
0120   sf<float> phi;    //in degrees.
0121   sf<float> tau;    //in degrees.
0122 
0123   ////////////////////////////////////////////////////////////////
0124   /// legend related :////////////////////////////////////////////
0125   ////////////////////////////////////////////////////////////////
0126   sf<bool> legends_automated;
0127   //sf<bool> legends_attached_to_infos;
0128   //if legends_attached_to_infos is false :
0129   //  legends_origin is used to place the legends. It is then
0130   //  the lower left corner of the box containing all legends.
0131   mf_vec<vec2f,float> legends_origin; //common origin of legend boxes.
0132   enum unit_type {
0133     unit_percent,
0134     unit_axis
0135   };
0136   mf_enum<unit_type> legends_origin_unit;
0137   mf_vec<vec2f,float> legends_size; //overall legend boxes size.
0138   mf_string legends_string;
0139 
0140   ////////////////////////////////////////////////////////////////
0141   ////////////////////////////////////////////////////////////////
0142   ////////////////////////////////////////////////////////////////
0143 
0144   sf<bool> shape_automated;
0145 
0146   enum shape_type {
0147     xy = 0,
0148     xyz
0149   };
0150   sf_enum<shape_type> shape;
0151 
0152   // used with xy shape :
0153   sf<float> xy_depth; //all is in z [0,xy_depth]
0154 
0155   sf<unsigned int> curve_number_of_points;
0156 
0157   sf<bool> data_light_on_automated;
0158 
0159   // for gopaw :
0160   sf<bool> primitives_enforced;
0161   sf<bool> inner_frame_enforced;
0162   // to be implemented :
0163   sf<bool> top_axis_visible;
0164   sf<bool> right_axis_visible;
0165   sf<bool> superpose_bins;
0166   // For contours :
0167   sf<unsigned int> number_of_levels;
0168   mf<float> levels;
0169 
0170 public:
0171   virtual const desc_fields& node_desc_fields() const {
0172     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::plotter)
0173     static const desc_fields s_v(parent::node_desc_fields(),63, //WARNING : take care of count.
0174 
0175       TOOLS_ARG_FIELD_DESC(width),
0176       TOOLS_ARG_FIELD_DESC(height),
0177       TOOLS_ARG_FIELD_DESC(left_margin),
0178       TOOLS_ARG_FIELD_DESC(right_margin),
0179       TOOLS_ARG_FIELD_DESC(bottom_margin),
0180       TOOLS_ARG_FIELD_DESC(top_margin),
0181       TOOLS_ARG_FIELD_DESC(depth),
0182       TOOLS_ARG_FIELD_DESC(down_margin),
0183       TOOLS_ARG_FIELD_DESC(up_margin),
0184       TOOLS_ARG_FIELD_DESC(colormap_visible),  //10
0185 
0186       TOOLS_ARG_FIELD_DESC_ENUMS_BEG(colormap_axis_labeling,2)
0187         TOOLS_ARG_ENUM(cells),
0188         TOOLS_ARG_ENUM(min_max)
0189       TOOLS_ARG_FIELD_DESC_ENUMS_END,
0190 
0191       TOOLS_ARG_FIELD_DESC(colormap_attached),
0192       TOOLS_ARG_FIELD_DESC(colormap_axis_visible),
0193 
0194       TOOLS_ARG_FIELD_DESC(title_up),
0195       TOOLS_ARG_FIELD_DESC(title_to_axis),
0196       TOOLS_ARG_FIELD_DESC(title_height),
0197       TOOLS_ARG_FIELD_DESC(title_automated),
0198 
0199       TOOLS_ARG_FIELD_DESC_ENUMS_BEG(title_hjust,3)
0200         "left",left,
0201         "center",center,
0202         "right",right
0203       TOOLS_ARG_FIELD_DESC_ENUMS_END,
0204 
0205       TOOLS_ARG_FIELD_DESC(title),
0206 
0207       TOOLS_ARG_FIELD_DESC(x_axis_enforced),  //20
0208       TOOLS_ARG_FIELD_DESC(x_axis_automated),
0209       TOOLS_ARG_FIELD_DESC(x_axis_min),
0210       TOOLS_ARG_FIELD_DESC(x_axis_max),
0211       TOOLS_ARG_FIELD_DESC(x_axis_is_log),
0212 
0213       TOOLS_ARG_FIELD_DESC(y_axis_enforced),
0214       TOOLS_ARG_FIELD_DESC(y_axis_automated),
0215       TOOLS_ARG_FIELD_DESC(y_axis_min),
0216       TOOLS_ARG_FIELD_DESC(y_axis_max),
0217       TOOLS_ARG_FIELD_DESC(y_axis_is_log),
0218 
0219       TOOLS_ARG_FIELD_DESC(z_axis_enforced),  //30
0220       TOOLS_ARG_FIELD_DESC(z_axis_automated),
0221       TOOLS_ARG_FIELD_DESC(z_axis_min),
0222       TOOLS_ARG_FIELD_DESC(z_axis_max),
0223       TOOLS_ARG_FIELD_DESC(z_axis_is_log),
0224 
0225       TOOLS_ARG_FIELD_DESC(value_top_margin),
0226       TOOLS_ARG_FIELD_DESC(value_bottom_margin),
0227       TOOLS_ARG_FIELD_DESC(value_bins_with_entries),
0228 
0229       TOOLS_ARG_FIELD_DESC(infos_width),
0230       TOOLS_ARG_FIELD_DESC(infos_x_margin),
0231       TOOLS_ARG_FIELD_DESC(infos_y_margin), //40
0232       TOOLS_ARG_FIELD_DESC(infos_what),
0233 
0234       TOOLS_ARG_FIELD_DESC(func2D_borders_visible),
0235       TOOLS_ARG_FIELD_DESC(theta),
0236       TOOLS_ARG_FIELD_DESC(phi),
0237       TOOLS_ARG_FIELD_DESC(tau),
0238 
0239       TOOLS_ARG_FIELD_DESC(legends_automated),
0240 
0241       TOOLS_ARG_FIELD_DESC_ENUMS_BEG(legends_origin,2)
0242         "unit_percent",unit_percent,
0243         "unit_axis",unit_axis
0244       TOOLS_ARG_FIELD_DESC_ENUMS_END,
0245 
0246       TOOLS_ARG_FIELD_DESC(legends_origin_unit),
0247       TOOLS_ARG_FIELD_DESC(legends_size),
0248       TOOLS_ARG_FIELD_DESC(legends_string), //50
0249 
0250       TOOLS_ARG_FIELD_DESC(shape_automated),
0251 
0252       TOOLS_ARG_FIELD_DESC_ENUMS_BEG(shape,2)
0253         "xy",xy,
0254         "xyz",xyz
0255       TOOLS_ARG_FIELD_DESC_ENUMS_END,
0256 
0257       TOOLS_ARG_FIELD_DESC(xy_depth),
0258       TOOLS_ARG_FIELD_DESC(curve_number_of_points),
0259 
0260       TOOLS_ARG_FIELD_DESC(number_of_levels),
0261       TOOLS_ARG_FIELD_DESC(levels),
0262 
0263       TOOLS_ARG_FIELD_DESC(data_light_on_automated),
0264 
0265       TOOLS_ARG_FIELD_DESC(primitives_enforced),
0266       TOOLS_ARG_FIELD_DESC(inner_frame_enforced),
0267 
0268       TOOLS_ARG_FIELD_DESC(title_box_width), //60
0269       TOOLS_ARG_FIELD_DESC(title_box_height),
0270       TOOLS_ARG_FIELD_DESC(title_box_x_margin),
0271       TOOLS_ARG_FIELD_DESC(title_box_y_margin)   //63
0272 
0273     );
0274     return s_v;
0275   }
0276   virtual bool touched() {
0277     if(parent::touched()) return true;
0278 
0279     if(background_style().touched()) return true;
0280     if(title_style().touched()) return true;
0281     if(infos_style().touched()) return true;
0282     if(title_box_style().touched()) return true;
0283     if(inner_frame_style().touched()) return true;
0284     if(grid_style().touched()) return true;
0285     if(wall_style().touched()) return true;
0286 
0287    {tools_vforit(style,m_bins_style,it) {if((*it).touched()) return true;}}
0288    {tools_vforit(style,m_errors_style,it) {if((*it).touched()) return true;}}
0289    {tools_vforit(style,m_func_style,it) {if((*it).touched()) return true;}}
0290    {tools_vforit(style,m_points_style,it) {if((*it).touched()) return true;}}
0291    {tools_vforit(style,m_left_hatch_style,it) {if((*it).touched()) return true;}}
0292    {tools_vforit(style,m_right_hatch_style,it) {if((*it).touched()) return true;}}
0293    {tools_vforit(style,m_legend_style,it) {if((*it).touched()) return true;}}
0294 
0295     return false;
0296   }
0297   virtual void reset_touched() {
0298     parent::reset_touched();
0299 
0300     background_style().reset_touched();
0301     title_style().reset_touched();
0302     infos_style().reset_touched();
0303     title_box_style().reset_touched();
0304     inner_frame_style().reset_touched();
0305     grid_style().reset_touched();
0306     wall_style().reset_touched();
0307 
0308    {tools_vforit(style,m_bins_style,it) (*it).reset_touched();}
0309    {tools_vforit(style,m_errors_style,it) (*it).reset_touched();}
0310    {tools_vforit(style,m_func_style,it) (*it).reset_touched();}
0311    {tools_vforit(style,m_points_style,it) (*it).reset_touched();}
0312    {tools_vforit(style,m_left_hatch_style,it) (*it).reset_touched();}
0313    {tools_vforit(style,m_right_hatch_style,it) (*it).reset_touched();}
0314    {tools_vforit(style,m_legend_style,it) (*it).reset_touched();}
0315   }
0316 
0317 private:
0318   void add_fields(){
0319     // if adding a field, look for reset_style(), set_from_style() and set_from_string()
0320     add_field(&width);
0321     add_field(&height);
0322     add_field(&left_margin);
0323     add_field(&right_margin);
0324     add_field(&bottom_margin);
0325     add_field(&top_margin);
0326     add_field(&depth);
0327     add_field(&down_margin);
0328     add_field(&up_margin);
0329 
0330     add_field(&title_up);
0331     add_field(&title_to_axis);
0332     add_field(&title_height);
0333     add_field(&title_automated);
0334     add_field(&title_hjust);
0335     add_field(&title);
0336 
0337     add_field(&x_axis_enforced);
0338     add_field(&x_axis_automated);
0339     add_field(&x_axis_min);
0340     add_field(&x_axis_max);
0341     add_field(&x_axis_is_log);
0342 
0343     add_field(&y_axis_enforced);
0344     add_field(&y_axis_automated);
0345     add_field(&y_axis_min);
0346     add_field(&y_axis_max);
0347     add_field(&y_axis_is_log);
0348 
0349     add_field(&z_axis_enforced);
0350     add_field(&z_axis_automated);
0351     add_field(&z_axis_min);
0352     add_field(&z_axis_max);
0353     add_field(&z_axis_is_log);
0354 
0355     add_field(&value_top_margin);
0356     add_field(&value_bottom_margin);
0357     add_field(&value_bins_with_entries);
0358 
0359     add_field(&infos_width);
0360     add_field(&infos_x_margin);
0361     add_field(&infos_y_margin);
0362     add_field(&infos_what);
0363 
0364     add_field(&title_box_width);
0365     add_field(&title_box_height);
0366     add_field(&title_box_x_margin);
0367     add_field(&title_box_y_margin);
0368 
0369     add_field(&func2D_borders_visible);
0370     add_field(&theta);
0371     add_field(&phi);
0372     add_field(&tau);
0373 
0374     add_field(&legends_automated);
0375     //add_field(&legends_attached_to_infos);
0376     add_field(&legends_origin);
0377     add_field(&legends_origin_unit);
0378     add_field(&legends_size);
0379     add_field(&legends_string);
0380 
0381     add_field(&shape_automated);
0382     add_field(&shape);
0383 
0384     add_field(&xy_depth);
0385     add_field(&curve_number_of_points);
0386     add_field(&number_of_levels);
0387     add_field(&levels);
0388     add_field(&data_light_on_automated);
0389     add_field(&primitives_enforced);
0390     add_field(&inner_frame_enforced);
0391   }
0392 public: //style
0393   void copy_style(const plotter& a_from) {  //used in sg::plots.
0394     ////////////////////////////////////////////
0395     ////////////////////////////////////////////
0396     ////////////////////////////////////////////
0397     shape_automated = a_from.shape_automated;
0398     shape = a_from.shape;
0399     xy_depth = a_from.xy_depth;
0400     curve_number_of_points = a_from.curve_number_of_points;
0401     value_top_margin = a_from.value_top_margin;
0402     value_bottom_margin = a_from.value_bottom_margin;
0403     value_bins_with_entries = a_from.value_bins_with_entries;
0404     infos_what = a_from.infos_what;
0405     infos_width = a_from.infos_width;
0406     //infos height is automatic.
0407     infos_x_margin = a_from.infos_x_margin;
0408     infos_y_margin = a_from.infos_y_margin;
0409 
0410     title_box_width = a_from.title_box_width;
0411     title_box_height = a_from.title_box_height;
0412     title_box_x_margin = a_from.title_box_x_margin;
0413     title_box_y_margin = a_from.title_box_y_margin;
0414 
0415     legends_automated = a_from.legends_automated;
0416     title_automated = a_from.title_automated;
0417     title = a_from.title;
0418     title_up = a_from.title_up;
0419     title_hjust = a_from.title_hjust;
0420 
0421     colormap_visible = a_from.colormap_visible;
0422     colormap_axis_labeling = a_from.colormap_axis_labeling;
0423     colormap_attached = a_from.colormap_attached;
0424     colormap_axis_visible = a_from.colormap_axis_visible;
0425 
0426     number_of_levels = a_from.number_of_levels;
0427     levels  = a_from.levels;
0428     data_light_on_automated = a_from.data_light_on_automated;
0429     primitives_enforced = a_from.primitives_enforced;
0430     inner_frame_enforced = a_from.inner_frame_enforced;
0431 
0432     ////////////////////////////////////////////
0433     ////////////////////////////////////////////
0434     ////////////////////////////////////////////
0435     x_axis_enforced = a_from.x_axis_enforced;
0436     x_axis_automated = a_from.x_axis_automated;
0437     x_axis_min = a_from.x_axis_min;
0438     x_axis_max = a_from.x_axis_max;
0439     x_axis_is_log = a_from.x_axis_is_log;
0440 
0441     y_axis_enforced = a_from.y_axis_enforced;
0442     y_axis_automated = a_from.y_axis_automated;
0443     y_axis_min = a_from.y_axis_min;
0444     y_axis_max = a_from.y_axis_max;
0445     y_axis_is_log = a_from.y_axis_is_log;
0446 
0447     z_axis_enforced = a_from.z_axis_enforced;
0448     z_axis_automated = a_from.z_axis_automated;
0449     z_axis_min = a_from.z_axis_min;
0450     z_axis_max = a_from.z_axis_max;
0451     z_axis_is_log = a_from.z_axis_is_log;
0452 
0453     ////////////////////////////////////////////
0454     ////////////////////////////////////////////
0455     ////////////////////////////////////////////
0456 
0457     m_background_style = a_from.m_background_style;
0458     m_title_style = a_from.m_title_style;
0459     m_infos_style = a_from.m_infos_style;
0460     m_title_box_style = a_from.m_title_box_style;
0461     m_inner_frame_style = a_from.m_inner_frame_style;
0462     m_grid_style = a_from.m_grid_style;
0463     m_wall_style = a_from.m_wall_style;
0464 
0465     m_bins_style = a_from.m_bins_style;
0466     m_errors_style = a_from.m_errors_style;
0467     m_func_style = a_from.m_func_style;
0468     m_points_style = a_from.m_points_style;
0469     m_left_hatch_style = a_from.m_left_hatch_style;
0470     m_right_hatch_style = a_from.m_right_hatch_style;
0471     m_legend_style = a_from.m_legend_style;
0472   }
0473 
0474   void reset_style(bool a_geom = false) {
0475     //reset fields that are considered as part of the style.
0476 
0477     //::printf("debug : tools::sg::plotter::reset_style :\n");
0478 
0479     shape_automated = true;
0480     shape = xy;
0481 
0482     xy_depth = 0.01f;
0483     curve_number_of_points = 100;
0484     ////////////////////////////////////////////
0485     value_top_margin = 0.1f; //percent.  // CERN-PAW seems to have 0.1F and CERN-ROOT 0.05F.
0486     value_bottom_margin = 0.0f; //percent.
0487     value_bins_with_entries = true; //gopaw uses false.
0488 
0489     infos_what = s_infos_what_def();
0490     infos_width = 0.3f;
0491     //infos height is automatic.
0492     infos_x_margin = default_infos_margin(); //percent of width
0493     infos_y_margin = default_infos_margin(); //percent of height
0494 
0495     title_box_width = default_title_box_width();
0496     title_box_height = default_title_box_height();
0497     title_box_x_margin = default_title_box_x_margin(); //percent of width
0498     title_box_y_margin = default_title_box_y_margin(); //percent of height
0499 
0500     legends_automated = true;
0501 
0502     ////////////////////////////////////////////
0503 
0504     if(a_geom) {
0505     float xfac = 1.0F/20.0F; //0.05
0506     float yfac = 1.0F/20.0F; //0.05
0507 
0508     // Take PAW defaults :
0509     float XSIZ = 20 * xfac;    //1     //page width
0510     float YSIZ = 20 * yfac;    //1     //page height
0511     float XMGL = 2 * xfac;     //0.1   //left x margin (to data frame).
0512     float XMGR = 2 * xfac;     //0.1   //right y margin (to data frame).
0513     float YMGL = 2 * yfac;     //0.1   //low y margin (to data frame).
0514     float YMGU = 2 * yfac;     //0.1   //up y margin (to data frame).
0515     // Axes :
0516     float VSIZ = 0.28F * yfac; //0.014 //tick label character size.
0517     float XVAL = 0.4F * xfac;  //0.02 //x distance of y tick label to data frame.
0518     float YVAL = 0.4F * yfac;  //0.02 //y distance of x tick label to data frame.
0519     float XTIC = 0.3F * yfac;  //0.015 //y length of X axis ticks.
0520     float YTIC = 0.3F * xfac;  //0.015 //x length of Y axis ticks.
0521     float XLAB = 1.4F * xfac;  //0.07  //x distance of y title to data frame.
0522     float YLAB = 0.8F * yfac;  //0.04  //y distance of x title to data frame.
0523     float ASIZ = 0.28F * yfac; //0.014 // axis title (label) character size.
0524 
0525     float YHTI = 1.2F * yfac;  //0.06  //y distance of title to x axis.
0526     float TSIZ = 0.28F * yfac; //0.014 //title character size
0527 
0528     float zfac = 1.0F/20.0F; //0.05
0529     float ZSIZ = 20 * zfac;    //1     //page depth
0530     float ZMGD = 2 * zfac;     //0.1   //low y margin (to data frame).
0531     float ZMGU = 2 * zfac;     //0.1   //up y margin (to data frame).
0532 
0533     width = XSIZ;
0534     height = YSIZ;
0535     depth = ZSIZ;
0536 
0537     left_margin = XMGL;
0538     right_margin = XMGR;
0539     bottom_margin = YMGL;
0540     top_margin = YMGU;
0541     down_margin = ZMGD;
0542     up_margin = ZMGU;
0543 
0544     title_to_axis = YHTI;
0545     title_height = TSIZ;
0546 
0547     if(shape.value()==xy) {
0548       m_x_axis.tick_length.value(XTIC);
0549       m_x_axis.label_to_axis.value(YVAL);
0550       m_x_axis.label_height.value(VSIZ);
0551       m_x_axis.title_to_axis.value(YLAB);
0552       m_x_axis.title_height.value(ASIZ);
0553 
0554       m_y_axis.tick_length.value(YTIC);
0555       m_y_axis.label_to_axis.value(XVAL);
0556       m_y_axis.label_height.value(VSIZ);
0557       m_y_axis.title_to_axis.value(XLAB);
0558       m_y_axis.title_height.value(ASIZ);
0559 
0560       m_cmap_axis.tick_length.value(YTIC);
0561       m_cmap_axis.label_to_axis.value(XVAL);
0562       m_cmap_axis.label_height.value(VSIZ);
0563       m_cmap_axis.title_to_axis.value(XLAB);
0564       m_cmap_axis.title_height.value(ASIZ);
0565 
0566     } else { //xyz
0567       m_x_axis.tick_length.value(XTIC);
0568       m_x_axis.label_to_axis.value(YVAL);
0569       m_x_axis.label_height.value(VSIZ);
0570       m_x_axis.title_to_axis.value(YLAB);
0571       m_x_axis.title_height.value(ASIZ);
0572 
0573       m_y_axis.tick_length.value(XTIC);
0574       m_y_axis.label_to_axis.value(YVAL);
0575       m_y_axis.label_height.value(VSIZ);
0576       m_y_axis.title_to_axis.value(YLAB);
0577       m_y_axis.title_height.value(ASIZ);
0578 
0579       m_z_axis.tick_length.value(YTIC);
0580       m_z_axis.label_to_axis.value(XVAL);
0581       m_z_axis.label_height.value(VSIZ);
0582       m_z_axis.title_to_axis.value(XLAB);
0583       m_z_axis.title_height.value(ASIZ);
0584 
0585       m_cmap_axis.tick_length.value(XTIC);
0586       m_cmap_axis.label_to_axis.value(YVAL);
0587       m_cmap_axis.label_height.value(VSIZ);
0588       m_cmap_axis.title_to_axis.value(YLAB);
0589       m_cmap_axis.title_height.value(ASIZ);
0590 
0591     }
0592 
0593     }
0594 
0595     title_automated = true;
0596     title.value().clear();
0597     title_up = true;
0598     title_hjust = center;
0599 
0600     ////////////////////////////////////////////
0601     colormap_visible = true;
0602     colormap_axis_labeling = cells;
0603     colormap_attached = true;
0604     colormap_axis_visible = true;
0605 
0606     ////////////////////////////////////////////
0607     x_axis_enforced = false;
0608     x_axis_automated = true;
0609     x_axis_min = 0;
0610     x_axis_max = 1;
0611     x_axis_is_log = false;
0612 
0613     y_axis_enforced = false;
0614     y_axis_automated = true;
0615     y_axis_min = 0;
0616     y_axis_max = 1;
0617     y_axis_is_log = false;
0618 
0619     z_axis_enforced = false;
0620     z_axis_automated = true;
0621     z_axis_min = 0;
0622     z_axis_max = 1;
0623     z_axis_is_log = false;
0624 
0625     m_x_axis.reset_style();
0626     m_y_axis.reset_style();
0627     m_z_axis.reset_style();
0628 
0629     ////////////////////////////////////////////
0630     ////////////////////////////////////////////
0631     ////////////////////////////////////////////
0632     number_of_levels = 10;
0633     levels.clear();
0634     data_light_on_automated = true;
0635     primitives_enforced = false;
0636     inner_frame_enforced = false;
0637 
0638     ////////////////////////////////////////////
0639     // setup styles :
0640     ////////////////////////////////////////////
0641 
0642     m_title_style = text_style();
0643     m_infos_style = text_style();
0644     m_title_box_style = text_style();
0645     m_background_style = style();
0646     m_wall_style = style();
0647     m_inner_frame_style = style();
0648     m_grid_style = style();
0649 
0650     m_title_style.color = colorf_black();
0651     m_title_style.font = font_hershey();
0652     m_title_style.font_modeling = font_filled;
0653     m_title_style.encoding = encoding_PAW();
0654 
0655     m_background_style.back_color = colorf_white();
0656     m_background_style.line_width = 0; //no border
0657     m_background_style.color = colorf_black(); //border
0658 
0659     m_inner_frame_style.color = colorf_black();
0660     m_inner_frame_style.line_pattern = line_solid;
0661 
0662     m_grid_style.color = colorf_black();
0663     m_grid_style.line_pattern = line_dashed;
0664 
0665     m_infos_style.font = font_hershey();
0666     m_infos_style.font_modeling = font_filled;
0667     m_infos_style.encoding = encoding_PAW();
0668 
0669     m_title_box_style.visible = false;
0670     m_title_box_style.font = font_hershey();
0671     m_title_box_style.font_modeling = font_filled;
0672     m_title_box_style.encoding = encoding_PAW();
0673 
0674    {tools_vforit(style,m_bins_style,it) {
0675       (*it) = style();
0676       (*it).modeling = modeling_top_lines();
0677       (*it).marker_size = 5; //for bins1D of profile.
0678     }}
0679    {tools_vforit(style,m_errors_style,it) {(*it) = style();(*it).visible = false;}}
0680    {tools_vforit(style,m_func_style,it) (*it) = style();}
0681    {tools_vforit(style,m_points_style,it) {
0682       (*it) = style();
0683       (*it).modeling = modeling_markers(); //for gopaw.
0684     }}
0685    {tools_vforit(style,m_left_hatch_style,it) {(*it) = style();(*it).visible = false;}}
0686    {tools_vforit(style,m_right_hatch_style,it) {(*it) = style();(*it).visible = false;}}
0687    {tools_vforit(style,m_legend_style,it) {(*it) = style();(*it).visible = false;}}
0688 
0689   }
0690 
0691   void gopaw_reset_style() {
0692    {tools_vforit(style,m_bins_style,it) {
0693       (*it) = style();
0694       (*it).modeling = modeling_top_lines();
0695       (*it).marker_size = 5; //for bins1D of profile.
0696     }}
0697 
0698    {tools_vforit(style,m_errors_style,it) {(*it) = style();(*it).visible = false;}}
0699    {tools_vforit(style,m_func_style,it) (*it) = style();}
0700    {tools_vforit(style,m_points_style,it) {
0701       (*it) = style();
0702       (*it).modeling = modeling_markers(); //for gopaw.
0703     }}
0704    {tools_vforit(style,m_left_hatch_style,it) {(*it) = style();(*it).visible = false;}}
0705    {tools_vforit(style,m_right_hatch_style,it) {(*it) = style();(*it).visible = false;}}
0706    {tools_vforit(style,m_legend_style,it) {(*it) = style();(*it).visible = false;}}
0707   }
0708 
0709   typedef std::pair<std::string,std::string> style_item_t;
0710   typedef std::vector<style_item_t> style_t;
0711   bool set_from_style(std::ostream& a_out,const style_t& a_style) {
0712     tools_vforcit(style_item_t,a_style,it) {
0713       const std::string& key = (*it).first;
0714       const std::string& sv = (*it).second;
0715       if(key=="tag") {
0716    
0717       } else if(key=="width") {
0718         float v;
0719         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0720         width = v;
0721       } else if(key=="height") {
0722         float v;
0723         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0724         height = v;
0725       } else if(key=="depth") {
0726         float v;
0727         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0728         depth = v;
0729 
0730       } else if(key=="left_margin") {
0731         float v;
0732         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0733         left_margin = v;
0734       } else if(key=="right_margin") {
0735         float v;
0736         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0737         right_margin = v;
0738       } else if(key=="bottom_margin") {
0739         float v;
0740         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0741         bottom_margin = v;
0742       } else if(key=="top_margin") {
0743         float v;
0744         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0745         top_margin = v;
0746       } else if(key=="down_margin") {
0747         float v;
0748         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0749         down_margin = v;
0750       } else if(key=="up_margin") {
0751         float v;
0752         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0753         up_margin = v;
0754 
0755       } else if(key=="title") {
0756         title = sv;
0757       } else if(key=="title_up") {
0758         bool v;
0759         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0760         title_up = v;
0761       } else if(key=="title_to_axis") {
0762         float v;
0763         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0764         title_to_axis = v;
0765       } else if(key=="title_height") {
0766         float v;
0767         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0768         title_height = v;
0769       } else if(key=="title_automated") {
0770         bool v;
0771         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0772         title_automated = v;
0773       } else if(key=="title_hjust") {
0774         hjust v;
0775         if(!shjust(sv,v))
0776           {style_failed(a_out,key,sv);return false;}
0777         title_hjust = v;
0778 
0779       } else if(key=="x_axis_enforced") {
0780         bool v;
0781         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0782         x_axis_enforced = v;
0783       } else if(key=="x_axis_automated") {
0784         bool v;
0785         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0786         x_axis_automated = v;
0787       } else if(key=="x_axis_min") {
0788         float v;
0789         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0790         x_axis_min = v;
0791       } else if(key=="x_axis_max") {
0792         float v;
0793         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0794         x_axis_max = v;
0795       } else if(key=="x_axis_is_log") {
0796         bool v;
0797         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0798         x_axis_is_log = v;
0799 
0800       } else if(key=="y_axis_enforced") {
0801         bool v;
0802         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0803         y_axis_enforced = v;
0804       } else if(key=="y_axis_automated") {
0805         bool v;
0806         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0807         y_axis_automated = v;
0808       } else if(key=="y_axis_min") {
0809         float v;
0810         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0811         y_axis_min = v;
0812       } else if(key=="y_axis_max") {
0813         float v;
0814         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0815         y_axis_max = v;
0816       } else if(key=="y_axis_is_log") {
0817         bool v;
0818         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0819         y_axis_is_log = v;
0820 
0821       } else if(key=="z_axis_enforced") {
0822         bool v;
0823         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0824         z_axis_enforced = v;
0825       } else if(key=="z_axis_automated") {
0826         bool v;
0827         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0828         z_axis_automated = v;
0829       } else if(key=="z_axis_min") {
0830         float v;
0831         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0832         z_axis_min = v;
0833       } else if(key=="z_axis_max") {
0834         float v;
0835         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0836         z_axis_max = v;
0837       } else if(key=="z_axis_is_log") {
0838         bool v;
0839         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0840         z_axis_is_log = v;
0841 
0842       } else if(key=="value_top_margin") {
0843         float v;
0844         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0845         value_top_margin = v;
0846       } else if(key=="value_bottom_margin") {
0847         float v;
0848         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0849         value_bottom_margin = v;
0850       } else if(key=="value_bins_with_entries") {
0851         float v;
0852         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0853         value_bins_with_entries = v;
0854       } else if(key=="infos_width") {
0855         float v;
0856         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0857         infos_width = v;
0858       } else if(key=="infos_x_margin") {
0859         float v;
0860         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0861         infos_x_margin = v;
0862       } else if(key=="infos_y_margin") {
0863         float v;
0864         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0865         infos_y_margin = v;
0866 
0867       } else if(key=="title_box_width") {
0868         float v;
0869         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0870         title_box_width = v;
0871       } else if(key=="title_box_height") {
0872         float v;
0873         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0874         title_box_height = v;
0875       } else if(key=="title_box_x_margin") {
0876         float v;
0877         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0878         title_box_x_margin = v;
0879       } else if(key=="title_box_y_margin") {
0880         float v;
0881         if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;}
0882         title_box_y_margin = v;
0883 
0884       } else if(key=="infos_what") {
0885         infos_what = sv;
0886       } else if(key=="legends_automated") {
0887         bool v;
0888         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0889         legends_automated = v;
0890       } else if(key=="legends_origin") {
0891         vec2f v;
0892         if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;}
0893         legends_origin.setValue(v);
0894       } else if(key=="legends_size") {
0895         vec2f v;
0896         if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;}
0897         legends_size.setValue(v);
0898       } else if(key=="legends_origin_unit") {
0899         unit_type v;
0900         if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;}
0901         legends_origin_unit.setValue(v);
0902 
0903       } else if(key=="shape_automated") {
0904         bool v;
0905         if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
0906         shape_automated = v;
0907 
0908       } else if(key=="shape") {
0909         if(sv=="xy") {
0910           shape = xy;
0911         } else if(sv=="xyz") {
0912           shape = xyz;
0913         } else {
0914           style_failed(a_out,key,sv);return false;
0915         }
0916 
0917       } else {
0918         a_out << "tools::sg::plotter::set_from_style : unknown key " << key << "." << std::endl;
0919       }
0920     }
0921     return true;
0922   }
0923 
0924 protected:
0925   bool s2axis(const std::string& a_s,sg::axis*& a_axis) {
0926          if(a_s=="x_axis")        {a_axis = &(x_axis());return true;}
0927     else if(a_s=="y_axis")        {a_axis = &(y_axis());return true;}
0928     else if(a_s=="z_axis")        {a_axis = &(z_axis());return true;}
0929     else if(a_s=="colormap_axis") {a_axis = &(colormap_axis());return true;}
0930     else {
0931       a_axis = 0;
0932       return false;
0933     }
0934   }
0935 public:
0936   bool set_from_string(std::ostream& a_out,cmaps_t& a_cmaps,const std::string& a_field,const std::string& a_value) {
0937     // see also plotter_style file.
0938     std::string::size_type pos = a_field.find('.');
0939     bool status = true;
0940     if(pos==std::string::npos) {
0941       style_t _style;
0942       _style.push_back(style_item_t(a_field,a_value));
0943       if(!set_from_style(a_out,_style)) status = false;
0944     } else {
0945       std::vector<std::string> _words;
0946       words(a_field,".",false,_words);
0947       if(_words.size()==2) {
0948         const std::string& word0 = _words[0];
0949         const std::string& word1 = _words[1];
0950         std::string _s = word1+" "+std::string(a_value);
0951         sg::axis* _axis = 0;
0952              if(word0=="background_style")  {if(!background_style().from_string(a_out,a_cmaps,_s)) status = false;}
0953         else if(word0=="title_style")       {if(!title_style().from_string(a_out,a_cmaps,_s)) status = false;}
0954         else if(word0=="infos_style")       {if(!infos_style().from_string(a_out,a_cmaps,_s)) status = false;}
0955         else if(word0=="title_box_style")   {if(!title_box_style().from_string(a_out,a_cmaps,_s)) status = false;}
0956         else if(word0=="inner_frame_style") {if(!inner_frame_style().from_string(a_out,a_cmaps,_s)) status = false;}
0957         else if(word0=="grid_style")        {if(!grid_style().from_string(a_out,a_cmaps,_s)) status = false;}
0958         else if(word0=="wall_style")        {if(!wall_style().from_string(a_out,a_cmaps,_s)) status = false;}
0959         else if(!s2axis(word0,_axis)) {
0960           a_out << "tools::sg::plotter::set_from_string : unexpected axis field " << word0 << "." << std::endl;
0961           status = false;
0962         } else {
0963           style_t _style;
0964           _style.push_back(style_item_t(word1,a_value));
0965           if(!_axis->set_from_style(a_out,_style)) status = false;
0966         }
0967       } else if(_words.size()==3) {
0968         const std::string& word0 = _words[0];
0969         const std::string& word1 = _words[1];
0970         const std::string& word2 = _words[2];
0971         sg::axis* _axis = 0;
0972         std::string _s = word2+" "+std::string(a_value);
0973         unsigned int index;
0974         bool to_status = to<unsigned int>(word1,index);
0975         if(word0=="bins_style") {
0976           if(!to_status) {
0977             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
0978             status = false;
0979           } else {
0980             if(!bins_style(index).from_string(a_out,a_cmaps,_s)) status = false;
0981           }
0982         } else if(word0=="errors_style") {
0983           if(!to_status) {
0984             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
0985             status = false;
0986           } else {
0987             if(!errors_style(index).from_string(a_out,a_cmaps,_s)) status = false;
0988           }
0989         } else if(word0=="func_style") {
0990           if(!to_status) {
0991             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
0992             status = false;
0993           } else {
0994             if(!func_style(index).from_string(a_out,a_cmaps,_s)) status = false;
0995           }
0996         } else if(word0=="points_style") {
0997           if(!to_status) {
0998             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
0999             status = false;
1000           } else {
1001             if(!points_style(index).from_string(a_out,a_cmaps,_s)) status = false;
1002           }
1003         } else if(word0=="left_hatch_style") {
1004           if(!to_status) {
1005             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
1006             status = false;
1007           } else {
1008             if(!left_hatch_style(index).from_string(a_out,a_cmaps,_s)) status = false;
1009           }
1010         } else if(word0=="right_hatch_style") {
1011           if(!to_status) {
1012             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
1013             status = false;
1014           } else {
1015             if(!right_hatch_style(index).from_string(a_out,a_cmaps,_s)) status = false;
1016           }
1017         } else if(word0=="legend_style") {
1018           if(!to_status) {
1019             a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl;
1020             status = false;
1021           } else {
1022             if(!legend_style(index).from_string(a_out,a_cmaps,_s)) status = false;
1023           }
1024         } else if(!s2axis(word0,_axis)) {
1025           a_out << "tools::sg::plotter::set_from_string : unexpected axis field " << word0 << "." << std::endl;
1026           status = false;
1027         } else {
1028                if(word1=="line_style")   {if(!_axis->line_style().from_string(a_out,a_cmaps,_s)) status = false;}
1029           else if(word1=="ticks_style")  {if(!_axis->ticks_style().from_string(a_out,a_cmaps,_s)) status = false;}
1030           else if(word1=="labels_style") {if(!_axis->labels_style().from_string(a_out,a_cmaps,_s)) status = false;}
1031           else if(word1=="mag_style")    {if(!_axis->mag_style().from_string(a_out,a_cmaps,_s)) status = false;}
1032           else if(word1=="title_style")  {if(!_axis->title_style().from_string(a_out,a_cmaps,_s)) status = false;}
1033           else {
1034             a_out << "tools::sg::plotter::set_from_string : unexpected style field " << word1 << "." << std::endl;
1035             status = false;
1036           }
1037         }
1038       } else {
1039         a_out << "tools::sg::plotter::set_from_string : unexpected number of fields " << _words.size() << "." << std::endl;
1040         status = false;
1041       }
1042     }
1043     return status;
1044   }
1045 
1046   void set_encoding(const std::string& a_value) {
1047     title_style().encoding = a_value;
1048     infos_style().encoding = a_value;
1049     title_box_style().encoding = a_value;
1050     m_x_axis.set_encoding(a_value);
1051     m_y_axis.set_encoding(a_value);
1052     m_z_axis.set_encoding(a_value);
1053     m_cmap_axis.set_encoding(a_value);
1054   }
1055   void set_encoding_none() {set_encoding(encoding_none());}
1056 
1057   void print_available_customization(std::ostream& a_out) const {
1058     a_out << "plotter fields :" << std::endl;
1059    {const std::vector<field_desc>& fds = node_desc_fields();
1060     tools_vforcit(field_desc,fds,itd) {
1061       a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl;
1062     }}
1063     a_out << std::endl;
1064 
1065     a_out << "plotter data available styles :" << std::endl;
1066     a_out << " bins_style.<uint>, class style" << std::endl;
1067     a_out << " errors_style.<uint>, class style" << std::endl;
1068     a_out << " func_style.<uint>, class style" << std::endl;
1069     a_out << " points_style.<uint>, class style" << std::endl;
1070     a_out << " left_hatch_style.<uint>, class style" << std::endl;
1071     a_out << " right_hatch_style.<uint>, class style" << std::endl;
1072     a_out << " legend_style.<uint>, class style" << std::endl;
1073     a_out << std::endl;
1074 
1075     a_out << "plotter available styles :" << std::endl;
1076     a_out << " title_style, class text_style" << std::endl;
1077     a_out << " infos_style, class text_style" << std::endl;
1078     a_out << " title_box_style, class text_style" << std::endl;
1079     a_out << " background_style, class style" << std::endl;
1080     a_out << " inner_frame_style, class style" << std::endl;
1081     a_out << " grid_style, class style" << std::endl;
1082     a_out << " wall_style, class style" << std::endl;
1083     a_out << std::endl;
1084 
1085     a_out << "plotter available axes :" << std::endl;
1086     a_out << " x_axis" << std::endl;
1087     a_out << " y_axis" << std::endl;
1088     a_out << " z_axis" << std::endl;
1089     a_out << " colormap_axis" << std::endl;
1090     a_out << std::endl;
1091 
1092     a_out << "plotter axis available styles :" << std::endl;
1093     a_out << " title_style, class text_style" << std::endl;
1094     a_out << " labels_style, class text_style" << std::endl;
1095     a_out << " mag_style, class text_style" << std::endl;
1096     a_out << " line_style, class line_style" << std::endl;
1097     a_out << " ticks_style, class line_style" << std::endl;
1098     a_out << std::endl;
1099 
1100     a_out << "plotter style class fields :" << std::endl;
1101    {style _style;
1102     const std::vector<field_desc>& fds = _style.node_desc_fields();
1103     tools_vforcit(field_desc,fds,itd) {
1104       a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl;
1105     }}
1106     a_out << std::endl;
1107 
1108     a_out << "plotter text_style class fields :" << std::endl;
1109    {text_style _style;
1110     const std::vector<field_desc>& fds = _style.node_desc_fields();
1111     tools_vforcit(field_desc,fds,itd) {
1112       a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl;
1113     }}
1114     a_out << std::endl;
1115 
1116     a_out << "plotter line_style class fields :" << std::endl;
1117    {line_style _style;
1118     const std::vector<field_desc>& fds = _style.node_desc_fields();
1119     tools_vforcit(field_desc,fds,itd) {
1120       a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl;
1121     }}
1122     a_out << std::endl;
1123   }
1124 protected:
1125   void style_failed(std::ostream& a_out,const std::string& a_key,const std::string& a_value) {
1126     a_out << "tools::sg::plotter::set_from_style :"
1127           << " failed for key " << sout(a_key)
1128           << " and value " << sout(a_value) << "."
1129           << std::endl;
1130   }
1131 public:
1132   virtual void render(render_action& a_action) {
1133     if(touched()) {
1134       update_sg(a_action.out());
1135       reset_touched();
1136     }
1137     m_group.render(a_action);
1138   }
1139   virtual void pick(pick_action& a_action) {
1140     if(touched()) {
1141       update_sg(a_action.out());
1142       reset_touched();
1143     }
1144     nodekit_pick(a_action,m_group,this);
1145   }
1146   virtual void search(search_action& a_action) {
1147     if(touched()) {
1148       update_sg(a_action.out());
1149       reset_touched();
1150     }
1151     node::search(a_action);
1152     if(a_action.done()) return;
1153     m_group.search(a_action);
1154   }
1155   virtual void bbox(bbox_action& a_action) {
1156     if(touched()) {
1157       update_sg(a_action.out());
1158       reset_touched();
1159     }
1160     m_group.bbox(a_action);
1161   }
1162 
1163   virtual bool write(write_action& a_action) {
1164     if(touched()) {
1165       update_sg(a_action.out());
1166       reset_touched();
1167     }
1168     return m_group.write(a_action);
1169   }
1170 public:
1171   plotter(const base_freetype& a_ttf)
1172   :parent()
1173   ,width(0)
1174   ,height(0)
1175   ,left_margin(0)
1176   ,right_margin(0)
1177   ,bottom_margin(0)
1178   ,top_margin(0)
1179   ,depth(0)
1180   ,down_margin(0)
1181   ,up_margin(0)
1182 
1183   ,title_up(true)
1184   ,title_to_axis(0) //set below.
1185   ,title_height(0)  //set below.
1186   ,title_automated(true)
1187   ,title_hjust(center)
1188   ,title("")
1189 
1190   ,colormap_visible(true)
1191   ,colormap_axis_labeling(cells)
1192   ,colormap_attached(true)
1193   ,colormap_axis_visible(true)
1194 
1195   ,x_axis_enforced(false)
1196   ,x_axis_automated(true)
1197   ,x_axis_min(0)
1198   ,x_axis_max(1)
1199   ,x_axis_is_log(false)
1200   ,y_axis_enforced(false)
1201   ,y_axis_automated(true)
1202   ,y_axis_min(0)
1203   ,y_axis_max(1)
1204   ,y_axis_is_log(false)
1205   ,z_axis_enforced(false)
1206   ,z_axis_automated(true)
1207   ,z_axis_min(0)
1208   ,z_axis_max(1)
1209   ,z_axis_is_log(false)
1210 
1211   ,value_top_margin(0.1f) //percent. // CERN-PAW seems to have 0.1F and CERN-ROOT 0.05F.
1212   ,value_bottom_margin(0.0f) //percent.
1213   ,value_bins_with_entries(true)
1214 
1215   ,infos_width(0.3f) //percent of width
1216   ,infos_x_margin(default_infos_margin()) //percent of width
1217   ,infos_y_margin(default_infos_margin()) //percent of height
1218   ,infos_what(s_infos_what_def())
1219 
1220   ,title_box_width(default_title_box_width())       //percent of width
1221   ,title_box_height(default_title_box_height())     //percent of height
1222   ,title_box_x_margin(default_title_box_x_margin()) //percent of width
1223   ,title_box_y_margin(default_title_box_y_margin()) //percent of height
1224 
1225   ,func2D_borders_visible(true)
1226   ,theta(30)
1227   ,phi(30)
1228   ,tau(-90)
1229 
1230   ,legends_automated(true)
1231 
1232   ,shape_automated(true)
1233   ,shape(xy)
1234 
1235   ,xy_depth(0.01f)
1236   ,curve_number_of_points(100)
1237   ,data_light_on_automated(true)
1238   ,primitives_enforced(false)
1239   ,inner_frame_enforced(false)
1240   ,number_of_levels(10)
1241   ,levels()
1242 
1243   ,m_ttf(a_ttf)
1244 
1245   ,m_cmap_axis(a_ttf)
1246   ,m_x_axis(a_ttf)
1247   ,m_y_axis(a_ttf)
1248   ,m_z_axis(a_ttf)
1249 
1250   ,m_shape(xy)
1251   {
1252     m_cmaps[style_default_colormap::s_default()] = style_default_colormap(); //costly
1253 
1254     add_fields();
1255     reset_style(true);
1256 
1257     init_sg(); // skeleton of scene graph.
1258   }
1259   virtual ~plotter(){
1260     clear_plottables();
1261     clear_primitives();
1262     clear_cmaps();
1263   }
1264 public:
1265   plotter(const plotter& a_from)
1266   :parent(a_from)
1267   ,width(a_from.width)
1268   ,height(a_from.height)
1269   ,left_margin(a_from.left_margin)
1270   ,right_margin(a_from.right_margin)
1271   ,bottom_margin(a_from.bottom_margin)
1272   ,top_margin(a_from.top_margin)
1273   ,depth(a_from.depth)
1274   ,down_margin(a_from.down_margin)
1275   ,up_margin(a_from.up_margin)
1276 
1277   ,title_up(a_from.title_up)
1278   ,title_to_axis(a_from.title_to_axis)
1279   ,title_height(a_from.title_height)
1280   ,title_automated(a_from.title_automated)
1281   ,title_hjust(a_from.title_hjust)
1282   ,title(a_from.title)
1283 
1284   ,colormap_visible(a_from.colormap_visible)
1285   ,colormap_axis_labeling(a_from.colormap_axis_labeling)
1286   ,colormap_attached(a_from.colormap_attached)
1287   ,colormap_axis_visible(a_from.colormap_axis_visible)
1288 
1289   ,x_axis_enforced(a_from.x_axis_enforced)
1290   ,x_axis_automated(a_from.x_axis_automated)
1291   ,x_axis_min(a_from.x_axis_min)
1292   ,x_axis_max(a_from.x_axis_max)
1293   ,x_axis_is_log(a_from.x_axis_is_log)
1294   ,y_axis_enforced(a_from.y_axis_enforced)
1295   ,y_axis_automated(a_from.y_axis_automated)
1296   ,y_axis_min(a_from.y_axis_min)
1297   ,y_axis_max(a_from.y_axis_max)
1298   ,y_axis_is_log(a_from.y_axis_is_log)
1299   ,z_axis_enforced(a_from.z_axis_enforced)
1300   ,z_axis_automated(a_from.z_axis_automated)
1301   ,z_axis_min(a_from.z_axis_min)
1302   ,z_axis_max(a_from.z_axis_max)
1303   ,z_axis_is_log(a_from.z_axis_is_log)
1304   ,value_top_margin(a_from.value_top_margin)
1305   ,value_bottom_margin(a_from.value_bottom_margin)
1306   ,value_bins_with_entries(a_from.value_bins_with_entries)
1307 
1308   ,infos_width(a_from.infos_width)
1309   ,infos_x_margin(a_from.infos_x_margin)
1310   ,infos_y_margin(a_from.infos_y_margin)
1311   ,infos_what(a_from.infos_what)
1312 
1313   ,title_box_width(a_from.title_box_width)
1314   ,title_box_height(a_from.title_box_height)
1315   ,title_box_x_margin(a_from.title_box_x_margin)
1316   ,title_box_y_margin(a_from.title_box_y_margin)
1317 
1318   ,func2D_borders_visible(a_from.func2D_borders_visible)
1319   ,theta(a_from.theta)
1320   ,phi(a_from.phi)
1321   ,tau(a_from.tau)
1322 
1323   ,legends_automated(a_from.legends_automated)
1324   ,legends_origin(a_from.legends_origin)
1325   ,legends_origin_unit(a_from.legends_origin_unit)
1326   ,legends_size(a_from.legends_size)
1327   ,legends_string(a_from.legends_string)
1328 
1329   ,shape_automated(a_from.shape_automated)
1330   ,shape(a_from.shape)
1331 
1332   ,xy_depth(a_from.xy_depth)
1333   ,curve_number_of_points(a_from.curve_number_of_points)
1334   ,data_light_on_automated(a_from.data_light_on_automated)
1335   ,primitives_enforced(a_from.primitives_enforced)
1336   ,inner_frame_enforced(a_from.inner_frame_enforced)
1337   ,number_of_levels(a_from.number_of_levels)
1338   ,levels(a_from.levels)
1339 
1340   ,m_ttf(a_from.m_ttf)
1341 
1342   ,m_background_sep()
1343 
1344   ,m_cmap_axis(m_ttf)
1345   ,m_x_axis(m_ttf)
1346   ,m_y_axis(m_ttf)
1347   ,m_z_axis(m_ttf)
1348 
1349   ,m_etc_sep(a_from.m_etc_sep)
1350 
1351   ,m_shape(a_from.m_shape)
1352 
1353   ,m_bins_style(a_from.m_bins_style)
1354   ,m_errors_style(a_from.m_errors_style)
1355   ,m_func_style(a_from.m_func_style)
1356   ,m_points_style(a_from.m_points_style)
1357   ,m_left_hatch_style(a_from.m_left_hatch_style)
1358   ,m_right_hatch_style(a_from.m_right_hatch_style)
1359   ,m_legend_style(a_from.m_legend_style)
1360 
1361   ,m_title_style(a_from.m_title_style)
1362   ,m_infos_style(a_from.m_infos_style)
1363   ,m_title_box_style(a_from.m_title_box_style)
1364   ,m_background_style(a_from.m_background_style)
1365   ,m_wall_style(a_from.m_wall_style)
1366   ,m_inner_frame_style(a_from.m_inner_frame_style)
1367   ,m_grid_style(a_from.m_grid_style)
1368   ,m_cmaps(a_from.m_cmaps)
1369   {
1370     add_fields();
1371 
1372     // to copy axes styles :
1373     m_x_axis = a_from.m_x_axis;
1374     m_y_axis = a_from.m_y_axis;
1375     m_z_axis = a_from.m_z_axis;
1376     m_cmap_axis = a_from.m_cmap_axis;
1377 
1378     init_sg(); // skeleton of scene graph.
1379 
1380    {tools_vforcit(plottable*,a_from.m_plottables,it) {m_plottables.push_back((*it)->copy());}}
1381    {tools_vforcit(plotprim*,a_from.m_primitives,it) {m_primitives.push_back((*it)->copy());}}
1382   }
1383   plotter& operator=(const plotter& a_from){
1384     parent::operator=(a_from);
1385     if(&a_from==this) return *this;
1386 
1387     width = a_from.width;
1388     height = a_from.height;
1389     left_margin = a_from.left_margin;
1390     right_margin = a_from.right_margin;
1391     bottom_margin = a_from.bottom_margin;
1392     top_margin = a_from.top_margin;
1393     depth = a_from.depth;
1394     down_margin = a_from.down_margin;
1395     up_margin = a_from.up_margin;
1396 
1397     title_up = a_from.title_up;
1398     title_to_axis = a_from.title_to_axis;
1399     title_height = a_from.title_height;
1400     title_automated = a_from.title_automated;
1401     title_hjust = a_from.title_hjust;
1402     title = a_from.title;
1403 
1404     colormap_visible = a_from.colormap_visible;
1405     colormap_axis_labeling = a_from.colormap_axis_labeling;
1406     colormap_attached = a_from.colormap_attached;
1407     colormap_axis_visible = a_from.colormap_axis_visible;
1408 
1409     x_axis_enforced = a_from.x_axis_enforced;
1410     x_axis_automated = a_from.x_axis_automated;
1411     x_axis_min = a_from.x_axis_min;
1412     x_axis_max = a_from.x_axis_max;
1413     x_axis_is_log = a_from.x_axis_is_log;
1414     y_axis_enforced = a_from.y_axis_enforced;
1415     y_axis_automated = a_from.y_axis_automated;
1416     y_axis_min = a_from.y_axis_min;
1417     y_axis_max = a_from.y_axis_max;
1418     y_axis_is_log = a_from.y_axis_is_log;
1419     z_axis_enforced = a_from.z_axis_enforced;
1420     z_axis_automated = a_from.z_axis_automated;
1421     z_axis_min = a_from.z_axis_min;
1422     z_axis_max = a_from.z_axis_max;
1423     z_axis_is_log = a_from.z_axis_is_log;
1424     value_top_margin = a_from.value_top_margin;
1425     value_bottom_margin = a_from.value_bottom_margin;
1426     value_bins_with_entries = a_from.value_bins_with_entries;
1427 
1428     infos_width = a_from.infos_width;
1429     infos_x_margin = a_from.infos_x_margin;
1430     infos_y_margin = a_from.infos_y_margin;
1431     infos_what = a_from.infos_what;
1432 
1433     title_box_width = a_from.title_box_width;
1434     title_box_height = a_from.title_box_height;
1435     title_box_x_margin = a_from.title_box_x_margin;
1436     title_box_y_margin = a_from.title_box_y_margin;
1437 
1438     func2D_borders_visible = a_from.func2D_borders_visible;
1439     theta = a_from.theta;
1440     phi = a_from.phi;
1441     tau = a_from.tau;
1442 
1443     legends_automated = a_from.legends_automated;
1444     legends_origin = a_from.legends_origin;
1445     legends_origin_unit = a_from.legends_origin_unit;
1446     legends_size = a_from.legends_size;
1447     legends_string = a_from.legends_string;
1448 
1449     shape_automated = a_from.shape_automated;
1450     shape = a_from.shape;
1451 
1452     xy_depth = a_from.xy_depth;
1453     curve_number_of_points = a_from.curve_number_of_points;
1454     number_of_levels = a_from.number_of_levels;
1455     levels = a_from.levels;
1456     data_light_on_automated = a_from.data_light_on_automated;
1457     primitives_enforced = a_from.primitives_enforced;
1458     inner_frame_enforced = a_from.inner_frame_enforced;
1459 
1460     m_etc_sep = a_from.m_etc_sep;
1461 
1462     m_bins_style = a_from.m_bins_style;
1463     m_errors_style = a_from.m_errors_style;
1464     m_func_style = a_from.m_func_style;
1465     m_points_style = a_from.m_points_style;
1466     m_left_hatch_style = a_from.m_left_hatch_style;
1467     m_right_hatch_style = a_from.m_right_hatch_style;
1468     m_legend_style = a_from.m_legend_style;
1469 
1470     m_title_style = a_from.m_title_style;
1471     m_infos_style = a_from.m_infos_style;
1472     m_title_box_style = a_from.m_title_box_style;
1473     m_background_style = a_from.m_background_style;
1474     m_wall_style = a_from.m_wall_style;
1475     m_inner_frame_style = a_from.m_inner_frame_style;
1476     m_grid_style = a_from.m_grid_style;
1477 
1478     // to copy axes styles :
1479     m_x_axis = a_from.m_x_axis;
1480     m_y_axis = a_from.m_y_axis;
1481     m_z_axis = a_from.m_z_axis;
1482     m_cmap_axis = a_from.m_cmap_axis;
1483 
1484     m_cmaps = a_from.m_cmaps;
1485 
1486     clear_plottables();
1487     clear_primitives();
1488     clear_todels();
1489 
1490    {tools_vforcit(plottable*,a_from.m_plottables,it) {m_plottables.push_back((*it)->copy());}}
1491    {tools_vforcit(plotprim*,a_from.m_primitives,it) {m_primitives.push_back((*it)->copy());}}
1492 
1493     return *this;
1494   }
1495 public:
1496   size_t number_of_plottables() const {
1497     size_t number = 0;
1498     tools_vforcit(plottable*,m_plottables,it) {
1499       plottable* object = *it;
1500       if(!object) continue;
1501       if(!object->is_valid()) continue;
1502       // take into account all valid plottables, even the one without a representation.
1503       number++;
1504     }
1505     return number;
1506   }
1507 
1508 #define TOOLS_SG_PLOTTER_NUMBER_OF(a__what) \
1509   size_t number_of_plotted_##a__what##s() const {\
1510     size_t number = 0;\
1511     tools_vforcit(plottable*,m_plottables,it) {\
1512       plottable* object = *it;\
1513       if(!object) continue;\
1514       if(!object->is_valid()) continue;\
1515       if(safe_cast<plottable,a__what>(*object)) number++;\
1516     }\
1517     return number;\
1518   }
1519 
1520   TOOLS_SG_PLOTTER_NUMBER_OF(bins1D)
1521   TOOLS_SG_PLOTTER_NUMBER_OF(bins2D)
1522   TOOLS_SG_PLOTTER_NUMBER_OF(points2D)
1523   TOOLS_SG_PLOTTER_NUMBER_OF(points3D)
1524   TOOLS_SG_PLOTTER_NUMBER_OF(func1D)
1525   TOOLS_SG_PLOTTER_NUMBER_OF(func2D)
1526 
1527 #undef TOOLS_SG_PLOTTER_NUMBER_OF
1528 
1529   void plotted_object_names(std::vector<std::string>& a_names) const {
1530     a_names.clear();
1531     tools_vforcit(plottable*,m_plottables,it) {
1532       plottable* object = *it;
1533       if(!object) continue;
1534       if(!object->is_valid()) continue;
1535       // take into account all valid plottables, even the one without a representation.
1536       a_names.push_back(object->name());
1537     }
1538   }
1539 
1540 public: //public
1541   const torche& data_light() const {return m_data_light;}
1542   torche& data_light() {return m_data_light;}
1543 
1544   matrix& tsf() {return m_tsf;}
1545 
1546   const separator& etc_sep() const {return m_etc_sep;}
1547   separator& etc_sep() {return m_etc_sep;}
1548 
1549   const std::vector<plottable*>& plottables() const {return m_plottables;}
1550 
1551   void add_plottable(plottable* a_p) {
1552     //WARNING : it takes ownership of a_p object.
1553     m_plottables.push_back(a_p);
1554     touch();
1555   }
1556 
1557   void prep_plottable(plottable* a_p) {
1558     //WARNING : it takes ownership of a_p object.
1559     m_plottables.insert(m_plottables.begin(),a_p);
1560     touch();
1561   }
1562 
1563   void transfer_plottables(std::vector<plottable*>& a_to) {
1564     a_to = m_plottables;
1565     m_plottables.clear(); //do not delete plottables !
1566     touch();
1567   }
1568 
1569   template <class T>
1570   bool remove_plottables() {
1571     bool found = false;
1572     std::vector<plottable*>::iterator it;
1573     for(it=m_plottables.begin();it!=m_plottables.end();) {
1574       plottable* object = *it;
1575       if(object && safe_cast<plottable,T>(*object)) {
1576         it = m_plottables.erase(it);
1577         delete object;
1578         found = true;
1579       } else {
1580         it++;
1581       }
1582     }
1583     if(found) touch();
1584     return found;
1585   }
1586 
1587   void add_primitive(plotprim* a_prim) {m_primitives.push_back(a_prim);touch();}
1588 
1589   void transfer_primitives(std::vector<plotprim*>& a_to) {
1590     a_to = m_primitives;
1591     m_primitives.clear(); //do not delete primitives !
1592     touch();
1593   }
1594 
1595   template <class T>
1596   void add_todel(T* a_obj) {
1597     m_todel_group.add(new sg::holder<T>(a_obj));
1598   }
1599   template <class T>
1600   void remove_todels(){
1601     remove_holders<T>(m_todel_group.children());
1602   }
1603   void transfer_todels(std::vector<node*>& a_to) { //used in sg::plots.
1604     m_todel_group.transfer(a_to);
1605   }
1606   void add_node_todel(node* a_node) { //used in sg::plots.
1607     m_todel_group.add(a_node);
1608   }
1609 
1610   void clear() {
1611     clear_plottables();
1612     clear_primitives();
1613     clear_todels();
1614 
1615     legends_string.clear();
1616     legends_origin_unit.clear();
1617     legends_origin.clear();
1618     legends_size.clear();
1619 
1620     primitives_enforced = false;
1621     inner_frame_enforced = false;
1622   }
1623 
1624   const sg::axis& x_axis() const {return m_x_axis;}
1625   sg::axis& x_axis() {return m_x_axis;}
1626 
1627   const sg::axis& y_axis() const {return m_y_axis;}
1628   sg::axis& y_axis() {return m_y_axis;}
1629 
1630   const sg::axis& z_axis() const {return m_z_axis;}
1631   sg::axis& z_axis() {return m_z_axis;}
1632 
1633   const sg::axis& colormap_axis() const {return m_cmap_axis;}
1634   sg::axis& colormap_axis() {return m_cmap_axis;}
1635 
1636   text_style& title_style() {return m_title_style;}
1637   style& background_style() {return m_background_style;}
1638   style& wall_style() {return m_wall_style;}
1639   style& inner_frame_style() {return m_inner_frame_style;}
1640   style& grid_style() {return m_grid_style;}
1641   text_style& infos_style() {return m_infos_style;}
1642   text_style& title_box_style() {return m_title_box_style;}
1643 
1644   style& bins_style(size_t a_index) {
1645     size_t sz = m_bins_style.size();
1646     if(a_index>=sz) {
1647       //012345 sz=6
1648       //         9 a_index wanted
1649       //      6789 loop
1650       for(size_t index=sz;index<=a_index;index++) {
1651         m_bins_style.push_back(style());
1652         m_bins_style.back().modeling = modeling_top_lines();
1653         m_bins_style.back().marker_size = 5; //for bins1D of profile.
1654       }
1655     }
1656     return m_bins_style[a_index];
1657   }
1658 
1659   style& errors_style(size_t a_index) {
1660     size_t sz = m_errors_style.size();
1661     if(a_index>=sz) {
1662       for(size_t index=sz;index<=a_index;index++) {
1663         m_errors_style.push_back(style());
1664         m_errors_style.back().visible = false;
1665       }
1666     }
1667     return m_errors_style[a_index];
1668   }
1669 
1670   style& func_style(size_t a_index) {
1671     size_t sz = m_func_style.size();
1672     if(a_index>=sz) {
1673       for(size_t index=sz;index<=a_index;index++) {
1674         m_func_style.push_back(style());
1675       }
1676     }
1677     return m_func_style[a_index];
1678   }
1679 
1680   style& points_style(size_t a_index) {
1681     size_t sz = m_points_style.size();
1682     if(a_index>=sz) {
1683       //012345 sz=6
1684       //         9 a_index wanted
1685       //      6789 loop
1686       for(size_t index=sz;index<=a_index;index++) {
1687         m_points_style.push_back(style());
1688         m_points_style.back().modeling = modeling_markers(); //for gopaw.
1689       }
1690     }
1691     return m_points_style[a_index];
1692   }
1693 
1694   style& left_hatch_style(size_t a_index) {
1695     size_t sz = m_left_hatch_style.size();
1696     if(a_index>=sz) {
1697       for(size_t index=sz;index<=a_index;index++) {
1698         m_left_hatch_style.push_back(style());
1699         m_left_hatch_style.back().visible = false;
1700       }
1701     }
1702     return m_left_hatch_style[a_index];
1703   }
1704 
1705   style& right_hatch_style(size_t a_index) {
1706     size_t sz = m_right_hatch_style.size();
1707     if(a_index>=sz) {
1708       for(size_t index=sz;index<=a_index;index++) {
1709         m_right_hatch_style.push_back(style());
1710         m_right_hatch_style.back().visible = false;
1711       }
1712     }
1713     return m_right_hatch_style[a_index];
1714   }
1715 
1716   style& legend_style(size_t a_index) {
1717     size_t sz = m_legend_style.size();
1718     if(a_index>=sz) {
1719       for(size_t index=sz;index<=a_index;index++) {
1720         m_legend_style.push_back(style());
1721       }
1722     }
1723     return m_legend_style[a_index];
1724   }
1725 
1726   void bins_modelings(size_t a_index,std::vector<std::string>& a_opts) {
1727     a_opts.clear();
1728     update_shape();
1729     if(m_shape==xy) {
1730       size_t ibins = 0;
1731       tools_vforcit(plottable*,m_plottables,it) {
1732         plottable* object = *it;
1733         if(!object) continue;
1734         if(bins1D* b1 = safe_cast<plottable,bins1D>(*object)) {
1735           //update_bins1D_xy
1736           if(a_index==ibins) {
1737             if(b1->is_profile()) {
1738               a_opts.push_back(modeling_points());
1739               a_opts.push_back(modeling_markers());
1740               return;
1741             } else {
1742               a_opts.push_back(modeling_boxes());
1743               a_opts.push_back(modeling_wire_boxes());
1744               a_opts.push_back(modeling_bar_chart());
1745               a_opts.push_back(modeling_top_lines());
1746               a_opts.push_back(modeling_points());
1747               a_opts.push_back(modeling_markers());
1748               return;
1749             }
1750           }
1751           ibins++;
1752         } if(safe_cast<plottable,bins2D>(*object)) {
1753           //update_bins2D_xy
1754           if(a_index==ibins) {
1755             a_opts.push_back(modeling_curve());
1756             a_opts.push_back(modeling_filled_curve());
1757             a_opts.push_back(modeling_boxes());
1758             a_opts.push_back(modeling_wire_boxes());
1759             a_opts.push_back(modeling_solid());
1760             a_opts.push_back(modeling_points());
1761             return;
1762           }
1763           ibins++;
1764         }
1765       }
1766     }
1767   }
1768 
1769   bool xx_2_yy(const vec3f& a_pos,vec3f& a_out) const {
1770     // a_pos is in data frame NDC coordinates.
1771    {float XSIZ = width;
1772     float XMGL = left_margin;
1773     float XMGR = right_margin;
1774     float wData = XSIZ-XMGL-XMGR;
1775     a_out[0] = wData*a_pos[0];}
1776 
1777    {float YSIZ = height;
1778     float YMGL = bottom_margin;
1779     float YMGU = top_margin;
1780     float hData = YSIZ-YMGL-YMGU;
1781     a_out[1] = hData*a_pos[1];}
1782 
1783    {float ZSIZ = depth;
1784     float ZMGD = down_margin;
1785     float ZMGU = up_margin;
1786     float dData = ZSIZ-ZMGD-ZMGU;
1787     a_out[2] = dData*a_pos[2];}
1788 
1789     return true;
1790   }
1791 
1792   bool data_frame_2_vp(const vec3f& a_pos,vec3f& a_vp) const {
1793     // a_pos is in data frame NDC coordinates.
1794     // a_vp is in viewport/screen coordinates (in [0,1]).
1795    {float XSIZ = width;
1796     float XMGL = left_margin;
1797     float XMGR = right_margin;
1798     float wData = XSIZ-XMGL-XMGR;
1799     if(XSIZ==0.0F) {
1800       //SoDebugError::postInfo("tools::sg;:plotter::data_frame_2_vp","XSIZ is 0");
1801       return false;
1802     }
1803     a_vp[0] = (wData*a_pos[0] + XMGL)/XSIZ;}
1804 
1805    {float YSIZ = height;
1806     float YMGL = bottom_margin;
1807     float YMGU = top_margin;
1808     float hData = YSIZ-YMGL-YMGU;
1809     if(YSIZ==0.0F) {
1810       return false;
1811     }
1812     a_vp[1] = (hData*a_pos[1] + YMGL)/YSIZ;}
1813 
1814    {float ZSIZ = depth;
1815     float ZMGD = down_margin;
1816     float ZMGU = up_margin;
1817     float dData = ZSIZ-ZMGD-ZMGU;
1818     if(ZSIZ==0.0F) {
1819       return false;
1820     }
1821     a_vp[2] = (dData*a_pos[2] + ZMGD)/ZSIZ;}
1822 
1823     return true;
1824   }
1825 
1826   bool vp_2_data_frame(const vec3f& a_vp,vec3f& a_pos) const {
1827     // a_vp is in viewport/screen coordinates (in [0,1]).
1828     // a_pos is in data frame NDC coordinates.
1829 
1830    {float XSIZ = width;
1831     float XMGL = left_margin;
1832     float XMGR = right_margin;
1833     float wData = XSIZ-XMGL-XMGR;
1834     if(wData==0.0F) {
1835       return false;
1836     }
1837     a_pos[0] = (a_vp[0]*XSIZ - XMGL)/wData;}
1838 
1839    {float YSIZ = height;
1840     float YMGL = bottom_margin;
1841     float YMGU = top_margin;
1842     float hData = YSIZ-YMGL-YMGU;
1843     if(hData==0.0F) {
1844       return false;
1845     }
1846     a_pos[1] = (a_vp[1]*YSIZ - YMGL)/hData;}
1847 
1848    {float ZSIZ = depth;
1849     float ZMGD = down_margin;
1850     float ZMGU = up_margin;
1851     float dData = ZSIZ-ZMGD-ZMGU;
1852     if(dData==0.0F) {
1853       return false;
1854     }
1855     a_pos[2] = (a_vp[2]*ZSIZ - ZMGD)/dData;}
1856 
1857     return true;
1858   }
1859 
1860   bool data_frame_2_axis(const vec3f& aDF,vec3f& a_pos) const {
1861     // aDF is in data area coordinates. In [0,1][0,1][0,1].
1862     // a_pos is in axes coordinates.
1863 
1864     // Assume that axes min,max,is_log are up to date.
1865 
1866    {float mn = m_x_axis.minimum_value;
1867     float mx = m_x_axis.maximum_value;
1868     bool lg = m_x_axis.is_log;
1869     if(lg) {
1870       mn = fpow(10,mn);
1871       mx = fpow(10,mx);
1872     }
1873     a_pos[0] = verify_log_inv(aDF[0],mn,mx-mn,lg);}
1874 
1875    {float mn = m_y_axis.minimum_value;
1876     float mx = m_y_axis.maximum_value;
1877     bool lg = m_y_axis.is_log;
1878     if(lg) {
1879       mn = fpow(10,mn);
1880       mx = fpow(10,mx);
1881     }
1882     a_pos[1] = verify_log_inv(aDF[1],mn,mx-mn,lg);}
1883 
1884    {float mn = m_z_axis.minimum_value;
1885     float mx = m_z_axis.maximum_value;
1886     bool lg = m_z_axis.is_log;
1887     if(lg) {
1888       mn = fpow(10,mn);
1889       mx = fpow(10,mx);
1890     }
1891     a_pos[2] = verify_log_inv(aDF[2],mn,mx-mn,lg);}
1892 
1893     return true;
1894   }
1895 
1896   bool axis_2_data_frame(const vec3f& a_pos,vec3f& aDF) const {
1897     // a_pos is in axes coordinates.
1898     // aDF in data area coordinate. In [0,1][0,1][0,1].
1899 
1900     // Assume that axes min,max,logScale are up to date.
1901 
1902    {float mn = m_x_axis.minimum_value;
1903     float mx = m_x_axis.maximum_value;
1904     if(mx==mn) {
1905       return false;
1906     }
1907     bool lg = m_x_axis.is_log;
1908     if(lg) {
1909       if(mn<=0) {
1910         return false;
1911       }
1912       if(mx<=0) {
1913         return false;
1914       }
1915       mn = flog10(mn);
1916       mx = flog10(mx);
1917     }
1918     aDF[0] = verify_log(a_pos[0],mn,mx-mn,lg);}
1919 
1920    {float mn = m_y_axis.minimum_value;
1921     float mx = m_y_axis.maximum_value;
1922     if(mx==mn) {
1923       return false;
1924     }
1925     bool lg = m_y_axis.is_log;
1926     if(lg) {
1927       if(mn<=0) {
1928         return false;
1929       }
1930       if(mx<=0) {
1931         return false;
1932       }
1933       mn = flog10(mn);
1934       mx = flog10(mx);
1935     }
1936     aDF[1] = verify_log(a_pos[1],mn,mx-mn,lg);}
1937 
1938    {float mn = m_z_axis.minimum_value;
1939     float mx = m_z_axis.maximum_value;
1940     if(mx==mn) {
1941       return false;
1942     }
1943     bool lg = m_z_axis.is_log;
1944     if(lg) {
1945       if(mn<=0) {
1946         return false;
1947       }
1948       if(mx<=0) {
1949         return false;
1950       }
1951       mn = flog10(mn);
1952       mx = flog10(mx);
1953     }
1954     aDF[2] = verify_log(a_pos[2],mn,mx-mn,lg);}
1955 
1956     return true;
1957   }
1958 
1959   bool axis_2_vp(const vec3f& a_pos,vec3f& a_vp) const {
1960     // a_pos is in axes coordinates.
1961     // a_vp is in viewport/screen coordinates (in [0,1]).
1962     vec3f d; // In data area coordinate. In [0,1][0,1][0,1].
1963     if(!axis_2_data_frame(a_pos,d)) return false;
1964     return data_frame_2_vp(d,a_vp);
1965   }
1966 
1967   bool vp_2_axis(const vec3f& a_vp,vec3f& a_pos) const {
1968     // a_vp is in viewport/screen coordinates (in [0,1]).
1969     // a_pos is in axes coordinates.
1970     vec3f d; // In data area coordinate. In [0,1][0,1][0,1].
1971     if(!vp_2_data_frame(a_vp,d)) return false;
1972     return data_frame_2_axis(d,a_pos);
1973   }
1974 
1975 public:
1976   void set_axes_modeling(const std::string& a_v){
1977     m_x_axis.modeling = a_v;
1978     m_y_axis.modeling = a_v;
1979     m_z_axis.modeling = a_v;
1980     m_cmap_axis.modeling = a_v;
1981   }
1982 
1983   void set_axes_color(const colorf& a_color){
1984     m_x_axis.line_style().color = a_color;
1985     m_x_axis.ticks_style().color = a_color;
1986     m_x_axis.labels_style().color = a_color;
1987     m_x_axis.title_style().color = a_color;
1988     m_x_axis.mag_style().color = a_color;
1989 
1990     m_y_axis.line_style().color = a_color;
1991     m_y_axis.ticks_style().color = a_color;
1992     m_y_axis.labels_style().color = a_color;
1993     m_y_axis.title_style().color = a_color;
1994     m_y_axis.mag_style().color = a_color;
1995 
1996     m_z_axis.line_style().color = a_color;
1997     m_z_axis.ticks_style().color = a_color;
1998     m_z_axis.labels_style().color = a_color;
1999     m_z_axis.title_style().color = a_color;
2000     m_z_axis.mag_style().color = a_color;
2001 
2002     m_cmap_axis.line_style().color = a_color;
2003     m_cmap_axis.ticks_style().color = a_color;
2004     m_cmap_axis.labels_style().color = a_color;
2005     m_cmap_axis.title_style().color = a_color;
2006     m_cmap_axis.mag_style().color = a_color;
2007   }
2008 
2009   void set_axes_text_scale(float a_v){
2010     m_x_axis.labels_style().scale = a_v;
2011     m_x_axis.title_style().scale = a_v;
2012     m_x_axis.mag_style().scale = a_v;
2013 
2014     m_y_axis.labels_style().scale = a_v;
2015     m_y_axis.title_style().scale = a_v;
2016     m_y_axis.mag_style().scale = a_v;
2017 
2018     m_z_axis.labels_style().scale = a_v;
2019     m_z_axis.title_style().scale = a_v;
2020     m_z_axis.mag_style().scale = a_v;
2021 
2022     m_cmap_axis.labels_style().scale = a_v;
2023     m_cmap_axis.title_style().scale = a_v;
2024     m_cmap_axis.mag_style().scale = a_v;
2025   }
2026 
2027   void set_axes_line_pattern(unsigned short a_v){
2028     m_x_axis.line_style().pattern = a_v;
2029     m_y_axis.line_style().pattern = a_v;
2030     m_z_axis.line_style().pattern = a_v;
2031     m_cmap_axis.line_style().pattern = a_v;
2032   }
2033 
2034   void set_axes_line_width(int a_v){
2035     m_x_axis.line_style().width = float(a_v);
2036     m_y_axis.line_style().width = float(a_v);
2037     m_z_axis.line_style().width = float(a_v);
2038     m_cmap_axis.line_style().width = float(a_v);
2039 
2040     m_x_axis.ticks_style().width = float(a_v);
2041     m_y_axis.ticks_style().width = float(a_v);
2042     m_z_axis.ticks_style().width = float(a_v);
2043     m_cmap_axis.ticks_style().width = float(a_v);
2044   }
2045 
2046   void set_axes_tick_length(float a_v){
2047     m_x_axis.tick_length = a_v;
2048     m_y_axis.tick_length = a_v;
2049     m_z_axis.tick_length = a_v;
2050     m_cmap_axis.tick_length = a_v;
2051   }
2052 
2053   void set_axes_title_height(float a_v){
2054     m_x_axis.title_height = a_v;
2055     m_y_axis.title_height = a_v;
2056     m_z_axis.title_height = a_v;
2057     m_cmap_axis.title_height = a_v;
2058   }
2059 
2060   void set_axes_label_height(float a_v){
2061     m_x_axis.label_height = a_v;
2062     m_y_axis.label_height = a_v;
2063     m_z_axis.label_height = a_v;
2064     m_cmap_axis.label_height = a_v;
2065   }
2066 
2067   void set_axes_font_modeling(font_modeling a_v){
2068     m_x_axis.labels_style().font_modeling = a_v;
2069     m_x_axis.title_style().font_modeling = a_v;
2070     m_x_axis.mag_style().font_modeling = a_v;
2071 
2072     m_y_axis.labels_style().font_modeling = a_v;
2073     m_y_axis.title_style().font_modeling = a_v;
2074     m_y_axis.mag_style().font_modeling = a_v;
2075 
2076     m_z_axis.labels_style().font_modeling = a_v;
2077     m_z_axis.title_style().font_modeling = a_v;
2078     m_z_axis.mag_style().font_modeling = a_v;
2079 
2080     m_cmap_axis.labels_style().font_modeling = a_v;
2081     m_cmap_axis.title_style().font_modeling = a_v;
2082     m_cmap_axis.mag_style().font_modeling = a_v;
2083   }
2084 
2085   void set_font_modeling(font_modeling a_v){
2086     set_axes_font_modeling(a_v);
2087     title_style().font_modeling = a_v;
2088     infos_style().font_modeling = a_v;
2089     title_box_style().font_modeling = a_v;
2090   }
2091 protected:
2092   void init_sg(){
2093 
2094     m_group.add(new noderef(m_background_sep));
2095     m_group.add(new noderef(m_cmap_sep));
2096     m_group.add(new noderef(m_infos_title_sep));
2097     m_group.add(new noderef(m_infos_sep));
2098     m_group.add(new noderef(m_legend_sep));
2099     m_group.add(new noderef(m_title_box_sep));
2100     m_group.add(new noderef(m_tsf));
2101     m_group.add(new noderef(m_layout));
2102     m_group.add(new noderef(m_title_sep));
2103     m_group.add(new noderef(m_x_axis_sep));
2104     m_group.add(new noderef(m_y_axis_sep));
2105     m_group.add(new noderef(m_z_axis_sep));
2106     m_group.add(new noderef(m_grid_sep));
2107     m_group.add(new noderef(m_data_sep));
2108     m_group.add(new noderef(m_primitives_sep));
2109 
2110     m_cmap_sep.add(new noderef(m_cmap_matrix));
2111     m_cmap_sep.add(new noderef(m_cmap_cells_sep));
2112     m_cmap_sep.add(new noderef(m_cmap_axis_matrix));
2113     m_cmap_sep.add(new noderef(m_cmap_axis));
2114 
2115     m_x_axis_sep.add(new noderef(m_x_axis_matrix));
2116     m_x_axis_sep.add(new noderef(m_x_axis));
2117 
2118     m_y_axis_sep.add(new noderef(m_y_axis_matrix));
2119     m_y_axis_sep.add(new noderef(m_y_axis));
2120 
2121     m_z_axis_sep.add(new noderef(m_z_axis_matrix));
2122     m_z_axis_sep.add(new noderef(m_z_axis));
2123 
2124     m_data_sep.add(new noderef(m_data_light));
2125     m_data_sep.add(new noderef(m_data_matrix));
2126 
2127     m_data_sep.add(new noderef(m_bins_sep));
2128     m_data_sep.add(new noderef(m_errors_sep));
2129     m_data_sep.add(new noderef(m_func_sep));
2130     m_data_sep.add(new noderef(m_points_sep));
2131     m_data_sep.add(new noderef(m_inner_frame_sep));
2132     m_data_sep.add(new noderef(m_etc_sep));
2133   }
2134 
2135   void update_layout(){
2136     float XSIZ = width;
2137     float XMGL = left_margin;
2138     float XMGR = right_margin;
2139     float wData = XSIZ-XMGL-XMGR;
2140 
2141     float YSIZ = height;
2142     float YMGL = bottom_margin;
2143     float YMGU = top_margin;
2144     float hData = YSIZ-YMGL-YMGU;
2145 
2146     float ZSIZ = depth;
2147     float ZMGD = down_margin;
2148     float ZMGU = up_margin;
2149     float dData = ZSIZ-ZMGD-ZMGU;
2150 
2151    {mat4f& mtx = m_layout.mtx.value();
2152     mtx.set_identity();
2153 
2154     if(m_shape==xy) {
2155       // in rep primitives (0,0) is the lower left corner
2156       // of the data area square;
2157       mtx.mul_translate(-XSIZ/2+XMGL,-YSIZ/2+YMGL,0);
2158 
2159       if(data_light_on_automated.value()) m_data_light.on = false;
2160       vec3f dir(0,0,-1);
2161       m_data_light.direction = dir;
2162 
2163     } else { //xyz
2164       // global transformation (to have a "lego" layout) :
2165       //  translate so that the center of the scene
2166       //  is the center of the data area cube;
2167       //  then rotate to have lego 3D layout.
2168 
2169       mtx.mul_rotate(1,0,0,theta*fdeg2rad());
2170       mtx.mul_rotate(0,1,0,phi*fdeg2rad());
2171       mtx.mul_rotate(1,0,0,tau*fdeg2rad());
2172 
2173       // To place as CERN-PAW default.
2174       // In CERN-PAW, it is the projection
2175       // which fits in the (XSIZ,XMGL,XMGR)/(YSIZ,YMGL,YMGU)
2176       // page setup.
2177 
2178       rotf r1(vec3f(1,0,0),theta * fdeg2rad());
2179       rotf r2(vec3f(0,1,0),phi * fdeg2rad());
2180       rotf r3(vec3f(1,0,0),tau * fdeg2rad());
2181 
2182       rotf r = r1*r2*r3;
2183       mat4f _m;
2184       r.value(_m);
2185 
2186       float xmn = -0.5F*wData;
2187       float ymn = -0.5F*hData;
2188       float zmn = -0.5F*dData;
2189       float xmx =  0.5F*wData;
2190       float ymx =  0.5F*hData;
2191       float zmx =  0.5F*dData;
2192 
2193       box3f _box;
2194       float x,y,z;
2195       // zmn face :
2196      {x = xmn;y = ymn;z = zmn;
2197       _m.mul_3f(x,y,z);
2198       _box.extend_by(x,y,z);}
2199      {x = xmx;y = ymn;z = zmn;
2200       _m.mul_3f(x,y,z);
2201       _box.extend_by(x,y,z);}
2202      {x = xmx;y = ymx;z = zmn;
2203       _m.mul_3f(x,y,z);
2204       _box.extend_by(x,y,z);}
2205      {x = xmn;y = ymx;z = zmn;
2206       _m.mul_3f(x,y,z);
2207       _box.extend_by(x,y,z);}
2208 
2209       // zmx face :
2210      {x = xmn;y = ymn;z = zmx;
2211       _m.mul_3f(x,y,z);
2212       _box.extend_by(x,y,z);}
2213      {x = xmx;y = ymn;z = zmx;
2214       _m.mul_3f(x,y,z);
2215       _box.extend_by(x,y,z);}
2216      {x = xmx;y = ymx;z = zmx;
2217       _m.mul_3f(x,y,z);
2218       _box.extend_by(x,y,z);}
2219      {x = xmn;y = ymx;z = zmx;
2220       _m.mul_3f(x,y,z);
2221       _box.extend_by(x,y,z);}
2222 
2223       float xfac = _box.mx()[0]-_box.mn()[0];
2224       float yfac = _box.mx()[1]-_box.mn()[1];
2225       float zfac = _box.mx()[2]-_box.mn()[2];
2226 
2227       //cube setup (driven by hData) :
2228       mtx.mul_scale(hData/xfac,hData/yfac,hData/zfac);
2229 
2230       mtx.mul_translate(-wData/2,-hData/2,-dData/2); //Applied first.
2231 
2232       if(data_light_on_automated.value()) m_data_light.on = true;
2233      {vec3f dir(1,-1,-10);
2234       float dx,dy,dz;dir.value(dx,dy,dz);
2235       mat4f inv;
2236       if(mtx.invert(inv)) {
2237         inv.mul_dir_3f(dx,dy,dz);
2238         m_data_light.direction = vec3f(dx,dy,dz);
2239       }}
2240     }}
2241 
2242    {mat4f& mtx = m_data_matrix.mtx.value();
2243     mtx.set_identity();
2244     if(m_shape==xy) {
2245       mtx.mul_scale(wData,hData,1); //z size decided with xy_depth
2246     } else if(m_shape==xyz) {
2247       mtx.mul_scale(wData,hData,dData);
2248     }}
2249 
2250   }
2251 
2252 public:
2253   void update_sg(std::ostream& a_out) {
2254 
2255     update_shape();
2256     update_axes_data(a_out);
2257 
2258     update_background();
2259     update_layout();
2260 
2261     // roundtrip over plottables to check if they are valids. Done first.
2262     unsigned int nplottables = 0;
2263     unsigned int nbins = 0;
2264     unsigned int npoints = 0;
2265     unsigned int nfunc = 0;
2266    {tools_vforit(plottable*,m_plottables,it) {
2267       plottable* object = *it;
2268       if(!object) continue;
2269       if(!object->is_valid()) {
2270         *it = 0;
2271         delete object;
2272       } else {
2273         if(safe_cast<plottable,bins1D>(*object)) {
2274           nplottables++;
2275           nbins++;
2276         } else if(safe_cast<plottable,bins2D>(*object)) {
2277           nplottables++;
2278           nbins++;
2279 
2280         } else if(safe_cast<plottable,points2D>(*object)) {
2281           nplottables++;
2282           npoints++;
2283         } else if(safe_cast<plottable,points3D>(*object)) {
2284           nplottables++;
2285           npoints++;
2286 
2287         } else if(safe_cast<plottable,func1D>(*object)) {
2288           nplottables++;
2289           nfunc++;
2290         } else if(safe_cast<plottable,func2D>(*object)) {
2291           nplottables++;
2292           nfunc++;
2293         }
2294       }
2295     }}
2296 
2297     clear_cmaps();
2298     m_bins_cmaps.resize(nbins,0);
2299     m_points_cmaps.resize(npoints,0);
2300     m_func_cmaps.resize(nfunc,0);
2301 
2302     // even if !nplottables we continue.
2303 
2304     m_infos_title_sep.clear();
2305     m_infos_sep.clear();
2306     m_legend_strings.clear();
2307 
2308     bool superpose = false; 
2309     float xmin =  m_x_axis_data.min_value();
2310     float xmax =  m_x_axis_data.max_value();
2311     bool xlog = m_x_axis_data.is_log();
2312     if(xlog) {
2313       if((xmin<=0) || (xmax<=0) ) {
2314         m_x_axis_data.adjust();
2315         xmin =  m_x_axis_data.min_value();
2316         xmax =  m_x_axis_data.max_value();
2317         // now should have reasonable values.
2318       }
2319       if((xmin<=0) || (xmax<=0) ) {
2320         xlog = false;
2321       } else {
2322         xmin = flog10(xmin);
2323         xmax = flog10(xmax);
2324       }
2325     }
2326 
2327     float ymin =  m_y_axis_data.min_value();
2328     float ymax =  m_y_axis_data.max_value();
2329     bool ylog = m_y_axis_data.is_log();
2330     if(ylog) {
2331       if((ymin<=0) || (ymax<=0) ) {
2332         m_y_axis_data.adjust();
2333         ymin = m_y_axis_data.min_value();
2334         ymax = m_y_axis_data.max_value();
2335         // now should have reasonable values.
2336       }
2337       if((ymin<=0) || (ymax<=0) ) {
2338         ylog = false;
2339       }else{
2340         ymin = flog10(ymin);
2341         ymax = flog10(ymax);
2342       }
2343     }
2344 
2345     float zmin =  m_z_axis_data.min_value();
2346     float zmax =  m_z_axis_data.max_value();
2347     bool zlog = m_z_axis_data.is_log();
2348     if(zlog) {
2349       if((zmin<=0) || (zmax<=0) ) {
2350         m_z_axis_data.adjust();
2351         zmin = m_z_axis_data.min_value();
2352         zmax = m_z_axis_data.max_value();
2353         // now should have reasonable values.
2354       }
2355       if((zmin<=0) || (zmax<=0) ) {
2356         zlog = false;
2357       }else{
2358         zmin = flog10(zmin);
2359         zmax = flog10(zmax);
2360       }
2361     }
2362 
2363     if(m_shape==xy) {
2364       if(xmin>=xmax) {
2365         DUMP_UPDATE_WHAT(a_out,"bad min/max x axes");
2366       }
2367       if(ymin>=ymax) {
2368         DUMP_UPDATE_WHAT(a_out,"bad min/max y axes");
2369       }
2370     } else if(m_shape==xyz) {
2371       if(xmin>=xmax) {
2372         DUMP_UPDATE_WHAT(a_out,"bad min/max x axes");
2373       }
2374       if(ymin>=ymax) {
2375         DUMP_UPDATE_WHAT(a_out,"bad min/max y axes");
2376       }
2377       if(zmin>=zmax) {
2378         DUMP_UPDATE_WHAT(a_out,"bad min/max z axes");
2379       }
2380     }
2381 
2382    {float XSIZ = width;
2383     float XMGL = left_margin;
2384     float XMGR = right_margin;
2385     float wData = XSIZ-XMGL-XMGR;
2386 
2387     float YSIZ = height;
2388     float YMGL = bottom_margin;
2389     float YMGU = top_margin;
2390     float hData = YSIZ-YMGL-YMGU;
2391     if(m_shape==xy) {
2392       if(wData<=0) {
2393         DUMP_UPDATE_WHAT(a_out,"null w data area");
2394       }
2395       if(hData<=0) {
2396         DUMP_UPDATE_WHAT(a_out,"null h data area");
2397       }
2398     } else if(m_shape==xyz) {
2399       float ZSIZ = depth;
2400       float ZMGD = down_margin;
2401       float ZMGU = up_margin;
2402       float dData = ZSIZ-ZMGD-ZMGU;
2403       if(wData<=0) {
2404         DUMP_UPDATE_WHAT(a_out,"null w data area");
2405       }
2406       if(hData<=0) {
2407         DUMP_UPDATE_WHAT(a_out,"null h data area");
2408       }
2409       if(dData<=0) {
2410         DUMP_UPDATE_WHAT(a_out,"null d data area");
2411       }
2412     }}
2413 
2414     float dx   = xmax - xmin;
2415     float dy   = ymax - ymin;
2416     float dz   = zmax - zmin;
2417 
2418     rep_box boxX(xmin,dx,xlog);
2419     rep_box boxY(ymin,dy,ylog);
2420     rep_box boxZ(zmin,dz,zlog);
2421 
2422     ////////////////////////////////////
2423     /// data : /////////////////////////
2424     ////////////////////////////////////
2425     if(m_shape==xy) {
2426       // first data plane is at zz = _zoffset().
2427 
2428       float zz = 0;
2429 
2430       ////////////////////////////////////
2431       /// binss //////////////////////////
2432       ////////////////////////////////////
2433 
2434      {m_bins_sep.clear();
2435       m_errors_sep.clear();
2436 
2437       unsigned int ibins = 0; //used to get each bins style and colormap.
2438       tools_vforcit(plottable*,m_plottables,it) {
2439         plottable* object = *it;
2440         if(!object) continue;
2441         if(bins1D* b1 = safe_cast<plottable,bins1D>(*object)) {
2442 
2443           zz += _zoffset(); // ibins = 0 back (PAW convention).
2444           style* data_style = merge_bins_style(ibins,*object);
2445           style* _left_hatch_style = merge_left_hatch_style(ibins,*object);
2446           style* _right_hatch_style = merge_right_hatch_style(ibins,*object);
2447           style* error_style = merge_errors_style(ibins,*object);
2448 
2449           update_bins1D_xy(a_out,*b1,
2450                            *data_style,*_left_hatch_style,*_right_hatch_style,*error_style,ibins,
2451                            superpose,boxX,boxY,zz);
2452 
2453           if(legends_automated.value()) {
2454             m_legend_strings.push_back(object->legend());
2455             style& _style = legend_style(m_legend_strings.size()-1);
2456             _style.color = data_style->color;
2457             _style.marker_style = data_style->marker_style;
2458             _style.marker_size = data_style->marker_size;
2459           }
2460 
2461           delete data_style;
2462           delete _left_hatch_style;
2463           delete _right_hatch_style;
2464           delete error_style;
2465           ibins++;
2466         } if(bins2D* b2 = safe_cast<plottable,bins2D>(*object)) {
2467           zz += _zoffset(); // ibins = 0 back (PAW convention).
2468           style* data_style = merge_bins_style(ibins,*object);
2469 
2470           update_bins2D_xy(a_out,*b2,*data_style,ibins,boxX,boxY,boxZ,zz);
2471 
2472           if(legends_automated.value()) {
2473             m_legend_strings.push_back(object->legend());
2474             style& _style = legend_style(m_legend_strings.size()-1);
2475             _style.color = data_style->color;
2476             _style.marker_style = data_style->marker_style;
2477             _style.marker_size = data_style->marker_size;
2478           }
2479 
2480           delete data_style;
2481           ibins++;
2482         }
2483       }}
2484 
2485       ////////////////////////////////////
2486       /// funcs //////////////////////////
2487       ////////////////////////////////////
2488 
2489      {m_func_sep.clear();
2490       //zz = 0; // Functions in front.
2491       unsigned int ifunc = 0; //used to get each func style and colormap.
2492       tools_vforcit(plottable*,m_plottables,it) {
2493         plottable* object = *it;
2494         if(!object) continue;
2495         if(func1D* f1 = safe_cast<plottable,func1D>(*object)) {
2496           zz += _zoffset();
2497           style* data_style = merge_func_style(ifunc,*object);
2498           update_func1D_xy(a_out,*f1,*data_style,boxX,boxY,zz);
2499           if(legends_automated.value()) {
2500             m_legend_strings.push_back(object->legend());
2501             style& _style = legend_style(m_legend_strings.size()-1);
2502             _style.color = data_style->color;
2503             _style.marker_style = data_style->marker_style;
2504             _style.marker_size = data_style->marker_size;
2505           }
2506           delete data_style;
2507           ifunc++;
2508         } else if(func2D* f2 = safe_cast<plottable,func2D>(*object)) {
2509           zz += _zoffset();
2510           style* data_style = merge_func_style(ifunc,*object);
2511           update_func2D_xy(a_out,*f2,ifunc,*data_style,boxX,boxY,boxZ,zz);
2512           if(legends_automated.value()) {
2513             m_legend_strings.push_back(object->legend());
2514             style& _style = legend_style(m_legend_strings.size()-1);
2515             _style.color = data_style->color;
2516             _style.marker_style = data_style->marker_style;
2517             _style.marker_size = data_style->marker_size;
2518           }
2519           delete data_style;
2520           ifunc++;
2521         }
2522       }}
2523 
2524       ////////////////////////////////////
2525       /// pointss ////////////////////////
2526       ////////////////////////////////////
2527      {m_points_sep.clear();
2528       unsigned int ipoints = 0; //used to get each points style and colormap.
2529       tools_vforcit(plottable*,m_plottables,it) {
2530         plottable* object = *it;
2531         if(!object) continue;
2532         if(points2D* p2 = safe_cast<plottable,points2D>(*object)) {
2533 
2534           zz += _zoffset(); // ibins = 0 back (PAW convention).
2535           style* data_style = merge_points_style(ipoints,*object);
2536           update_points2D_xy(a_out,*p2,*data_style,boxX,boxY,zz);
2537 
2538           if(legends_automated.value()) {
2539             m_legend_strings.push_back(object->legend());
2540             style& _style = legend_style(m_legend_strings.size()-1);
2541             _style.color = data_style->color;
2542             _style.modeling = data_style->modeling;
2543             _style.marker_style = data_style->marker_style;
2544             _style.marker_size = data_style->marker_size;
2545             _style.point_size = data_style->point_size;
2546           }
2547 
2548           delete data_style;
2549           ipoints++;
2550         }
2551       }}
2552     }
2553 
2554     if(m_shape==xyz) {
2555 
2556       ////////////////////////////////////
2557       /// binss //////////////////////////
2558       ////////////////////////////////////
2559      {m_bins_sep.clear();
2560       m_errors_sep.clear();
2561       unsigned int ibins = 0; //used to get each bins style and colormap.
2562       tools_vforcit(plottable*,m_plottables,it) {
2563         plottable* object = *it;
2564         if(!object) continue;
2565         if(safe_cast<plottable,bins1D>(*object)) {
2566           ibins++;
2567         } else if(bins2D* b2 = safe_cast<plottable,bins2D>(*object)) {
2568           style* data_style = merge_bins_style(ibins,*object);
2569           update_bins2D_xyz(a_out,*b2,ibins,*data_style,boxX,boxY,boxZ);
2570           delete data_style;
2571           ibins++;
2572         }
2573       }}
2574 
2575       ////////////////////////////////////
2576       /// funcs //////////////////////////
2577       ////////////////////////////////////
2578 
2579      {m_func_sep.clear();
2580       unsigned int ifunc = 0; //used to get each func style and colormap.
2581       tools_vforcit(plottable*,m_plottables,it) {
2582         plottable* object = *it;
2583         if(!object) continue;
2584         if(safe_cast<plottable,func1D>(*object)) {
2585           ifunc++;
2586         } else if(func2D* f2 = safe_cast<plottable,func2D>(*object)) {
2587           style* data_style = merge_func_style(ifunc,*object);
2588           update_func2D_xyz(a_out,*f2,ifunc,*data_style,boxX,boxY,boxZ);
2589           delete data_style;
2590           ifunc++;
2591         }
2592       }}
2593 
2594       ////////////////////////////////////
2595       /// pointss ////////////////////////
2596       ////////////////////////////////////
2597      {m_points_sep.clear();
2598       unsigned int ipoints = 0; //used to get each points style and colormap.
2599       tools_vforcit(plottable*,m_plottables,it) {
2600         plottable* object = *it;
2601         if(!object) continue;
2602         if(points3D* p3 = safe_cast<plottable,points3D>(*object)) {
2603 
2604           style* data_style = merge_points_style(ipoints,*object);
2605           update_points3D_xyz(a_out,*p3,*data_style,boxX,boxY,boxZ);
2606 
2607           if(legends_automated.value()) {
2608             m_legend_strings.push_back(object->legend());
2609             style& _style = legend_style(m_legend_strings.size()-1);
2610             _style.color = data_style->color;
2611             _style.modeling = data_style->modeling;
2612             _style.marker_style = data_style->marker_style;
2613             _style.marker_size = data_style->marker_size;
2614             _style.point_size = data_style->point_size;
2615           }
2616 
2617           delete data_style;
2618           ipoints++;
2619         }
2620       }}
2621     }
2622 
2623     ////////////////////////////////////
2624     /// axes : /////////////////////////
2625     ////////////////////////////////////
2626     // done before update_legends() which needs
2627     // the x_axis min/max if legends_origin_unit
2628     // is unit_axis.
2629 
2630     // axes :
2631     if(m_shape==xy){
2632       if(x_axis_enforced.value()) {
2633         update_x_axis_2D();
2634         m_x_axis.minimum_value = x_axis_min.value();
2635         m_x_axis.maximum_value = x_axis_max.value();
2636         m_x_axis.is_log = x_axis_is_log.value();
2637         m_x_axis.update_sg(a_out); // So that the grid be correct.
2638         m_x_axis.reset_touched();
2639       } else {
2640         if(!nplottables) {
2641           m_x_axis.width = 0;
2642         } else {
2643           update_x_axis_2D();
2644           update_axis(a_out,m_x_axis,m_x_axis_data);
2645         }
2646       }
2647 
2648       if(y_axis_enforced.value()) {
2649         update_y_axis_2D();
2650         m_y_axis.minimum_value = y_axis_min.value();
2651         m_y_axis.maximum_value = y_axis_max.value();
2652         m_y_axis.is_log = y_axis_is_log.value();
2653         m_y_axis.update_sg(a_out); // So that the grid be correct.
2654         m_y_axis.reset_touched();
2655       } else {
2656         if(!nplottables) {
2657           m_y_axis.width = 0;
2658         } else {
2659           update_y_axis_2D();
2660           update_axis(a_out,m_y_axis,m_y_axis_data);
2661         }
2662       }
2663 
2664       if(z_axis_enforced.value()) {
2665         update_z_axis_2D();
2666         m_z_axis.minimum_value = z_axis_min.value();
2667         m_z_axis.maximum_value = z_axis_max.value();
2668         m_z_axis.is_log = z_axis_is_log.value();
2669         m_z_axis.update_sg(a_out); // So that the grid be correct.
2670         m_z_axis.reset_touched();
2671       } else {
2672         if(!nplottables) {
2673           m_z_axis.width = 0;
2674         } else {
2675           update_z_axis_2D();
2676         }
2677       }
2678     }
2679 
2680     if(m_shape==xyz){
2681       if(x_axis_enforced.value()) {
2682         update_x_axis_3D();
2683         m_x_axis.minimum_value = x_axis_min.value();
2684         m_x_axis.maximum_value = x_axis_max.value();
2685         m_x_axis.is_log = x_axis_is_log.value();
2686         m_x_axis.update_sg(a_out); // So that the grid be correct.
2687         m_x_axis.reset_touched();
2688       } else {
2689         if(!nplottables) {
2690           m_x_axis.width = 0;
2691         } else {
2692           update_x_axis_3D();
2693           update_axis(a_out,m_x_axis,m_x_axis_data);
2694         }
2695       }
2696 
2697       if(y_axis_enforced.value()) {
2698         update_y_axis_3D();
2699         m_y_axis.minimum_value = y_axis_min.value();
2700         m_y_axis.maximum_value = y_axis_max.value();
2701         m_y_axis.is_log = y_axis_is_log.value();
2702         m_y_axis.update_sg(a_out); // So that the grid be correct.
2703         m_y_axis.reset_touched();
2704       } else {
2705         if(!nplottables) {
2706           m_y_axis.width = 0;
2707         } else {
2708           update_y_axis_3D();
2709           update_axis(a_out,m_y_axis,m_y_axis_data);
2710         }
2711       }
2712 
2713       if(z_axis_enforced.value()) {
2714         update_z_axis_3D();
2715         m_z_axis.minimum_value = z_axis_min.value();
2716         m_z_axis.maximum_value = z_axis_max.value();
2717         m_z_axis.is_log = z_axis_is_log.value();
2718         m_z_axis.update_sg(a_out); // So that the grid be correct.
2719         m_z_axis.reset_touched();
2720       } else {
2721         if(!nplottables) {
2722           m_z_axis.width = 0;
2723         } else {
2724           update_z_axis_3D();
2725           update_axis(a_out,m_z_axis,m_z_axis_data);
2726         }
2727       }
2728     }
2729 
2730     if(nplottables) {
2731       // infos box is done before update_legends()
2732       // because legends may be placed relative to it.
2733       update_infos(a_out);
2734     }
2735     m_legend_sep.clear();
2736 
2737     if(!legends_automated) {
2738       m_legend_strings = legends_string.values();
2739     }
2740     update_legends(a_out);
2741 
2742     if(title_automated) {
2743       std::string _s;
2744       get_title(_s);
2745       title.value(_s);
2746       title.reset_touched(); //output field.
2747     }
2748     m_title_sep.clear();
2749     if(nplottables) update_title();
2750 
2751     m_title_box_sep.clear();
2752     if(nplottables) update_title_box();
2753 
2754     m_inner_frame_sep.clear();
2755     if(inner_frame_enforced.value() || nplottables) {
2756       if(m_shape==xy) {
2757         update_inner_frame_XY();
2758       } else {
2759         update_inner_frame_XYZ();
2760       }
2761     }
2762 
2763     m_grid_sep.clear();
2764     if(nplottables) {
2765       if(m_shape==xy) {
2766         update_grid_XY();
2767       } else {
2768         update_grid_XYZ();
2769       }
2770     }
2771 
2772     m_cmap_axis.width = 0;
2773     m_cmap_cells_sep.clear();
2774     if(m_bins_cmaps.size() && m_bins_cmaps[0] && m_bins_cmaps[0]->valn()) {     //major_bins
2775       update_cmap(a_out,*(m_bins_cmaps[0]));
2776     } else if(m_points_cmaps.size() && m_points_cmaps[0] && m_points_cmaps[0]->valn()) { //major_points
2777       update_cmap(a_out,*(m_points_cmaps[0]));
2778     } else if(m_func_cmaps.size() && m_func_cmaps[0] && m_func_cmaps[0]->valn()) { //major_func
2779       update_cmap(a_out,*(m_func_cmaps[0]));
2780     }
2781 
2782     update_primitives(a_out);
2783   }
2784 
2785   void get_value_axis_min_max(float a_Sw_mn,float a_Sw_mx,bool a_is_log,float& a_min,float& a_max,bool a_min_visible) {
2786     if(a_Sw_mn>a_Sw_mx) {
2787       a_min = 0;
2788       a_max = 0;
2789       return;
2790     }
2791     // a_Sw_mx >= a_Sw_mn.
2792     if(a_is_log && (a_Sw_mn<=0) ) { //let data_axis.adjust() do something.
2793       a_min = a_Sw_mn;
2794       a_max = a_Sw_mx;
2795       return;
2796     }
2797     float mn;
2798     if(a_is_log) {
2799       if(value_bottom_margin.value()!=0) {
2800         float log_Sw_mn = flog10(a_Sw_mn);
2801         float log_Sw_mx = flog10(a_Sw_mx);
2802         float log_mn = log_Sw_mn - (log_Sw_mx-log_Sw_mn)*value_bottom_margin;
2803         mn = fpow(10,log_mn);
2804       } else {
2805         mn = a_Sw_mn;
2806         if(a_min_visible) { // arrang so that the bin with a_Sw_mn be visible.
2807           float log_Sw_mn = flog10(a_Sw_mn);
2808           mn = fpow(10,log_Sw_mn)*(1.0f-0.4f);
2809         }
2810       }
2811     } else {
2812       if(value_bottom_margin.value()!=0) {
2813         mn = a_Sw_mn - (a_Sw_mx-a_Sw_mn)*value_bottom_margin;
2814       } else {
2815         if(a_min_visible) {
2816           // Arrange so that the bin with a_Sw_mn (if not 0) be visible. (If 0, it will be anyway on the x axis) :
2817           if(a_Sw_mn>0) {
2818             mn = 0; //PAW logic.
2819           } else if(a_Sw_mn==0) {
2820             mn = 0; //PAW logic. min bin will be anyway on x axis.
2821           } else {
2822             mn = a_Sw_mn; // min bin will be anyway on x axis.
2823           }
2824         } else {
2825           mn = a_Sw_mn; //min bin will be on x axis.
2826         }
2827       }
2828     }
2829     a_min = mn;
2830 
2831     float mx;
2832     if(a_is_log) {
2833       if(value_top_margin.value()!=0) {
2834         float log_Sw_mn = flog10(a_Sw_mn);
2835         float log_Sw_mx = flog10(a_Sw_mx);
2836         float log_mx = log_Sw_mx + (log_Sw_mx-log_Sw_mn)*value_top_margin;
2837         mx = fpow(10,log_mx);
2838       } else {
2839         mx = a_Sw_mx; //max bin will be on top of frame (then not visible if same color).
2840       }
2841     } else {
2842       mx = a_Sw_mx + (a_Sw_mx-mn)*value_top_margin;
2843     //mx = a_Sw_mx + (a_Sw_mx-a_Sw_mn)*value_top_margin; //not compatible with gopaw.
2844     }
2845     a_max = mx;
2846   }
2847 
2848   void update_axes_data(std::ostream& a_out){
2849     m_x_axis_data.set_min_value(0);
2850     m_x_axis_data.set_max_value(0);
2851     m_x_axis_data.set_is_log(x_axis_is_log);
2852 
2853     m_y_axis_data.set_min_value(0);
2854     m_y_axis_data.set_max_value(0);
2855     m_y_axis_data.set_is_log(y_axis_is_log);
2856 
2857     m_z_axis_data.set_min_value(0);
2858     m_z_axis_data.set_max_value(0);
2859     m_z_axis_data.set_is_log(z_axis_is_log);
2860 
2861     if(!x_axis_automated) { //def = true
2862       m_x_axis_data.set_min_value(x_axis_min);
2863       m_x_axis_data.set_max_value(x_axis_max);
2864     }
2865 
2866     if(!y_axis_automated) {
2867       m_y_axis_data.set_min_value(y_axis_min);
2868       m_y_axis_data.set_max_value(y_axis_max);
2869     }
2870 
2871     if(!z_axis_automated) {
2872       m_z_axis_data.set_min_value(z_axis_min);
2873       m_z_axis_data.set_max_value(z_axis_max);
2874     }
2875 
2876     bins1D* b1;
2877     bins2D* b2;
2878 
2879     func1D* f1;
2880     func2D* f2;
2881 
2882     points2D* p2;
2883     points3D* p3;
2884 
2885     if(first_bins(b1,b2)) {
2886 
2887       if(b1) {
2888 
2889         if(x_axis_automated) {
2890           m_x_axis_data.set_min_value(b1->axis_min());
2891           m_x_axis_data.set_max_value(b1->axis_max());
2892         }
2893 
2894         if(y_axis_automated) {
2895           float Sw_mn,Sw_mx;
2896           b1->bins_Sw_range(Sw_mn,Sw_mx,value_bins_with_entries.value());
2897           float mn,mx;
2898           get_value_axis_min_max(Sw_mn,Sw_mx,m_y_axis_data.is_log(),mn,mx,true);
2899           m_y_axis_data.set_min_value(mn);
2900           m_y_axis_data.set_max_value(mx);
2901 
2902           m_y_axis_data.adjust();
2903         }
2904 
2905       } if(b2) {
2906         if(x_axis_automated) {
2907           m_x_axis_data.set_min_value(b2->x_axis_min());
2908           m_x_axis_data.set_max_value(b2->x_axis_max());
2909         }
2910 
2911         if(y_axis_automated) {
2912           m_y_axis_data.set_min_value(b2->y_axis_min());
2913           m_y_axis_data.set_max_value(b2->y_axis_max());
2914         }
2915 
2916         if(z_axis_automated) {
2917           float Sw_mn,Sw_mx;
2918           b2->bins_Sw_range(Sw_mn,Sw_mx,value_bins_with_entries.value());
2919           float mn,mx;
2920           get_value_axis_min_max(Sw_mn,Sw_mx,m_z_axis_data.is_log(),mn,mx,false);
2921           m_z_axis_data.set_min_value(mn);
2922           m_z_axis_data.set_max_value(mx);
2923 
2924           m_z_axis_data.adjust();
2925         }
2926       } /*else if(f_binsList[0]->getDimension()==3) {
2927         //FIXME : should do something.
2928       } else {
2929         // Unusual case.
2930       }*/
2931 
2932     } else if(first_points(p2,p3)) {
2933       if(p2) {
2934         if(x_axis_automated) {
2935           m_x_axis_data.set_min_value(p2->x_axis_min());
2936           m_x_axis_data.set_max_value(p2->x_axis_max());
2937         }
2938         if(y_axis_automated) {
2939           float ymn = p2->y_axis_min();
2940           float ymx = p2->y_axis_max();
2941           m_y_axis_data.set_min_value(ymn);
2942           m_y_axis_data.set_max_value(ymx);
2943         }
2944       } else if(p3) {
2945 
2946         if(x_axis_automated) {
2947           m_x_axis_data.set_min_value(p3->x_axis_min());
2948           m_x_axis_data.set_max_value(p3->x_axis_max());
2949         }
2950 
2951         if(y_axis_automated) {
2952           m_y_axis_data.set_min_value(p3->y_axis_min());
2953           m_y_axis_data.set_max_value(p3->y_axis_max());
2954         }
2955 
2956         if(z_axis_automated) {
2957           m_z_axis_data.set_min_value(p3->z_axis_min());
2958           m_z_axis_data.set_max_value(p3->z_axis_max());
2959         }
2960       }
2961 
2962     } else if(first_func(f1,f2)) {
2963 
2964       if(f1) {
2965 
2966         if(x_axis_automated) {
2967           float xmn = f1->x_min();
2968           float xmx = f1->x_max();
2969           if(xmx<=xmn) {
2970             xmn = -1;
2971             xmx = 1;
2972           }
2973           m_x_axis_data.set_min_value(xmn);
2974           m_x_axis_data.set_max_value(xmx);
2975         }
2976 
2977         if(y_axis_automated) {
2978           float xmn = m_x_axis_data.min_value();
2979           float xmx = m_x_axis_data.max_value();
2980           unsigned int nstp = f1->x_steps();
2981           nstp = nstp <=0 ? curve_number_of_points.value(): nstp;
2982 
2983           float df = (xmx - xmn)/nstp;
2984           bool problem = false;
2985           float vmin;
2986           if(!f1->value(xmn,vmin)) problem = true;
2987           float vmax = vmin;
2988           for(unsigned int ibin=0;ibin<=nstp;ibin++) {
2989             float xx = xmn + ibin * df;
2990             float val;
2991             if(!f1->value(xx,val)) problem = true;
2992             vmax = max_of<float>(vmax,val);
2993             vmin = min_of<float>(vmin,val);
2994           }
2995           if(problem) {
2996             a_out << "tools::sg::plotter :"
2997                   << " problem when getting some function value."
2998                   << std::endl;
2999           }
3000           m_y_axis_data.set_min_value(vmin);
3001           m_y_axis_data.set_max_value(vmax);
3002           m_y_axis_data.adjust();
3003         }
3004 
3005       } else if(f2) {
3006         if(x_axis_automated) {
3007           float xmn = f2->x_min();
3008           float xmx = f2->x_max();
3009           if(xmx<=xmn) {
3010             xmn = -1;
3011             xmx = 1;
3012           }
3013           m_x_axis_data.set_min_value(xmn);
3014           m_x_axis_data.set_max_value(xmx);
3015         }
3016 
3017         if(y_axis_automated) {
3018           float ymn =  f2->y_min();
3019           float ymx =  f2->y_max();
3020           if(ymx<=ymn) {
3021             ymn = -1;
3022             ymx = 1;
3023           }
3024           m_y_axis_data.set_min_value(ymn);
3025           m_y_axis_data.set_max_value(ymx);
3026         }
3027 
3028         if(z_axis_automated) {
3029 
3030           float xmn = m_x_axis_data.min_value();
3031           float xmx = m_x_axis_data.max_value();
3032           int nx = f2->x_steps();
3033           nx = nx <=0 ? curve_number_of_points.value() : nx;
3034 
3035           float ymn = m_y_axis_data.min_value();
3036           float ymx = m_y_axis_data.max_value();
3037           int ny = f2->y_steps();
3038           ny = ny <=0 ? curve_number_of_points.value() : ny;
3039 
3040           float dfx = (xmx - xmn)/nx;
3041           float dfy = (ymx - ymn)/ny;
3042 
3043           bool problem = false;
3044           float vmin;
3045           if(!f2->value(xmn,ymn,vmin)) problem = true;
3046           float vmax = vmin;
3047           for(int jbin=ny-1;jbin>=0;jbin--) {
3048             for(int ibin=nx-1;ibin>=0;ibin--) {
3049               float xx = xmn + ibin * dfx;
3050               float yy = ymn + jbin * dfy;
3051               float val;
3052               if(!f2->value(xx,yy,val)) problem = true;
3053               vmin = min_of<float>(vmin,val);
3054               vmax = max_of<float>(vmax,val);
3055             }
3056           }
3057           if(problem) {
3058             a_out << "tools::sg::plotter :"
3059                   << " problem when getting some function value."
3060                   << std::endl;
3061           }
3062           m_z_axis_data.set_min_value(vmin);
3063           m_z_axis_data.set_max_value(vmax);
3064           m_z_axis_data.adjust();
3065         }
3066       }
3067     }
3068   }
3069   void update_shape(){
3070     m_shape = get_shape();
3071   }
3072 
3073   void update_axis(std::ostream& a_out,sg::axis& a_axis,data_axis& a_data){
3074     a_axis.minimum_value = a_data.min_value();
3075     a_axis.maximum_value = a_data.max_value();
3076     a_axis.is_log = a_data.is_log();
3077     a_axis.update_sg(a_out); // So that the grid be correct.
3078     a_axis.reset_touched();
3079   }
3080 
3081   void update_x_axis_2D(){
3082     float XSIZ = width;
3083     float XMGL = left_margin;
3084     float XMGR = right_margin;
3085     float wData = XSIZ-XMGL-XMGR;
3086 
3087     //m_x_axis.verbose.setValue(verbose);
3088     m_x_axis.tick_up = true;
3089     m_x_axis.width = wData;
3090 
3091    {text_style& style = m_x_axis.labels_style();
3092     if(!style.enforced.value()) { //gopaw may enforce style.
3093       style.x_orientation = vec3f(1,0,0);
3094       style.y_orientation = vec3f(0,1,0);
3095       style.hjust = center;
3096       style.vjust = top;
3097     }}
3098 
3099    {text_style& style = m_x_axis.title_style();
3100     style.x_orientation = vec3f(1,0,0);
3101     style.y_orientation = vec3f(0,1,0);
3102     style.hjust = m_x_axis.title_hjust;
3103     style.vjust = top;}
3104 
3105    {text_style& style = m_x_axis.mag_style();
3106     style.hjust = left;
3107     style.vjust = bottom;}
3108 
3109     m_x_axis_matrix.set_translate(0,0,_zaxis());
3110   }
3111 
3112   void update_y_axis_2D(){
3113     float YSIZ = height;
3114     float YMGL = bottom_margin;
3115     float YMGU = top_margin;
3116     float hData = YSIZ-YMGL-YMGU;
3117 
3118     m_y_axis.tick_up.value(true);
3119     m_y_axis.width.value(hData);
3120 
3121    {text_style& style = m_y_axis.labels_style();
3122     if(!style.enforced.value()) {
3123       style.x_orientation = vec3f(0,1,0);
3124       style.y_orientation = vec3f(1,0,0);
3125       style.hjust = right;
3126       style.vjust = middle;
3127     }}
3128 
3129    {text_style& style = m_y_axis.title_style();
3130     style.x_orientation = vec3f(1,0,0);
3131     style.y_orientation = vec3f(0,-1,0);
3132     style.hjust = m_y_axis.title_hjust;
3133     style.vjust = bottom;}
3134 
3135    {text_style& style = m_y_axis.mag_style();
3136     style.x_orientation = vec3f(0,1,0);
3137     style.y_orientation = vec3f(1,0,0);
3138     style.hjust = right;
3139     style.vjust = bottom;}
3140 
3141    {mat4f& mtx = m_y_axis_matrix.mtx.value();
3142     mtx.set_translate(0,0,_zaxis());
3143     mtx.mul_rotate(0,1,0,fpi());
3144     mtx.mul_rotate(0,0,1,fhalf_pi());}
3145   }
3146 
3147   void update_z_axis_2D(){
3148     m_z_axis.width = 0;
3149     m_z_axis_matrix.set_identity();
3150   }
3151 
3152   void update_x_axis_3D(){
3153     float XSIZ = width;
3154     float XMGL = left_margin;
3155     float XMGR = right_margin;
3156     float wData = XSIZ-XMGL-XMGR;
3157 
3158     m_x_axis.tick_up = false;
3159     m_x_axis.width = wData;
3160 
3161    {text_style& style = m_x_axis.labels_style();
3162     if(!style.enforced.value()) {
3163       style.x_orientation = vec3f(1,0,0);
3164       style.y_orientation = vec3f(0,1,0);
3165       style.hjust = center;
3166       style.vjust = top;
3167     }}
3168 
3169    {text_style& style = m_x_axis.title_style();
3170     style.x_orientation = vec3f(1,0,0);
3171     style.y_orientation = vec3f(0,1,0);
3172     style.hjust = right;
3173     style.vjust = top;}
3174 
3175     m_x_axis_matrix.set_rotate(1,0,0,fhalf_pi());
3176 
3177   }
3178 
3179   void update_y_axis_3D(){
3180     float YSIZ = height;
3181     float YMGL = bottom_margin;
3182     float YMGU = top_margin;
3183     float hData = YSIZ-YMGL-YMGU;
3184 
3185     m_y_axis.tick_up = false;
3186     m_y_axis.width = hData;
3187 
3188    {text_style& style = m_y_axis.labels_style();
3189     if(!style.enforced.value()) {
3190       style.x_orientation = vec3f(-1,0,0);
3191       style.y_orientation = vec3f( 0,1,0);
3192       style.hjust = center;
3193       style.vjust = top;
3194     }}
3195 
3196    {text_style& style = m_y_axis.title_style();
3197     style.x_orientation = vec3f(-1,0,0);
3198     style.y_orientation = vec3f( 0,1,0);
3199     style.hjust = left;
3200     style.vjust = top;}
3201 
3202    {mat4f& mtx = m_y_axis_matrix.mtx.value();
3203     mtx.set_rotate(0,1,0,fhalf_pi());
3204     mtx.mul_rotate(0,0,1,fhalf_pi());}
3205   }
3206 
3207   void update_z_axis_3D(){
3208     float ZSIZ = depth;
3209     float ZMGD = down_margin;
3210     float ZMGU = up_margin;
3211     float dData = ZSIZ-ZMGD-ZMGU;
3212 
3213     m_z_axis.tick_up = false;
3214     m_z_axis.width = dData;
3215 
3216    {text_style& style = m_z_axis.labels_style();
3217     if(!style.enforced.value()) {
3218       style.x_orientation = vec3f(0,1,0);
3219       style.y_orientation = vec3f(1,0,0);
3220       style.hjust = right;
3221       style.vjust = middle;
3222     }}
3223 
3224    {text_style& style = m_z_axis.title_style();
3225     style.x_orientation = vec3f(0,1,0);
3226     style.y_orientation = vec3f(1,0,0);
3227     style.hjust = right;
3228     style.vjust = bottom;}
3229 
3230    {mat4f& mtx = m_z_axis_matrix.mtx.value();
3231     mtx.set_translate(0,m_y_axis.width.value(),0);
3232     mtx.mul_rotate(0,0,1,-fhalf_pi());
3233     mtx.mul_rotate(0,1,0,-fhalf_pi());}
3234 
3235   }
3236 
3237   void update_cmap(std::ostream& a_out,const base_colormap& a_cmap){
3238     if(!colormap_visible.value()) return;
3239 
3240     size_t valn = a_cmap.valn();
3241     if(!valn) return;
3242     size_t coln = a_cmap.colorn();
3243     if(!coln) return;
3244 
3245     float XSIZ = width;
3246     float XMGL = left_margin;
3247     float XMGR = right_margin;
3248     float wData = XSIZ-XMGL-XMGR;
3249 
3250     float YSIZ = height;
3251     float YMGL = bottom_margin;
3252     float YMGU = top_margin;
3253     float hData = YSIZ-YMGL-YMGU;
3254 
3255     float hcmap = hData;
3256 
3257    {mat4f& mtx = m_cmap_matrix.mtx.value();
3258     if(m_shape==xy) {
3259       mtx = m_layout.mtx.value();
3260       mtx.mul_translate(0,0,_zgrid());
3261     } else {
3262       float ZSIZ = depth;
3263       float ZMGD = down_margin;
3264       float ZMGU = up_margin;
3265       float dData = ZSIZ-ZMGD-ZMGU;
3266       hcmap = dData;
3267       if(colormap_attached.value()) {
3268         mtx = m_layout.mtx.value();
3269         mtx.mul_rotate(1,0,0,90.0F*fdeg2rad());
3270       } else { //OpenPAW
3271         float zz = -depth*0.5f;
3272         mtx.set_translate(-XSIZ/2+XMGL,-YSIZ/2+YMGL,zz); //applied first
3273       }
3274     }}
3275 
3276     float w  = XMGR*0.3F;
3277     float xx = wData+XMGR*0.1F;
3278     float zz = 0;
3279 
3280     float yy = 0;
3281     float h = hcmap/float(coln);
3282 
3283     // colored cells :
3284    {m_cmap_cells_sep.clear();
3285     m_cmap_cells_sep.add(new normal);
3286     for(unsigned int index=0;index<coln;index++)        {
3287       rgba* mat = new rgba();
3288       mat->color = a_cmap.color(index);
3289       m_cmap_cells_sep.add(mat);
3290 
3291       vertices* vtxs = new vertices;
3292       vtxs->mode = gl::triangle_fan();
3293       m_cmap_cells_sep.add(vtxs);
3294 
3295       vtxs->add(xx      ,yy     ,zz);
3296       vtxs->add(xx + w  ,yy     ,zz);
3297       vtxs->add(xx + w  ,yy + h ,zz);
3298       vtxs->add(xx      ,yy + h ,zz);
3299 
3300       yy += h;
3301     }}
3302 
3303     // surrounding box :
3304    {rgba* mat = new rgba();
3305     mat->color = colorf_black();
3306     m_cmap_cells_sep.add(mat);
3307 
3308     draw_style* ds = new draw_style;
3309     ds->style = draw_lines;
3310     ds->line_pattern = line_solid;
3311     ds->line_width = 1;
3312     m_cmap_cells_sep.add(ds);
3313 
3314     vertices* vtxs = new vertices;
3315     vtxs->mode = gl::line_strip();
3316     m_cmap_cells_sep.add(vtxs);
3317 
3318     vtxs->add(xx      ,0     ,zz);
3319     vtxs->add(xx + w  ,0     ,zz);
3320     vtxs->add(xx + w  ,hcmap ,zz);
3321     vtxs->add(xx      ,hcmap ,zz);
3322     vtxs->add(xx      ,0     ,zz);}
3323 
3324     if(!colormap_axis_visible.value()) {
3325       m_cmap_axis.width = 0;
3326     } else {
3327 
3328     // right axis :
3329     mat4f& mtx = m_cmap_axis_matrix.mtx.value();
3330     mtx.set_identity();
3331 
3332     zz += _zoffset()*0.01f;
3333 
3334     if(safe_cast<base_colormap,by_value_colormap>(a_cmap)) {
3335       if(colormap_axis_labeling.value()==cells) {
3336         if((valn+1)==coln) { // <col> <num> <col> ... <num> <col>
3337           mtx.set_translate(xx+w,h,zz);
3338         } else {
3339           mtx.set_translate(xx+w,0,zz);
3340         }
3341       } else {
3342         mtx.set_translate(xx+w,0,zz);
3343       }
3344     } else { //grey_scale,grey_scale_inverse,violet_to_red
3345       mtx.set_translate(xx+w,0,zz);
3346     }
3347 
3348     mtx.mul_rotate(0,0,1,fhalf_pi());
3349 
3350     m_cmap_axis.title = "";
3351     m_cmap_axis.tick_up = true;
3352 
3353     if(safe_cast<base_colormap,by_value_colormap>(a_cmap)) {
3354       if(colormap_axis_labeling.value()==cells) {
3355         if((valn+1)==coln) { // <col> <num> <col> ... <num> <col>
3356           m_cmap_axis.width = hcmap-2*h;
3357           m_cmap_axis.modeling = tick_modeling_none();
3358           m_cmap_axis.tick_number = uint32(valn);
3359           m_cmap_axis.labels.clear();
3360           m_cmap_axis.coords.clear();
3361           for(unsigned int index=0;index<valn;index++)        {
3362             //FIXME : for the labels, have a "mag" logic similar to SoAxis.
3363             char tmp[32];
3364             snpf(tmp,sizeof(tmp),"%g",a_cmap.value(index));
3365             m_cmap_axis.labels.add(tmp);
3366             m_cmap_axis.coords.add(h*index);
3367           }
3368         } else if((coln+1)==valn) { // <num> <col> <num> ... <col> <num>
3369           m_cmap_axis.width = hcmap;
3370           m_cmap_axis.modeling = tick_modeling_none();
3371           m_cmap_axis.tick_number = uint32(valn);
3372           m_cmap_axis.labels.clear();
3373           m_cmap_axis.coords.clear();
3374           for(unsigned int index=0;index<valn;index++)        {
3375             //FIXME : for the labels, have a "mag" logic similar to SoAxis.
3376             char tmp[32];
3377             snpf(tmp,sizeof(tmp),"%g",a_cmap.value(index));
3378             m_cmap_axis.labels.add(tmp);
3379             m_cmap_axis.coords.add(h*index);
3380           }
3381         } else {
3382           a_out << "tools::sg::plotter::update_cmap :"
3383                 << " inconsistent by value colormap."
3384                 << std::endl;
3385         }
3386       } else {
3387         m_cmap_axis.modeling = tick_modeling_hippo();
3388         m_cmap_axis.width = hcmap;
3389         m_cmap_axis.minimum_value = a_cmap.value(0);
3390         m_cmap_axis.maximum_value = a_cmap.value(uint32(valn)-1);
3391       }
3392     } else { //grey_scale,grey_scale_inverse,violet_to_red
3393       m_cmap_axis.modeling = tick_modeling_hippo();
3394       m_cmap_axis.width = hcmap;
3395       m_cmap_axis.minimum_value = a_cmap.value(0);
3396       m_cmap_axis.maximum_value = a_cmap.value(uint32(valn)-1);
3397     }
3398 
3399    {text_style& style = m_cmap_axis.labels_style();
3400     style.x_orientation = vec3f(0,-1,0);
3401     style.y_orientation = vec3f(1,0,0);
3402     style.hjust = left;
3403     style.vjust = middle;}
3404 
3405    {text_style& style = m_cmap_axis.mag_style();
3406     style.hjust = center;
3407     style.vjust = bottom;}
3408 
3409     }//end axis
3410   }
3411 
3412   void update_primitives(std::ostream& a_out) {
3413       m_primitives_sep.clear();
3414       tools_vforcit(plotprim*,m_primitives,it) {
3415         if(plottable_text* ptext = safe_cast<plotprim,plottable_text>(*(*it))) {
3416           update_primitive_text(*ptext);
3417         } else if(plottable_box* pbox = safe_cast<plotprim,plottable_box>(*(*it))) {
3418           update_primitive_box(a_out,*pbox);
3419         } else if(plottable_ellipse* pellipse = safe_cast<plotprim,plottable_ellipse>(*(*it))) {
3420           update_primitive_ellipse(a_out,*pellipse);
3421         } else if(plottable_img* pimg = safe_cast<plotprim,plottable_img>(*(*it))) {
3422           update_primitive_img(a_out,*pimg);
3423         }
3424       }
3425   }
3426 
3427 protected: //vis bins
3428   void update_bins1D_xy(std::ostream& a_out,
3429                         const bins1D& a_bins,
3430                         const style& a_data_style,
3431                         const style& a_left_hatch_style,
3432                         const style& a_right_hatch_style,
3433                         const style& a_errors_style,
3434                         int a_index,
3435                         bool /*aSuperpose*/,
3436                         const rep_box& a_box_x,
3437                         const rep_box& a_box_y,
3438                         float a_zz){
3439 
3440     float bmin = 0;
3441     float bmax = 0;
3442 
3443     size_t xnbin = a_bins.bins();
3444     std::vector<rep_bin1D> bins(xnbin);
3445    {bool first = true;
3446     for(size_t ibin=0;ibin<xnbin;ibin++) {
3447       float val = a_bins.bin_Sw(int(ibin));
3448       float xx = float(a_bins.bin_lower_edge(int(ibin)));
3449       float xe = float(a_bins.bin_upper_edge(int(ibin)));
3450       bins[ibin] = rep_bin1D(xx,xe,0,val);
3451       if(first) {
3452         first = false;
3453         bmin = val;
3454         bmax = val;
3455       } else {
3456         bmin = min_of<float>(bmin,val);
3457         bmax = max_of<float>(bmax,val);
3458       }
3459     }}
3460 
3461     bool errors_visible = a_errors_style.visible;
3462 
3463     if(a_data_style.visible) {
3464 
3465       painting_policy painting = a_data_style.painting;
3466       if(painting==painting_by_value) {
3467         m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping);
3468       } else if( (painting==painting_grey_scale) ||
3469                  (painting==painting_grey_scale_inverse) ||
3470                  (painting==painting_violet_to_red) ){
3471        {float dbins = bmax-bmin;
3472         if(dbins!=0.0F) {
3473           for(size_t index=0;index<xnbin;index++) bins[index].m_ratio = (a_bins.bin_Sw(int(index))-bmin)/dbins;
3474         }}
3475         if(painting==painting_grey_scale) {
3476           m_bins_cmaps[a_index] = new grey_scale_colormap(bmin,bmax,50);
3477         } else if(painting==painting_grey_scale_inverse) {
3478           m_bins_cmaps[a_index] = new grey_scale_inverse_colormap(bmin,bmax,50);
3479         } else if(painting==painting_violet_to_red) {
3480           m_bins_cmaps[a_index] = new violet_to_red_colormap(bmin,bmax,50);
3481         }
3482       } else {
3483         m_bins_cmaps[a_index] = new const_colormap(a_data_style.color);
3484       }
3485 
3486       if(a_bins.is_profile()) {
3487 
3488         style data_style = a_data_style;
3489         data_style.modeling = modeling_markers();
3490         rep_bins1D_xy_points(a_out,data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz);
3491 
3492         std::vector<float> bars(xnbin);
3493         for(size_t ibin=0;ibin<xnbin;ibin++) bars[ibin] = a_bins.bin_error(int(ibin));
3494 
3495         rep_errors_plus_xy(a_out,a_data_style,bins,a_box_x,a_box_y,bars,a_zz+_zerrors());
3496         errors_visible = false;
3497 
3498       } else {
3499 
3500         const std::string& modeling = a_data_style.modeling;
3501 
3502         bool _bar_chart = false;
3503 
3504         if((modeling==modeling_points())||(modeling==modeling_markers())){
3505             rep_bins1D_xy_points(a_out,a_data_style,
3506                                  *(m_bins_cmaps[a_index]),
3507                                  bins,a_box_x,a_box_y,a_zz);
3508           //}
3509         } else if(modeling==modeling_boxes()) {
3510             rep_bins1D_xy_boxes(a_data_style,
3511                                 *(m_bins_cmaps[a_index]),
3512                                 bins,a_box_x,a_box_y,a_zz //,std::string(sid_bin)
3513                                 );
3514         } else if(modeling==modeling_wire_boxes()) {
3515             rep_bins1D_xy_wire_boxes(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz,false);
3516         } else if(modeling==modeling_bar_chart()) {
3517            _bar_chart = true;
3518             rep_bins1D_xy_wire_boxes(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz,true);
3519         } else if(modeling==modeling_lines()){
3520           rep_bins1D_xy_lines_one(a_data_style,bins,a_box_x,a_box_y,a_zz/*,std::string(sid)*/);
3521         } else if(modeling==modeling_curve()){
3522           rep_bins1D_xy_curve_one(a_out,a_data_style,bins,a_box_x,a_box_y,a_zz/*,std::string(sid)*/);
3523 
3524         } else if(modeling==modeling_top_lines_boxes()) { //gopaw. pawex24, k_plus.
3525           style _style;_style.color = colorf_white();
3526           rep_bins1D_xy_boxes(_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz);
3527           rep_bins1D_xy_top_lines(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz+_zhatch());
3528 
3529         } else { //default modeling==modeling_top_lines()
3530           rep_bins1D_xy_top_lines(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz/*,std::string(sid_bin)*/);
3531 
3532         }
3533 
3534         hatching_policy hatching = a_data_style.hatching.value();
3535         if(hatching!=hatching_none) {
3536           // WARNING : must come AFTER rep_bins1_xy.
3537           if((hatching==hatching_right)||((hatching==hatching_left_and_right))) {
3538               rep_hatch1D_xy(a_right_hatch_style,bins,a_box_x,a_box_y,a_zz+_zhatch(),_bar_chart);
3539           }
3540           if((hatching==hatching_left)||((hatching==hatching_left_and_right))) {
3541               rep_hatch1D_xy(a_left_hatch_style,bins,a_box_x,a_box_y,a_zz+_zhatch(),_bar_chart);
3542           }
3543         }
3544 
3545       } //end !is_profile.
3546     } //end data_style visible
3547 
3548     // Errors :
3549     if(errors_visible) {
3550       std::vector<float> bars(xnbin);
3551       for(size_t ibin=0;ibin<xnbin;ibin++) bars[ibin] = a_bins.bin_error(int(ibin));
3552       const std::string& modeling = a_errors_style.modeling;
3553       if(modeling==modeling_plus()) {
3554         rep_errors_plus_xy(a_out,a_errors_style,bins,a_box_x,a_box_y,bars,a_zz+_zerrors());
3555       } else { //modeling_I()
3556         rep_errors_I_xy(a_out,a_errors_style,bins,a_box_x,a_box_y,bars,a_zz+_zerrors());
3557       }
3558     }
3559 
3560   }
3561 
3562   static bool bins2D_to_func(const bins2D& a_bins,float a_X,float a_Y,float& a_value){
3563     unsigned int xn = a_bins.x_bins();
3564     float xmn = a_bins.x_axis_min();
3565     float xmx = a_bins.x_axis_max();
3566     unsigned int yn = a_bins.y_bins();
3567     float ymn = a_bins.y_axis_min();
3568     float ymx = a_bins.y_axis_max();
3569 
3570     float dx = (xmx-xmn)/xn;
3571     float dy = (ymx-ymn)/yn;
3572     int ibin = (int)((a_X-xmn)/dx);
3573     int jbin = (int)((a_Y-ymn)/dy);
3574 
3575     if((ibin<0)||(ibin>=int(xn))) {a_value=0;return false;}
3576     if((jbin<0)||(jbin>=int(yn))) {a_value=0;return false;}
3577 
3578     float xx_0 = a_bins.bin_lower_edge_x(ibin);
3579     float xx_1 = a_bins.bin_lower_edge_x(ibin+1);
3580 
3581     float yy_0 = a_bins.bin_lower_edge_y(jbin);
3582     float yy_1 = a_bins.bin_lower_edge_y(jbin+1);
3583 
3584     float val1 = a_bins.bin_Sw(ibin,jbin);
3585     float val2 = a_bins.bin_Sw(ibin+1,jbin);
3586     float val4 = a_bins.bin_Sw(ibin,jbin+1);
3587 
3588     // Interpolate :
3589     vec3f p1(xx_0,yy_0,val1);
3590     vec3f p2(xx_1,yy_0,val2);
3591     vec3f p4(xx_0,yy_1,val4);
3592 
3593     //FIXME : case of (x,y) in (p2,p3,p4)
3594 
3595     plane<vec3f> _plane(p1,p2,p4);
3596     vec3f pt;
3597     line<vec3f> _line(vec3f(a_X,a_Y,0),vec3f(a_X,a_Y,10));
3598     _plane.intersect(_line,pt);
3599 
3600     a_value = pt[2];
3601     return true;
3602   }
3603 
3604   typedef struct {
3605     const func2D* m_func2D;
3606     const bins2D* m_bins2D;
3607     double m_limits[4];
3608     double m_limits_in[4];
3609     bool m_problem;
3610   } SbFunc;
3611 
3612   static double bins2D_to_contour(double a_X,double a_Y,void* aData) {
3613     SbFunc* func =(SbFunc*)aData;
3614     if( (a_X<func->m_limits_in[0])||
3615         (a_X>func->m_limits_in[1])||
3616         (a_Y<func->m_limits_in[2])||
3617         (a_Y>func->m_limits_in[3])
3618       ) return -FLT_MAX;
3619     float value;
3620     if(!bins2D_to_func(*(func->m_bins2D),(float)a_X,(float)a_Y,value)) func->m_problem = true;
3621     return value;
3622   }
3623 
3624   static double log_bins2D_to_contour(double a_X,double a_Y,void* aData) {
3625     SbFunc* func =(SbFunc*)aData;
3626     if( (a_X<func->m_limits_in[0])||
3627         (a_X>func->m_limits_in[1])||
3628         (a_Y<func->m_limits_in[2])||
3629         (a_Y>func->m_limits_in[3])
3630       ) return -FLT_MAX;
3631     float value;
3632     if(!bins2D_to_func(*(func->m_bins2D),(float)a_X,(float)a_Y,value)) func->m_problem = true;
3633     return take_log(value);
3634   }
3635 
3636   void update_bins2D_xy(std::ostream& a_out,
3637                         const bins2D& a_bins,
3638                         const style& a_data_style,
3639                         int a_index,
3640                         const rep_box& a_box_x,
3641                         const rep_box& a_box_y,
3642                         const rep_box& a_box_z,
3643                         float a_zz){
3644 
3645     if(!a_data_style.visible) return;
3646 
3647     unsigned int xnbin = a_bins.x_bins();
3648     unsigned int ynbin = a_bins.y_bins();
3649 
3650     const std::string& modeling = a_data_style.modeling;
3651 
3652     if( (modeling==modeling_curve()) || (modeling==modeling_filled_curve()) ){
3653 
3654       a_out << "tools::sg::update_bins2D_xy : modeling_curve :" << std::endl;
3655 
3656       painting_policy painting = a_data_style.painting;
3657 
3658       float zmin = a_box_z.m_pos;
3659       float dz = a_box_z.m_width;
3660       bool zlog = a_box_z.m_log;
3661 
3662       float xmn =  m_x_axis_data.min_value();
3663       float xmx =  m_x_axis_data.max_value();
3664       float ymn =  m_y_axis_data.min_value();
3665       float ymx =  m_y_axis_data.max_value();
3666 
3667       clist_contour list_contour;
3668       int nFir = 128;
3669       list_contour.set_first_grid(nFir,nFir); //Default : 32,32
3670       int nSec = 512; //slower than 256
3671       list_contour.set_secondary_grid(nSec,nSec); //Default : 256,256.
3672 
3673       double limits[4];
3674       // User limits :
3675       limits[0] = xmn;
3676       limits[1] = xmx;
3677       limits[2] = ymn;
3678       limits[3] = ymx;
3679 
3680       SbFunc sbFunc;
3681       sbFunc.m_func2D = 0;
3682       sbFunc.m_problem = false;
3683       sbFunc.m_bins2D = &a_bins;
3684       sbFunc.m_limits_in[0] = limits[0];
3685       sbFunc.m_limits_in[1] = limits[1];
3686       sbFunc.m_limits_in[2] = limits[2];
3687       sbFunc.m_limits_in[3] = limits[3];
3688 
3689       // Extend the grid to have some borders in order to close contours :
3690       int n = nSec - 2 * 10;
3691       double dx = (limits[1]-limits[0]) /n;
3692       double dy = (limits[3]-limits[2]) /n;
3693       limits[0] = limits[0] - 10 * dx;
3694       limits[1] = limits[1] + 10 * dx;
3695       limits[2] = limits[2] - 10 * dy;
3696       limits[3] = limits[3] + 10 * dy;
3697 
3698       sbFunc.m_limits[0] = limits[0];
3699       sbFunc.m_limits[1] = limits[1];
3700       sbFunc.m_limits[2] = limits[2];
3701       sbFunc.m_limits[3] = limits[3];
3702 
3703       list_contour.set_limits(limits);
3704 
3705       if(levels.size()) {
3706         size_t zn = levels.size();
3707         std::vector<double> zs(zn);
3708         for(size_t zi=0;zi<zn;zi++) zs[zi] = levels[zi];
3709         list_contour.set_planes(zs);
3710       } else {
3711         unsigned int zn = number_of_levels.value();
3712         if(zn<=0) zn = 1;
3713         std::vector<double> zs(zn+1);
3714         float zmax = zmin + dz;
3715         double zd = (zmax-zmin)/zn;
3716         for(unsigned int zi=0;zi<=zn;zi++) zs[zi] = zmin + zi * zd;
3717         list_contour.set_planes(zs);
3718       }
3719 
3720       if(zlog)
3721         list_contour.set_field_fcn(log_bins2D_to_contour,(void*)&sbFunc);
3722       else
3723         list_contour.set_field_fcn(bins2D_to_contour,(void*)&sbFunc);
3724 
3725       list_contour.ccontour::generate();
3726 
3727       if(!list_contour.compact_strips ()) {
3728         a_out << "tools::sg::plotter::updateBins2D_XY : clist_contour::compact_strips () : failure." << std::endl;
3729       } else {
3730         if( (painting==painting_by_level) || (painting==painting_by_value) ){
3731           m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping);
3732           if(zlog) m_bins_cmaps[a_index]->set_PAW_coloring();
3733         } else {
3734           m_bins_cmaps[a_index] = new const_colormap(a_data_style.color);
3735         }
3736 
3737         if(modeling==modeling_filled_curve()) {
3738           rep_contour_xy_filled(a_out,a_data_style,
3739                                 painting,*(m_bins_cmaps[a_index]),
3740                                 list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/);
3741         } else {
3742           rep_contour_xy(a_out,a_data_style,
3743                          painting,*(m_bins_cmaps[a_index]),
3744                          list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/);
3745         }
3746 
3747       }
3748 
3749       if(sbFunc.m_problem) {
3750         a_out << "tools::sg::plotter::updateFunction_XY(SbPlottableFunction2D) : "
3751               << "problem when getting some function value." << std::endl;
3752       }
3753 
3754     } else {
3755 
3756       bool hbe = a_bins.has_entries_per_bin();
3757 
3758       float bmin = 0;
3759       float bmax = 0;
3760 
3761       std::vector<rep_bin2D> bins;
3762      {bool first = true;
3763       for(int jbin=ynbin-1;jbin>=0;jbin--) {
3764         for(int ibin=xnbin-1;ibin>=0;ibin--) {
3765           if(hbe && (a_bins.bin_entries(ibin,jbin)<=0)) continue;
3766 
3767           float val = a_bins.bin_Sw(ibin,jbin);
3768 
3769           float xx = a_bins.bin_lower_edge_x(ibin);
3770           float xe = a_bins.bin_upper_edge_x(ibin);
3771           float yy = a_bins.bin_lower_edge_y(jbin);
3772           float ye = a_bins.bin_upper_edge_y(jbin);
3773 
3774           bins.push_back(rep_bin2D(xx,xe,yy,ye,val,ibin,jbin));
3775 
3776           if(first) {
3777             first = false;
3778             bmin = val;
3779             bmax = val;
3780           } else {
3781             bmin = min_of<float>(bmin,val);
3782             bmax = max_of<float>(bmax,val);
3783           }
3784         }
3785       }}
3786       size_t number = bins.size();
3787 
3788       painting_policy painting = a_data_style.painting;
3789       if(painting==painting_by_value) {
3790         m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping);
3791       } else if( (painting==painting_grey_scale) ||
3792                  (painting==painting_grey_scale_inverse) ||
3793                  (painting==painting_violet_to_red) ){
3794        {float dbins = bmax-bmin;
3795         if(dbins!=0.0F) {
3796           for(size_t index=0;index<number;index++) {
3797             bins[index].m_ratio = (bins[index].m_val-bmin)/dbins;
3798           }
3799         }}
3800         if(painting==painting_grey_scale) {
3801           m_bins_cmaps[a_index] = new grey_scale_colormap(bmin,bmax,50);
3802         } else if(painting==painting_grey_scale_inverse) {
3803           m_bins_cmaps[a_index] = new grey_scale_inverse_colormap(bmin,bmax,50);
3804         } else if(painting==painting_violet_to_red) {
3805           m_bins_cmaps[a_index] = new violet_to_red_colormap(bmin,bmax,50);
3806         }
3807       } else {
3808         m_bins_cmaps[a_index] = new const_colormap(a_data_style.color);
3809       }
3810 
3811       if(modeling==modeling_solid()) {
3812         rep_bins2D_xy_solid(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz);
3813 
3814       } else if(modeling==modeling_points()) {
3815         rep_bins2D_xy_random_one(a_data_style,bins,a_box_x,a_box_y,bmin,bmax,a_zz/*,std::string(sid)*/);
3816 
3817       } else if(modeling==modeling_wire_boxes()) {
3818           rep_bins2D_xy_wire_box(a_data_style,bins,a_box_x,a_box_y,bmin,bmax,a_zz/*,std::string(sid_bin)*/);
3819       } else if(modeling==modeling_texts()) {
3820           rep_bins2D_xy_text(a_data_style,bins,a_box_x,a_box_y/*,std::string(sid_bin)*/);
3821 
3822       } else { //default rep modeling==modeling_boxes()
3823         rep_bins2D_xy_box(a_data_style,bins,a_box_x,a_box_y,bmin,bmax,a_zz);
3824 
3825       }
3826 
3827 
3828     } //end if modeling
3829 
3830   }
3831 
3832   void update_func1D_xy(std::ostream& a_out,const func1D& a_func,
3833                         const style& a_style,const rep_box& a_box_x,const rep_box& a_box_y,float a_zz){
3834 
3835     if(!a_style.visible) return;
3836 
3837     float xmn = m_x_axis_data.min_value();
3838     float xmx = m_x_axis_data.max_value();
3839 
3840     unsigned int nstp = a_func.x_steps();
3841     nstp = nstp <=0 ? curve_number_of_points.value() : nstp;
3842 
3843     float df = (xmx - xmn)/nstp;
3844 
3845     bool problem = false;
3846     std::vector<vec3f> points(nstp+1);
3847     for(unsigned int ibin=0;ibin<=nstp;ibin++) {
3848       float xx = xmn + ibin * df;
3849       float val;
3850       if(!a_func.value(xx,val)) problem = true;
3851       points[ibin].set_value(xx,val,a_zz);
3852     }
3853     if(problem) {
3854       a_out << "tools::sg::plotter::update_func1D_xy :"
3855             << " problem when getting some function value."
3856             << std::endl;
3857     }
3858 
3859     const std::string& modeling = a_style.modeling;
3860 
3861     if(modeling==modeling_points()){
3862       vertices* vtxs = new vertices;
3863       std::vector<float>& pts = vtxs->xyzs.values(); //npt*3
3864       clip_points_2D(points,a_box_x,a_box_y,pts);
3865       if(pts.size()) {
3866         separator* sep = new separator;
3867         m_func_sep.add(sep);
3868 
3869         rgba* mat = new rgba();
3870         mat->color = a_style.color;
3871         sep->add(mat);
3872 
3873         draw_style* ds = new draw_style;
3874         ds->style = draw_points;
3875         ds->point_size = a_style.point_size;
3876         sep->add(ds);
3877 
3878         vtxs->mode = gl::points();
3879         sep->add(vtxs);
3880       } else {
3881         delete vtxs;
3882       }
3883 
3884     } else if(modeling==modeling_markers()){
3885       markers* _marks = new markers;
3886       std::vector<float>& pts = _marks->xyzs.values(); //npt*3
3887       clip_points_2D(points,a_box_x,a_box_y,pts);
3888       if(pts.size()) {
3889         separator* sep = new separator;
3890         m_func_sep.add(sep);
3891 
3892         rgba* mat = new rgba();
3893         mat->color = a_style.color;
3894         sep->add(mat);
3895 
3896         _marks->size = a_style.marker_size;
3897         _marks->style = a_style.marker_style;
3898         sep->add(_marks);
3899       } else {
3900         delete _marks;
3901       }
3902 
3903     } else {
3904 
3905       vertices* vtxs = new vertices;
3906       std::vector<float>& pts = vtxs->xyzs.values(); //npt*3
3907 
3908       clip_polyline_2D(points,a_box_x,a_box_y,pts);
3909       if(pts.size()) {
3910         separator* sep = new separator;
3911         m_func_sep.add(sep);
3912 
3913         rgba* mat = new rgba();
3914         mat->color = a_style.color;
3915         sep->add(mat);
3916 
3917         draw_style* ds = new draw_style;
3918         ds->style = draw_lines;
3919         ds->line_pattern = a_style.line_pattern;
3920         ds->line_width = a_style.line_width;
3921         sep->add(ds);
3922 
3923         vtxs->mode = gl::line_strip();
3924         sep->add(vtxs);
3925       } else {
3926         delete vtxs;
3927       }
3928     }
3929   }
3930 
3931   static double function_to_contour(double a_X,double a_Y,void* aData) {
3932     SbFunc* func = (SbFunc*)aData;
3933     if( (a_X<func->m_limits_in[0])||
3934         (a_X>func->m_limits_in[1])||
3935         (a_Y<func->m_limits_in[2])||
3936         (a_Y>func->m_limits_in[3])
3937       ) return -FLT_MAX;
3938     float value;
3939     if(!func->m_func2D->value((float)a_X,(float)a_Y,value)) func->m_problem = true;
3940     return double(value);
3941   }
3942   static double log_function_to_contour(double a_X,double a_Y,void* aData) {
3943     SbFunc* func =(SbFunc*)aData;
3944     if( (a_X<func->m_limits_in[0])||
3945         (a_X>func->m_limits_in[1])||
3946         (a_Y<func->m_limits_in[2])||
3947         (a_Y>func->m_limits_in[3])
3948       ) return -FLT_MAX;
3949     float value;
3950     if(!func->m_func2D->value((float)a_X,(float)a_Y,value)) func->m_problem = true;
3951     return take_log(value);
3952   }
3953 
3954   void update_func2D_xy(std::ostream& a_out,const func2D& a_func,int a_index,style& a_data_style,
3955                         const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_zz){
3956     if(!a_data_style.visible.value()) return;
3957     const std::string& modeling = a_data_style.modeling.getValue();
3958     painting_policy painting = a_data_style.painting;
3959 
3960     if( (modeling==modeling_curve()) || (modeling==modeling_filled_curve()) ) {
3961       float zmin = a_box_z.m_pos;
3962       float dz = a_box_z.m_width;
3963       bool zlog = a_box_z.m_log;
3964 
3965       float xmn = m_x_axis_data.min_value();
3966       float xmx = m_x_axis_data.max_value();
3967       float ymn = m_y_axis_data.min_value();
3968       float ymx = m_y_axis_data.max_value();
3969 
3970       clist_contour list_contour;
3971       int nFir = 128;
3972       list_contour.set_first_grid(nFir,nFir); //Default : 32,32
3973       int nSec = 512; //slower than 256
3974       list_contour.set_secondary_grid(nSec,nSec); //Default : 256,256.
3975 
3976       double limits[4];
3977       // User limits :
3978       limits[0] = xmn;
3979       limits[1] = xmx;
3980       limits[2] = ymn;
3981       limits[3] = ymx;
3982 
3983       SbFunc sbFunc;
3984       sbFunc.m_func2D = &a_func;
3985       sbFunc.m_problem = false;
3986       sbFunc.m_bins2D = 0;
3987       sbFunc.m_limits_in[0] = limits[0];
3988       sbFunc.m_limits_in[1] = limits[1];
3989       sbFunc.m_limits_in[2] = limits[2];
3990       sbFunc.m_limits_in[3] = limits[3];
3991 
3992       // Extend the grid to have some borders in order to close contours :
3993       int n = nSec - 2 * 10;
3994       double dx = (limits[1]-limits[0]) /n;
3995       double dy = (limits[3]-limits[2]) /n;
3996       limits[0] = limits[0] - 10 * dx;
3997       limits[1] = limits[1] + 10 * dx;
3998       limits[2] = limits[2] - 10 * dy;
3999       limits[3] = limits[3] + 10 * dy;
4000 
4001       sbFunc.m_limits[0] = limits[0];
4002       sbFunc.m_limits[1] = limits[1];
4003       sbFunc.m_limits[2] = limits[2];
4004       sbFunc.m_limits[3] = limits[3];
4005 
4006       list_contour.set_limits(limits);
4007 
4008       if(levels.getNum()) {
4009         size_t zn = levels.size();
4010         std::vector<double> zs(zn);
4011         for(size_t zi=0;zi<zn;zi++) zs[zi] = levels[zi];
4012         list_contour.set_planes(zs);
4013       } else {
4014         unsigned int zn = number_of_levels;
4015         if(zn<=0) zn = 1;
4016         std::vector<double> zs(zn+1);
4017         float zmax = zmin + dz;
4018         double zd = (zmax-zmin)/zn;
4019         for(unsigned int zi=0;zi<=zn;zi++) zs[zi] = zmin + zi * zd;
4020         list_contour.set_planes(zs);
4021       }
4022 
4023       if(zlog) {
4024         list_contour.set_field_fcn(log_function_to_contour,(void*)&sbFunc);
4025       } else {
4026         list_contour.set_field_fcn(function_to_contour,(void*)&sbFunc);
4027       }
4028 
4029       list_contour.ccontour::generate();
4030 
4031       if(!list_contour.compact_strips ()) {
4032         a_out << "tools::sg::plotter::update_func2D_xy : clist_contour::compact_strips () : failure." << std::endl;
4033       } else {
4034         if( (painting==painting_by_level) || (painting==painting_by_value) ){
4035           m_func_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping.value());
4036           if(zlog) m_func_cmaps[a_index]->set_PAW_coloring();
4037         } else {
4038           m_func_cmaps[a_index] = new const_colormap(a_data_style.color.value());
4039         }
4040 
4041         if(modeling==modeling_filled_curve()) {
4042           rep_contour_xy_filled(a_out,a_data_style,
4043                                 painting,*(m_func_cmaps[a_index]),
4044                                 list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/);
4045         } else {
4046           rep_contour_xy(a_out,a_data_style,
4047                          painting,*(m_func_cmaps[a_index]),
4048                          list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/);
4049         }
4050       }
4051 
4052       if(sbFunc.m_problem) {
4053         a_out << "tools::sg::plotter::update_func2D_xy : problem when getting some function value." << std::endl;
4054       }
4055 
4056     } else {
4057       a_out << "tools::sg::plotter::update_func2D_xy :"
4058             << " modeling " << modeling
4059           << " does not apply on Functi  on2D in XY. Valid modelings ared curve, filled_curve and polygon."
4060           << std::endl;
4061     }
4062 
4063   }
4064 
4065   void update_points2D_xy(std::ostream& a_out,const points2D& a_points,const style& a_style,
4066                           const rep_box& a_box_x,const rep_box& a_box_y,float a_zz) {
4067 
4068     if(!a_style.visible) return;
4069 
4070     size_t number = a_points.points();
4071     if(!number) return;
4072 
4073     const std::string& modeling = a_style.modeling;
4074 
4075     if(modeling==modeling_lines()) {
4076       rep_points2D_xy_lines(a_style,a_points,a_box_x,a_box_y,a_zz);
4077     } else if(modeling==modeling_curve()) {
4078       rep_points2D_xy_curve(a_out,a_style,a_points,a_box_x,a_box_y,a_zz);
4079     } else {
4080       rep_points2D_xy_points(a_out,a_style,a_points,a_box_x,a_box_y,a_zz);
4081     }
4082   }
4083 
4084   void update_points3D_xyz(std::ostream& a_out,const points3D& a_points,const style& a_style,
4085                            const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z) {
4086 
4087     if(!a_style.visible) return;
4088 
4089     size_t number = a_points.points();
4090     if(!number) return;
4091 
4092     rep_points3D_xyz_points(a_out,a_style,a_points,a_box_x,a_box_y,a_box_z);
4093   }
4094 
4095   void get_title(std::string& a_s){
4096     a_s.clear();
4097     bins1D* b1;
4098     bins2D* b2;
4099     func1D* f1;
4100     func2D* f2;
4101     points2D* p2;
4102     points3D* p3;
4103     if(first_bins(b1,b2)) {
4104       if(b1) {
4105         a_s = b1->title();
4106       } else if(b2) {
4107         a_s = b2->title();
4108       }
4109     } else if(first_points(p2,p3)) {
4110       if(p2) {
4111         a_s = p2->title();
4112       } else if(p3) {
4113         a_s = p3->title();
4114       }
4115     } else if(first_func(f1,f2)) {
4116       if(f1) {
4117         a_s = f1->title();
4118       } if(f2) {
4119         a_s = f2->title();
4120       }
4121     }
4122   }
4123 
4124   void update_bins2D_xyz(std::ostream& a_out,const bins2D& a_bins,unsigned int a_index,const style& a_style,
4125                          const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z){
4126     if(!a_style.visible) return;
4127 
4128     unsigned int xnbin = a_bins.x_bins();
4129     unsigned int ynbin = a_bins.y_bins();
4130     if(!xnbin || !ynbin) return;
4131 
4132     const std::string& modeling = a_style.modeling;
4133 
4134     if(modeling==modeling_boxes()) {
4135 
4136       bool hbe = a_bins.has_entries_per_bin();
4137 
4138       float bmin = 0;
4139       float bmax = 0;
4140 
4141       std::vector<rep_bin2D> bins;
4142      {bool first = true;
4143       for(int jbin=ynbin-1;jbin>=0;jbin--) {
4144         for(int ibin=xnbin-1;ibin>=0;ibin--) {
4145           if(hbe && (a_bins.bin_entries(ibin,jbin)<=0)) continue;
4146 
4147           float val = a_bins.bin_Sw(ibin,jbin);
4148 
4149           float xx = a_bins.bin_lower_edge_x(ibin);
4150           float xe = a_bins.bin_upper_edge_x(ibin);
4151           float yy = a_bins.bin_lower_edge_y(jbin);
4152           float ye = a_bins.bin_upper_edge_y(jbin);
4153 
4154           bins.push_back(rep_bin2D(xx,xe,yy,ye,val,ibin,jbin));
4155 
4156           if(first) {
4157             first = false;
4158             bmin = val;
4159             bmax = val;
4160           } else {
4161             bmin = min_of<float>(bmin,val);
4162             bmax = max_of<float>(bmax,val);
4163           }
4164         }
4165       }}
4166       size_t number = bins.size();
4167 
4168       painting_policy painting = a_style.painting;
4169       if(painting==painting_by_value) {
4170         m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping);
4171       } else if( (painting==painting_grey_scale) ||
4172                  (painting==painting_grey_scale_inverse) ||
4173                  (painting==painting_violet_to_red) ){
4174        {float dbins = bmax-bmin;
4175         if(dbins!=0.0F) {
4176           for(size_t index=0;index<number;index++) {
4177             bins[index].m_ratio = (bins[index].m_val-bmin)/dbins;
4178           }
4179         }}
4180         if(painting==painting_grey_scale) {
4181           m_bins_cmaps[a_index] = new grey_scale_colormap(bmin,bmax,50);
4182         } else if(painting==painting_grey_scale_inverse) {
4183           m_bins_cmaps[a_index] = new grey_scale_inverse_colormap(bmin,bmax,50);
4184         } else if(painting==painting_violet_to_red) {
4185           m_bins_cmaps[a_index] = new violet_to_red_colormap(bmin,bmax,50);
4186         }
4187       } else {
4188         m_bins_cmaps[a_index] = new const_colormap(a_style.color);
4189       }
4190 
4191       rep_bins2D_xyz_box(a_style,*m_bins_cmaps[a_index],bins,a_box_x,a_box_y,a_box_z,bmin,bmax);
4192 
4193     } else if(modeling==modeling_curve()){ //gopaw
4194 
4195       float bmin = 0;
4196       float bmax = 0;
4197 
4198       std::vector<rep_top_face2D> faces((xnbin-1)*(ynbin-1));
4199      {bool first = true;
4200       size_t facei = 0;
4201       unsigned int xnbin_1 = xnbin-1;
4202       unsigned int ynbin_1 = ynbin-1;
4203       for(unsigned int jbin=0;jbin<ynbin_1;jbin++) {
4204         for(unsigned int ibin=0;ibin<xnbin_1;ibin++) {
4205 
4206           float xx_0 = a_bins.bin_lower_edge_x(ibin);
4207           float xe_0 = a_bins.bin_upper_edge_x(ibin);
4208           float xx_1 = a_bins.bin_lower_edge_x(ibin+1);
4209           float xe_1 = a_bins.bin_upper_edge_x(ibin+1);
4210 
4211           float yy_0 = a_bins.bin_lower_edge_y(jbin);
4212           float ye_0 = a_bins.bin_upper_edge_y(jbin);
4213           float yy_1 = a_bins.bin_lower_edge_y(jbin+1);
4214           float ye_1 = a_bins.bin_upper_edge_y(jbin+1);
4215 
4216           float xx = (xx_0+xe_0)/2;
4217           float xe = (xx_1+xe_1)/2;
4218           float yy = (yy_0+ye_0)/2;
4219           float ye = (yy_1+ye_1)/2;
4220 
4221           float val1 = a_bins.bin_Sw(ibin,jbin);
4222           float val2 = a_bins.bin_Sw(ibin+1,jbin);
4223           float val3 = a_bins.bin_Sw(ibin+1,jbin+1);
4224           float val4 = a_bins.bin_Sw(ibin,jbin+1);
4225 
4226           faces[facei] = rep_top_face2D(xx,xe,yy,ye,val1,val2,val3,val4);
4227 
4228           if(first) {
4229             first = false;
4230             bmin = val1;
4231             bmax = val1;
4232           } else {
4233             bmin = min_of<float>(bmin,val1);
4234             bmax = max_of<float>(bmax,val1);
4235           }
4236 
4237           facei++;
4238         }
4239       }}
4240 
4241       painting_policy painting = a_style.painting;
4242       if((painting==painting_by_value)||(painting==painting_by_level)) {
4243         m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping);
4244       } else {
4245         m_bins_cmaps[a_index] = new const_colormap(a_style.color);
4246       }
4247 
4248       if(painting==painting_by_level) { //gopaw
4249         rep_top_face2D_xyz_by_level(a_style,painting,*(m_bins_cmaps[a_index]),
4250                                     faces,a_box_x,a_box_y,a_box_z,
4251                                     bmin,bmax/*,SbString(sid.c_str())*/);
4252 
4253       } else {
4254         bool zlog = a_box_z.m_log;
4255         if(zlog) m_func_cmaps[a_index]->set_PAW_coloring();
4256         rep_top_face2D_xyz(m_bins_sep,a_style,*(m_bins_cmaps[a_index]),faces,a_box_x,a_box_y,a_box_z);
4257 
4258         if(a_style.area_style.value()==area_edged) {
4259           style gs;
4260           gs.light_model = light_model_base_color();
4261           gs.line_width = 1;
4262           rep_top_face2D_xyz_line(gs,faces,a_box_x,a_box_y,a_box_z/*,SbString(sid.c_str())*/);
4263         }
4264 
4265         if(painting==painting_uniform) { //gopaw SURF3 (s_SURF_CONT).
4266 
4267           base_colormap* cmap = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping);
4268           if(cmap->colorn()<=0) {
4269             //a_out << "tools::sg::update_bins2D_xyz : bypass rep_contour_xy_filled." << std::endl;
4270             delete cmap;
4271           } else {
4272             float zmin = a_box_z.m_pos;
4273             float dz = a_box_z.m_width;
4274             float xmn =  m_x_axis_data.min_value();
4275             float xmx =  m_x_axis_data.max_value();
4276             float ymn =  m_y_axis_data.min_value();
4277             float ymx =  m_y_axis_data.max_value();
4278 
4279             clist_contour list_contour;
4280             int nFir = 128;
4281             list_contour.set_first_grid(nFir,nFir); //Default : 32,32
4282             int nSec = 512;
4283             list_contour.set_secondary_grid(nSec,nSec); //Default : 256,256.
4284 
4285             double limits[4];
4286             // User limits :
4287             limits[0] = xmn;
4288             limits[1] = xmx;
4289             limits[2] = ymn;
4290             limits[3] = ymx;
4291 
4292             SbFunc sbFunc;
4293             sbFunc.m_func2D = 0;
4294             sbFunc.m_problem = false;
4295             sbFunc.m_bins2D = &a_bins;
4296             sbFunc.m_limits_in[0] = limits[0];
4297             sbFunc.m_limits_in[1] = limits[1];
4298             sbFunc.m_limits_in[2] = limits[2];
4299             sbFunc.m_limits_in[3] = limits[3];
4300 
4301             // Extend the grid to have some borders in order to close contours :
4302             int n = nSec - 2 * 10;
4303             double dx = (limits[1]-limits[0]) /n;
4304             double dy = (limits[3]-limits[2]) /n;
4305             limits[0] = limits[0] - 10 * dx;
4306             limits[1] = limits[1] + 10 * dx;
4307             limits[2] = limits[2] - 10 * dy;
4308             limits[3] = limits[3] + 10 * dy;
4309 
4310             sbFunc.m_limits[0] = limits[0];
4311             sbFunc.m_limits[1] = limits[1];
4312             sbFunc.m_limits[2] = limits[2];
4313             sbFunc.m_limits[3] = limits[3];
4314 
4315             list_contour.set_limits(limits);
4316 
4317             size_t zn = cmap->colorn();
4318             if(zn<=0) zn = 1;
4319 
4320             std::vector<double> zs(zn+1);
4321             float zmax = zmin + dz;
4322             double zd = (zmax-zmin)/zn;
4323             for(size_t zi=0;zi<=zn;zi++) zs[zi] = zmin + zi * zd;
4324             list_contour.set_planes(zs);
4325 
4326             if(zlog) list_contour.set_field_fcn(log_bins2D_to_contour,(void*)&sbFunc);
4327             else     list_contour.set_field_fcn(bins2D_to_contour,(void*)&sbFunc);
4328 
4329             list_contour.ccontour::generate();
4330             if(!list_contour.compact_strips ()) {
4331               a_out << "tools::sg::plotter::update_bins2D_xyz : clist_contour::compact_strips () : failure." << std::endl;
4332               delete cmap;
4333             } else {
4334               delete m_bins_cmaps[a_index];
4335               m_bins_cmaps[a_index] = cmap; //to visualize the cmap.
4336 
4337               matrix* transf = new matrix;
4338               //contour back is at ZZ - 0.01F;
4339               transf->set_translate(0,0,1.02F);
4340               transf->mul_scale(1,1,0.01F); //applied first.
4341               m_bins_sep.add(transf);
4342 
4343               style gs;
4344               gs.light_model = light_model_base_color();
4345               //FIXME gs.transparency = 0.3F;
4346 
4347               float ZZ = 0.0F;
4348 
4349               rep_contour_xy_filled(a_out,gs,painting_by_level,*cmap,list_contour,
4350                                     a_box_x,a_box_y,a_box_z,ZZ/*,SbString(sid.c_str())*/);
4351             }
4352           }
4353 
4354         } //uniform
4355 
4356       }
4357 
4358     } //end if modeling
4359 
4360   }
4361 
4362   void update_func2D_xyz(std::ostream& a_out,
4363                          const func2D& a_func,
4364                          unsigned int a_index,
4365                          const style& a_style,
4366                          const rep_box& a_box_x,
4367                          const rep_box& a_box_y,
4368                          const rep_box& a_box_z){
4369     if(!a_style.visible) return;
4370 
4371     float xmn = m_x_axis_data.min_value();
4372     float xmx = m_x_axis_data.max_value();
4373 
4374     unsigned int nx = a_func.x_steps();
4375     nx = !nx?20:nx;
4376 
4377     float ymn = m_y_axis_data.min_value();
4378     float ymx = m_y_axis_data.max_value();
4379 
4380     unsigned int ny = a_func.y_steps();
4381     ny = !ny?20:ny;
4382 
4383     float dfx = (xmx - xmn)/nx;
4384     float dfy = (ymx - ymn)/ny;
4385 
4386     std::vector<rep_top_face2D> faces(nx*ny);
4387    {bool problem = false;
4388     unsigned int facei = 0;
4389     float* vprev = new float[2*nx];
4390     for(int jbin=ny-1;jbin>=0;jbin--) {
4391       float o1 = 0;
4392       float o4 = 0;
4393       for(int ibin=nx-1;ibin>=0;ibin--) {
4394 
4395         float xx = xmn + ibin * dfx;
4396         float yy = ymn + jbin * dfy;
4397         float xe = xx + dfx;
4398         float ye = yy + dfy;
4399 
4400         // Values at the corner :
4401         float val1;
4402         if(!a_func.value(xx,yy,val1)) problem = true;
4403         float val2;
4404         if(ibin==int(nx-1)) {
4405           if(!a_func.value(xe,yy,val2)) problem = true;
4406         } else {
4407           val2 = o1;
4408         }
4409         float val3,val4;
4410         if(jbin==int(ny-1)) {
4411           if(ibin==int(nx-1)) {
4412             if(!a_func.value(xe,ye,val3)) problem = true;
4413           } else {
4414             val3 = o4;
4415           }
4416           if(!a_func.value(xx,ye,val4)) problem = true;
4417         } else {
4418           val3 = vprev[2*ibin+1];
4419           val4 = vprev[2*ibin];
4420         }
4421         vprev[2*ibin] = val1;
4422         vprev[2*ibin+1] = val2;
4423         o4 = val4;
4424         o1 = val1;
4425 
4426         faces[facei] = rep_top_face2D(xx,xe,yy,ye,val1,val2,val3,val4);
4427         facei++;
4428       }
4429     }
4430     delete [] vprev;
4431     if(problem) {
4432       a_out << "tools::sg::plotter::update_func2D_xyz :"
4433             << " problem when getting some function value."
4434             << std::endl;
4435     }}
4436 
4437     painting_policy painting = a_style.painting;
4438 
4439     if(painting==painting_by_value) {
4440       m_func_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping);
4441 
4442     } else if( (painting==painting_grey_scale) ||
4443                (painting==painting_grey_scale_inverse) ||
4444                (painting==painting_violet_to_red) ){
4445       float vmin = faces[0].m_v1;
4446       float vmax = faces[0].m_v1;
4447       size_t number = faces.size();
4448       for(size_t index=0;index<number;index++) {
4449         float vmean  = faces[index].m_v1;
4450         vmean += faces[index].m_v2;
4451         vmean += faces[index].m_v3;
4452         vmean += faces[index].m_v4;
4453         vmean /= 4.0f;
4454 
4455         vmin = min_of<float>(vmin,vmean);
4456         vmax = max_of<float>(vmax,vmean);
4457 
4458         faces[index].m_ratio = vmean;
4459       }
4460 
4461      {float dbins = vmax-vmin;
4462       if(dbins!=0.0F) {
4463         for(size_t index=0;index<number;index++) {
4464           faces[index].m_ratio = (faces[index].m_ratio-vmin)/dbins;
4465         }
4466       }}
4467 
4468       if(painting==painting_grey_scale) {
4469         m_func_cmaps[a_index] = new grey_scale_colormap(vmin,vmax,50);
4470       } else if(painting==painting_grey_scale_inverse) {
4471         m_func_cmaps[a_index] = new grey_scale_inverse_colormap(vmin,vmax,50);
4472       } else if(painting==painting_violet_to_red) {
4473         m_func_cmaps[a_index] = new violet_to_red_colormap(vmin,vmax,50);
4474       }
4475 
4476     } else {
4477       m_func_cmaps[a_index] = new const_colormap(a_style.color);
4478     }
4479 
4480     {
4481       bool zlog = a_box_z.m_log;
4482       if(zlog) m_func_cmaps[a_index]->set_PAW_coloring();
4483       rep_top_face2D_xyz(m_func_sep,a_style,*(m_func_cmaps[a_index]),faces,a_box_x,a_box_y,a_box_z);
4484     }
4485 
4486     float xmin = a_box_x.m_pos;
4487     float dx = a_box_x.m_width;
4488     bool xlog = a_box_x.m_log;
4489 
4490     float ymin = a_box_y.m_pos;
4491     float dy = a_box_y.m_width;
4492     bool ylog = a_box_y.m_log;
4493 
4494     float zmin = a_box_z.m_pos;
4495     float dz = a_box_z.m_width;
4496     bool zlog = a_box_z.m_log;
4497 
4498    if(func2D_borders_visible.value()) {
4499    // border X (Y=0)
4500 
4501    {separator* sep = new separator;
4502    {normal* nm = new normal;
4503     nm->vec = vec3f(0,-1,0);
4504     sep->add(nm);}
4505    {rgba* mat = new rgba();
4506     mat->color = colorf(0.6f,0.2f,0.2f); //brown
4507     sep->add(mat);}
4508 
4509     vertices* vtxs = new vertices;
4510     vtxs->mode = gl::triangle_fan();
4511     sep->add(vtxs);
4512 
4513     bool empty = true;
4514     bool problem = false;
4515 
4516    {float xx = xmn;
4517     float yy = ymn;
4518     xx = verify_log(xx,xmin,dx,xlog);
4519     yy = verify_log(yy,ymin,dy,ylog);
4520     vtxs->add(xx,yy,0);}
4521 
4522    {float xx = xmx;
4523     float yy = ymn;
4524     xx = verify_log(xx,xmin,dx,xlog);
4525     yy = verify_log(yy,ymin,dy,ylog);
4526     vtxs->add(xx,yy,0);}
4527 
4528    {float val;
4529    {if(!a_func.value(xmx,ymn,val)) problem = true;
4530     val = verify_log(val,zmin,dz,zlog);
4531     if(val<0) val = 0;
4532     if(val>1) val = 1;}
4533    {float xx = xmx;
4534     float yy = ymn;
4535     xx = verify_log(xx,xmin,dx,xlog);
4536     yy = verify_log(yy,ymin,dy,ylog);
4537     vtxs->add(xx,yy,val);}}
4538 
4539     for(int ibin=nx-1;ibin>=0;ibin--) {
4540 
4541       float xx = xmn + ibin * dfx;
4542       float yy = ymn;
4543 
4544       float val;
4545      {if(!a_func.value(xx,yy,val)) problem = true;
4546       val = verify_log(val,zmin,dz,zlog);
4547       if(val<0) val = 0;
4548       if(val>1) val = 1;}
4549 
4550       xx = verify_log(xx,xmin,dx,xlog);
4551       yy = verify_log(yy,ymin,dy,ylog);
4552 
4553       if((xx>=0)&&(xx<=1) && (yy>=0)&&(yy<=1) ) {
4554 
4555         vtxs->add(xx,yy,val);
4556 
4557         empty = false;
4558       }
4559     }
4560     if(empty) {
4561       delete sep;
4562     } else {
4563       m_func_sep.add(sep);
4564     }
4565     if(problem) {
4566       a_out << "tools::sg::plotter::update_func2D_xyz :"
4567             << " problem when getting some function value."
4568             << std::endl;
4569     }}
4570 
4571     // border Y (X=0)
4572    {separator* sep = new separator;
4573    {normal* nm = new normal;
4574     nm->vec = vec3f(-1,0,0);
4575     sep->add(nm);}
4576    {rgba* mat = new rgba();
4577     mat->color = colorf(0.6f,0.2f,0.2f); //brown
4578     sep->add(mat);}
4579 
4580     vertices* vtxs = new vertices;
4581     vtxs->mode = gl::triangle_fan();
4582     sep->add(vtxs);
4583 
4584    {float xx = xmn;
4585     float yy = ymx;
4586     xx = verify_log(xx,xmin,dx,xlog);
4587     yy = verify_log(yy,ymin,dy,ylog);
4588     vtxs->add(xx,yy,0);}
4589 
4590    {float xx = xmn;
4591     float yy = ymn;
4592     xx = verify_log(xx,xmin,dx,xlog);
4593     yy = verify_log(yy,ymin,dy,ylog);
4594     vtxs->add(xx,yy,0);}
4595 
4596     bool empty = true;
4597     bool problem = false;
4598 
4599     for(unsigned int jbin=0;jbin<ny;jbin++) {
4600 
4601       float xx = xmn;
4602       float yy = ymn + jbin * dfy;
4603 
4604       float val;
4605      {if(!a_func.value(xx,yy,val)) problem = true;
4606       val = verify_log(val,zmin,dz,zlog);
4607       if(val<0) val = 0;
4608       if(val>1) val = 1;}
4609 
4610       xx = verify_log(xx,xmin,dx,xlog);
4611       yy = verify_log(yy,ymin,dy,ylog);
4612 
4613       if((xx>=0)&&(xx<=1)   &&
4614          (yy>=0)&&(yy<=1)   ){
4615 
4616         vtxs->add(xx,yy,val);
4617 
4618         empty = false;
4619 
4620       }
4621     }
4622 
4623    {float val;
4624    {if(!a_func.value(xmn,ymx,val)) problem = true;
4625     val = verify_log(val,zmin,dz,zlog);
4626     if(val<0) val = 0;
4627     if(val>1) val = 1;}
4628    {float xx = xmn;
4629     float yy = ymx;
4630     xx = verify_log(xx,xmin,dx,xlog);
4631     yy = verify_log(yy,ymin,dy,ylog);
4632     vtxs->add(xx,yy,val);}}
4633     if(empty) {
4634       delete sep;
4635     } else {
4636       m_func_sep.add(sep);
4637     }
4638     if(problem) {
4639       a_out << "tools::sg::plotter::update_func2D_xyz :"
4640             << " problem when getting some function value."
4641             << std::endl;
4642     }}
4643 
4644 
4645     } //func2D_borders_visible
4646 
4647   }
4648 
4649   void update_title(){
4650     if(!m_title_style.visible) return;
4651 
4652     if(m_shape==xyz) return;
4653 
4654     if(title.value().empty()) return;
4655 
4656     // Use the XY layout transform to position the title.
4657     // (Else we would have to compensate the 3D rotation
4658     //  in order to bring the title at the right position
4659     //  without rotation).
4660     //titleNode->addChild(layout);
4661 
4662     rgba* mat = new rgba();
4663     mat->color = m_title_style.color;
4664     m_title_sep.add(mat);
4665 
4666     float text_size = title_height * m_title_style.scale;
4667 
4668     std::string font = m_title_style.font.value();
4669 
4670     if(font==font_hershey()) {
4671       draw_style* ds = new draw_style;
4672       ds->style = draw_lines;
4673       ds->line_pattern = m_title_style.line_pattern;
4674       ds->line_width = m_title_style.line_width;
4675       m_title_sep.add(ds);
4676     } else {
4677       m_title_sep.add(new normal);
4678     }
4679 
4680     float XSIZ = width;
4681     float XMGL = left_margin;
4682     float XMGR = right_margin;
4683     float wData = XSIZ-XMGL-XMGR;
4684 
4685     float YSIZ = height;
4686     float YMGL = bottom_margin;
4687     float YMGU = top_margin;
4688     float hData = YSIZ-YMGL-YMGU;
4689 
4690     float xx = wData/2;
4691     float yy = hData + title_to_axis;
4692 
4693     float zz = _zinfos();
4694 
4695     vjust vjust = bottom;
4696     if(!title_up) {
4697       yy = -title_to_axis;
4698       vjust = top;
4699     }
4700 
4701     vec3f TX(1,0,0);
4702     vec3f TY(0,1,0);
4703     add_string(m_title_sep,
4704                        font,
4705                        m_title_style.font_modeling.value(),
4706                        m_title_style.encoding.value(),
4707                        m_title_style.smoothing,
4708                        title.value(),
4709                        xx,yy,zz, //vec
4710                        TX,TY,
4711                        text_size,
4712                        title_hjust,vjust,
4713                        m_ttf);
4714   }
4715 
4716   void update_title_box(){
4717     if(!m_title_box_style.visible) return;
4718     if(title.value().empty()) return;
4719 
4720     // same plane than infos, then in front of data and grid.
4721     float zz = _zinfos();
4722     if(m_shape==xyz) zz = depth*0.5f;
4723 
4724     float wbox = width*title_box_width;
4725     float hbox = height*title_box_height;
4726 
4727     float xmargin = width*title_box_x_margin;  //from left border
4728     float ymargin = height*title_box_y_margin; //from top border
4729 
4730     matrix* _tsf = new matrix;
4731    {float xx = -width*0.5f+wbox*0.5f+xmargin; //at left.
4732     float yy = height*0.5f-hbox*0.5F-ymargin; //at top.
4733     _tsf->set_translate(xx,yy,zz);
4734     _tsf->mul_scale(1,1,_zscale_text());}
4735     m_title_box_sep.add(_tsf);
4736 
4737     sg::text* title_box = new sg::text(m_ttf);
4738     title_box->width = wbox;
4739     title_box->height = hbox;
4740     title_box->back_area::color = m_title_box_style.back_color;
4741     title_box->color = m_title_box_style.color;
4742     title_box->font = m_title_box_style.font;
4743     title_box->font_modeling = m_title_box_style.font_modeling;
4744     title_box->encoding = m_title_box_style.encoding;
4745     title_box->line_width = m_title_box_style.line_width;
4746     title_box->confine = true;
4747     title_box->back_area::shadow = m_title_box_style.back_shadow;
4748 
4749     title_box->strings.add(title.value());
4750 
4751     m_title_box_sep.add(title_box);
4752   }
4753 
4754   void get_infos(std::string& a_s){
4755     a_s.clear();
4756     const std::string&  opts = infos_what.value();
4757    {bins1D* b1;
4758     bins2D* b2;
4759     func1D* f1;
4760     func2D* f2;
4761     points2D* p2;
4762     points3D* p3;
4763     if(first_bins(b1,b2)) {
4764       if(b1) {
4765         b1->infos(opts,a_s);
4766       } else if(b2) {
4767         b2->infos(opts,a_s);
4768       }
4769     } else if(first_points(p2,p3)) {
4770       if(p2) {
4771         p2->infos(opts,a_s);
4772       } else if(p3) {
4773         p3->infos(opts,a_s);
4774       }
4775     } else if(first_func(f1,f2)) {
4776       if(f1) {
4777         f1->infos(opts,a_s);
4778       } if(f2) {
4779         f2->infos(opts,a_s);
4780       }
4781     }}
4782     //look for fit infos :
4783    {tools_vforcit(plottable*,m_plottables,it) {
4784       plottable* object = *it;
4785       if(!object) continue;
4786       if(object->cast(s_tools_sg_fit2plot())) {
4787         if(a_s.size()) a_s += "\n";
4788         std::string _s;
4789         object->infos(opts,_s);
4790         a_s += _s;
4791       }
4792     }}
4793   }
4794 
4795   matrix* get_infos_matrix() {
4796     if(m_infos_sep.empty()) return 0;
4797     return (matrix*)m_infos_sep[0]; //WARNING.
4798   }
4799   sg::infos_box* get_infos_node() {
4800     if(m_infos_sep.empty()) return 0;
4801     return (sg::infos_box*)m_infos_sep[1]; //WARNING.
4802   }
4803 
4804   void update_infos(std::ostream&){
4805     if(!m_infos_style.visible) return;
4806 
4807     std::string sinfos;
4808     get_infos(sinfos);
4809     std::vector<std::string> ws;
4810     words(sinfos,"\n",false,ws);
4811     size_t linen = ws.size()/2;
4812 
4813     float zz = _zinfos(); //xy
4814     if(m_shape==xyz) zz = depth*0.5f;
4815 
4816     float _height = height;
4817     if(m_shape==xyz) _height = depth;
4818 
4819     float wbox = width*infos_width;
4820 
4821     matrix* infos_title_tsf = 0;
4822     sg::text* infos_title_text = 0;
4823 
4824     std::string infos_title;
4825     if(m_infos_style.modeling==infos_modeling_ROOT()) {
4826       std::vector<std::string> _ws; //to rm "Name".
4827       for(size_t index=0;index<linen;index++) {
4828         const std::string& name = ws[2*index];
4829         const std::string& value = ws[2*index+1];
4830         if(name=="Name") {
4831           infos_title = value;
4832         } else {
4833           _ws.push_back(name);
4834           _ws.push_back(value);
4835         }
4836       }
4837       ws = std::move(_ws);
4838       linen = ws.size()/2;
4839     }
4840 
4841     if(infos_title.size()) {
4842       float hbox = _height*0.05f;
4843 
4844       matrix* _tsf = new matrix;
4845      {float xx = width*0.5f  - wbox*0.5f -  width*infos_x_margin;
4846       float yy = _height*0.5f - hbox*0.5F - _height*infos_y_margin;
4847       _tsf->mul_translate(xx,yy,zz);
4848       _tsf->mul_scale(1,1,_zscale_text());}
4849       //in case of having infos, the tsf is refined below.
4850       m_infos_title_sep.add(_tsf);
4851 
4852       // same params as title_box.
4853       sg::text* txt = new sg::text(m_ttf);
4854       txt->width = wbox;
4855       txt->height = hbox;
4856       txt->back_area::color = m_infos_style.back_color;
4857       txt->color = m_infos_style.color;
4858       txt->font = m_infos_style.font;
4859       txt->font_modeling = m_infos_style.font_modeling;
4860       txt->encoding = m_infos_style.encoding;
4861       txt->line_width = m_infos_style.line_width;
4862       txt->confine = true;
4863       txt->back_area::shadow = m_infos_style.back_shadow;
4864 
4865       txt->hjust = center;
4866 
4867       txt->strings.add(infos_title);
4868       m_infos_title_sep.add(txt);
4869 
4870       // to refine height below.
4871       infos_title_tsf = _tsf;
4872       infos_title_text = txt;
4873     }
4874 
4875     if(sinfos.empty()) return;
4876     if(!linen) return;
4877 
4878     matrix* _tsf = new matrix;
4879     m_infos_sep.add(_tsf);
4880 
4881     sg::infos_box* infos = new sg::infos_box(m_ttf);
4882     infos->width = wbox;
4883     infos->back_area::color = m_infos_style.back_color;
4884     infos->color = m_infos_style.color;
4885     infos->font = m_infos_style.font;
4886     infos->encoding = m_infos_style.encoding;
4887     infos->font_modeling = m_infos_style.font_modeling;
4888     infos->line_width = m_infos_style.line_width;
4889     infos->back_area::shadow = m_infos_style.back_shadow;
4890     infos->border_line_width = m_infos_style.line_width;
4891 
4892    {for(size_t index=0;index<linen;index++) {
4893       const std::string& name = ws[2*index];
4894       const std::string& value = ws[2*index+1];
4895       infos->lstrings.add(name);
4896       infos->rstrings.add(value);
4897     }}
4898 
4899     // enforce an infos::update_sg to get infos::height
4900     // to place the box.
4901     infos->update_sg();
4902 
4903     // if any, set infos_title height :
4904     float title_hbox = 0;
4905     if(infos_title_tsf && infos_title_text) {
4906       title_hbox = infos->height/linen;
4907       float xx = width*0.5f  - wbox*0.5f       - width*infos_x_margin;
4908       float yy = _height*0.5f - title_hbox*0.5F - _height*infos_y_margin;
4909       infos_title_tsf->set_identity();
4910       infos_title_tsf->mul_translate(xx,yy,zz);
4911       infos_title_tsf->mul_scale(1,1,_zscale_text());
4912 
4913       infos_title_text->height = title_hbox;
4914     }
4915 
4916     float hbox = infos->height;
4917    {float xx = width*0.5f  -wbox*0.5f -width*infos_x_margin;
4918     float yy = _height*0.5f -hbox*0.5F - _height*infos_y_margin;
4919     yy -= title_hbox;
4920     _tsf->set_translate(xx,yy,zz);
4921     _tsf->mul_scale(1,1,_zscale_text());}
4922 
4923     m_infos_sep.add(infos);
4924   }
4925 
4926   void update_legends(std::ostream& a_out) {
4927     if(m_legend_strings.empty()) return;
4928     if(m_legend_strings.size()!=legends_origin.size()) return;
4929     if(legends_size.size()!=legends_origin.size()) return;
4930     if(legends_origin_unit.size()!=legends_origin.size()) return;
4931 
4932     float zz = _zinfos();
4933 
4934    {matrix* _tsf = new matrix;
4935     _tsf->mul_scale(1,1,_zscale_text());
4936     m_legend_sep.add(_tsf);}
4937 
4938     size_t number = m_legend_strings.size();
4939     for(size_t index=0;index<number;index++) {
4940       const style& _style = legend_style(index);
4941       if(!_style.visible) continue;
4942 
4943       separator* sep = new separator;
4944       m_legend_sep.add(sep);
4945 
4946       matrix* _tsf = new matrix;
4947       sep->add(_tsf);
4948 
4949       legend* text = new legend(m_ttf);
4950       text->font = _style.font;
4951       text->font_modeling = _style.font_modeling;
4952       text->encoding = _style.encoding;
4953       text->strings.add(m_legend_strings[index]);
4954       text->color = _style.color;
4955       text->marker_style = _style.marker_style;
4956       text->marker_size = _style.marker_size;
4957       text->back_visible = false;
4958       sep->add(text);
4959 
4960       //legends_size is in NDC of [0,width][0,height].
4961       float w = width  * legends_size[index][0];
4962       float h = height * legends_size[index][1];
4963       text->width = w;
4964       text->height = h;
4965 
4966       float xxx = w * 0.5f;
4967       float yyy = h * 0.5f;
4968 
4969       if(legends_origin_unit[index]==unit_axis) {
4970 
4971         // legends_origin is in axes coordinates.
4972         float x = legends_origin[index][0];
4973         float y = legends_origin[index][1];
4974 
4975         vec3f pos;
4976         if(!axis_2_vp(vec3f(x,y,0),pos)) {
4977           a_out << "tools::sg::plotter::update_legends : axis_2_vp() failed for x=" << x << ", y=" << y << "." << std::endl;
4978         } else {
4979           //pos is in NDC of [0,width][0,height].
4980           float xx = width  * (-0.5f+pos[0]);
4981           float yy = height * (-0.5f+pos[1]);
4982           _tsf->set_translate(xx,yy,zz);
4983         }
4984 
4985       } else { //unit_percent
4986         // legends_origin is
4987         // the UR corner of legend region relative
4988         // to UR of plotter region.
4989         float xur = legends_origin[index][0];
4990         float yur = legends_origin[index][1];
4991 
4992         vec2f ur(1-xur,1-yur);
4993 
4994         float x =  width*ur[0] - w;
4995         float y = height*ur[1] - h;
4996 
4997         float xx =  -width*0.5f + x;
4998         float yy = -height*0.5f + y;
4999 
5000         _tsf->set_translate(xx,yy,zz);
5001       }
5002 
5003       _tsf->mul_translate(xxx,yyy,0); //applied first.
5004 
5005     }
5006   }
5007 
5008   void update_background(){
5009     m_background_sep.clear();
5010     if(!m_background_style.visible) return;
5011 
5012     matrix* _tsf = new matrix;
5013     m_background_sep.add(_tsf);
5014 
5015     float w2 = width*0.5F;
5016     float h2 = height*0.5F;
5017 
5018     float zz = 0; //in xy, then before first data plane at _zoffset()
5019     if(m_shape==xyz) zz = -depth*0.5f;
5020 
5021    {rgba* mat = new rgba();
5022     if(m_background_style.line_width) { //there is a border.
5023       mat->color = m_background_style.color; //then border color !
5024     } else {
5025       mat->color = m_background_style.back_color;
5026     }
5027     m_background_sep.add(mat);
5028 
5029     m_background_sep.add(new normal);
5030 
5031     vertices* vtxs = new vertices;
5032     vtxs->mode = gl::triangle_fan();
5033     m_background_sep.add(vtxs);
5034 
5035     vtxs->add(-w2,-h2,zz);
5036     vtxs->add( w2,-h2,zz);
5037     vtxs->add( w2, h2,zz);
5038     vtxs->add(-w2, h2,zz);}
5039 
5040     if(m_background_style.line_width) { //border
5041       //WARNING : line_width should be in percent of width.
5042 
5043       //NOTE : border is done by drawing a front smaller polygon.
5044 
5045       rgba* mat = new rgba();
5046       mat->color = m_background_style.back_color; //yes,yes !
5047       m_background_sep.add(mat);
5048 
5049       vertices* vtxs = new vertices;
5050       vtxs->mode = gl::triangle_fan();
5051       m_background_sep.add(vtxs);
5052 
5053       float d = width*m_background_style.line_width;
5054 
5055       zz += _zoffset()*0.5f;
5056 
5057       vtxs->add(-w2+d,-h2+d,zz);
5058       vtxs->add( w2-d,-h2+d,zz);
5059       vtxs->add( w2-d, h2-d,zz);
5060       vtxs->add(-w2+d, h2-d,zz);
5061     }
5062 
5063   }
5064 
5065   void update_inner_frame_XY(){
5066     if(!m_inner_frame_style.visible) return;
5067 
5068     rgba* mat = new rgba();
5069     mat->color = m_inner_frame_style.color;
5070     m_inner_frame_sep.add(mat);
5071 
5072     draw_style* ds = new draw_style;
5073     ds->style = draw_lines;
5074     ds->line_pattern = m_inner_frame_style.line_pattern;
5075     ds->line_width = m_inner_frame_style.line_width;
5076     m_inner_frame_sep.add(ds);
5077 
5078     vertices* vtxs = new vertices;
5079     vtxs->mode = gl::line_strip();
5080     m_inner_frame_sep.add(vtxs);
5081 
5082     float zz = _zgrid();
5083 
5084     vtxs->add(0,0,zz);
5085     vtxs->add(1,0,zz);
5086     vtxs->add(1,1,zz);
5087     vtxs->add(0,1,zz);
5088     vtxs->add(0,0,zz);
5089   }
5090 
5091   void update_inner_frame_XYZ(){
5092     if(!m_inner_frame_style.visible) return;
5093 
5094     rgba* mat = new rgba();
5095     mat->color = m_inner_frame_style.color;
5096     m_inner_frame_sep.add(mat);
5097 
5098     draw_style* ds = new draw_style;
5099     ds->style = draw_lines;
5100     ds->line_pattern = m_inner_frame_style.line_pattern;
5101     ds->line_width = m_inner_frame_style.line_width;
5102     m_inner_frame_sep.add(ds);
5103 
5104     vertices* ls = new vertices;
5105     ls->mode = gl::lines();
5106     m_inner_frame_sep.add(ls);
5107 
5108     // z bottom :
5109     ls->add(0,0,0);ls->add(1,0,0);
5110     ls->add(1,0,0);ls->add(1,1,0);
5111     ls->add(1,1,0);ls->add(0,1,0);
5112     ls->add(0,1,0);ls->add(0,0,0);
5113 
5114     // z top :
5115     ls->add(0,0,1);ls->add(1,0,1);
5116     ls->add(1,0,1);ls->add(1,1,1);
5117     ls->add(1,1,1);ls->add(0,1,1);
5118     ls->add(0,1,1);ls->add(0,0,1);
5119 
5120     // sides along z :
5121     ls->add(0,0,0);ls->add(0,0,1);
5122     ls->add(1,0,0);ls->add(1,0,1);
5123     ls->add(1,1,0);ls->add(1,1,1);
5124     ls->add(0,1,0);ls->add(0,1,1);
5125   }
5126 
5127   void update_grid_XY(){
5128     if(!m_grid_style.visible) return;
5129 
5130     unsigned int number = m_x_axis.tick_number + m_y_axis.tick_number;
5131     if(number<=0) return;
5132 
5133     bool draw_vertical = true;
5134     bool draw_horizontal = true;
5135     if(m_grid_style.options.value()=="vertical") draw_horizontal = false;
5136     if(m_grid_style.options.value()=="horizontal") draw_vertical = false;
5137 
5138     rgba* mat = new rgba();
5139     mat->color = m_grid_style.color;
5140     m_grid_sep.add(mat);
5141 
5142     draw_style* ds = new draw_style;
5143     ds->style = draw_lines;
5144     ds->line_pattern = line_solid;
5145     ds->line_width = m_grid_style.line_width;
5146     m_grid_sep.add(ds);
5147 
5148     float zz = _zgrid();
5149 
5150     vertices* vtxs = new vertices;
5151     vtxs->mode = gl::lines();
5152     m_grid_sep.add(vtxs);
5153 
5154     std::vector<float>& pts = vtxs->xyzs.values();
5155 
5156     bool is_solid = m_grid_style.line_pattern.value()==line_solid;
5157 
5158     if(draw_vertical) {
5159       float _width = m_y_axis.width;
5160       float xx;
5161      {size_t _number = m_x_axis.coords.size();
5162       if(is_solid) {
5163         pts.reserve(_number*6);
5164         for(size_t count=0;count<_number;count++) {
5165           xx = m_x_axis.coords[count];
5166           vtxs->add(xx, 0    ,zz);
5167           vtxs->add(xx, _width,zz);
5168         }
5169       } else {
5170         pts.reserve(_number*100*6);
5171         for(size_t count=0;count<_number;count++) {
5172           xx = m_x_axis.coords[count];
5173           vtxs->add_dashed_line(xx,0,zz,xx,_width,zz,100);
5174         }
5175       }}
5176       if(m_x_axis.is_log) {
5177         size_t _number = m_x_axis.sub_coords.size();
5178         if(is_solid) {
5179           pts.reserve(_number*6);
5180           for(size_t count=0;count<_number;count++) {
5181             xx = m_x_axis.sub_coords[count];
5182             vtxs->add(xx, 0    ,zz);
5183             vtxs->add(xx,_width,zz);
5184           }
5185         } else {
5186           pts.reserve(_number*100*6);
5187           for(size_t count=0;count<_number;count++) {
5188             xx = m_x_axis.sub_coords[count];
5189             vtxs->add_dashed_line(xx,0,zz,xx,_width,zz,100);
5190           }
5191         }
5192       }
5193     }
5194 
5195     if(draw_horizontal) {
5196       float _width = m_x_axis.width;
5197       float yy;
5198      {size_t _number = m_y_axis.coords.size();
5199       if(is_solid) {
5200         pts.reserve(_number*6);
5201         for(size_t count=0;count<_number;count++) {
5202           yy = m_y_axis.coords[count];
5203           vtxs->add(0,yy    ,zz);
5204           vtxs->add(_width,yy,zz);
5205         }
5206       } else {
5207         pts.reserve(_number*100*6);
5208         for(size_t count=0;count<_number;count++) {
5209           yy = m_y_axis.coords[count];
5210           vtxs->add_dashed_line(0,yy,zz,_width,yy,zz,100);
5211         }
5212       }}
5213       if(m_y_axis.is_log) {
5214         size_t _number = m_y_axis.sub_coords.size();
5215         if(is_solid) {
5216           pts.reserve(_number*6);
5217           for(size_t count=0;count<_number;count++) {
5218             yy = m_y_axis.sub_coords[count];
5219             vtxs->add(0,yy,    zz);
5220             vtxs->add(_width,yy,zz);
5221           }
5222         } else {
5223           pts.reserve(_number*100*6);
5224           for(size_t count=0;count<_number;count++) {
5225             yy = m_y_axis.sub_coords[count];
5226             vtxs->add_dashed_line(0,yy,zz,_width,yy,zz,100);
5227           }
5228         }
5229       }
5230     }
5231 
5232   }
5233 
5234   void update_grid_XYZ(){
5235     if(!m_grid_style.visible) return;
5236 
5237     rgba* mat = new rgba();
5238     mat->color = m_grid_style.color;
5239     m_grid_sep.add(mat);
5240 
5241     draw_style* ds = new draw_style;
5242     ds->style = draw_lines;
5243     ds->line_pattern = m_grid_style.line_pattern;
5244     ds->line_width = m_grid_style.line_width;
5245     m_grid_sep.add(ds);
5246 
5247   }
5248 
5249 protected: //rep
5250   ////////////////////////////////////////////////////////////////////////////
5251   // reps xy /////////////////////////////////////////////////////////////////
5252   ////////////////////////////////////////////////////////////////////////////
5253   void rep_bins1D_xy_top_lines(const style& a_style,
5254                                const base_colormap& a_cmap,
5255                                const std::vector<rep_bin1D>& a_bins,
5256                                const rep_box& a_box_x,
5257                                const rep_box& a_box_y,
5258                                float a_zz/*,
5259                                const std::string& aID*/){
5260     painting_policy painting = a_style.painting;
5261 
5262     float xmin = a_box_x.m_pos;
5263     float dx = a_box_x.m_width;
5264     bool xlog = a_box_x.m_log;
5265 
5266     float ymin = a_box_y.m_pos;
5267     float dy = a_box_y.m_width;
5268     bool ylog = a_box_y.m_log;
5269 
5270     float y0 = 0;
5271     y0 = verify_log(y0,ymin,dy,ylog);
5272     if(y0<0) y0 = 0;
5273     if(y0>1) y0 = 1;
5274 
5275     separator* _sep = new separator();
5276 
5277     draw_style* ds = new draw_style;
5278     ds->style = draw_lines;
5279     ds->line_pattern = a_style.line_pattern;
5280     ds->line_width = a_style.line_width;
5281     _sep->add(ds);
5282 
5283     bool empty = true;
5284     colorf clr;
5285 
5286     float yp = 0;
5287     size_t xnbin = a_bins.size();
5288     for(size_t index=0;index<xnbin;index++) {
5289       float xx = a_bins[index].m_x_min;
5290       float xe = a_bins[index].m_x_max;
5291       float y = a_bins[index].m_val;
5292 
5293       float val = a_bins[index].m_val;
5294 
5295       xx = verify_log(xx,xmin,dx,xlog);
5296       xe = verify_log(xe,xmin,dx,xlog);
5297       y = verify_log(y,ymin,dy,ylog);
5298 
5299       // Clipping :
5300       if(xe<0) continue;
5301       if(xx>1) continue;
5302       if(xx<0) xx = 0;
5303       if(xe>1) xe = 1;
5304       if(y<0) y = 0;
5305       if(y>1) y = 1;
5306 
5307       separator* sep = new separator();
5308       _sep->add(sep);
5309 
5310       if(painting==painting_by_value) {
5311         a_cmap.get_color(val,clr);
5312       } else if( (painting==painting_grey_scale) ||
5313                  (painting==painting_grey_scale_inverse) ||
5314                  (painting==painting_violet_to_red) ){
5315         a_cmap.get_color(a_bins[index].m_ratio,clr);
5316       } else {
5317         clr = a_style.color;
5318       }
5319 
5320       rgba* mat = new rgba();
5321       mat->color = clr;
5322       sep->add(mat);
5323 
5324       vertices* vtxs = new vertices;
5325       vtxs->mode = gl::line_strip();
5326       sep->add(vtxs);
5327 
5328       vtxs->add(xx,yp,a_zz);
5329       vtxs->add(xx,y,a_zz);
5330       vtxs->add(xe,y,a_zz);
5331       if(index==xnbin-1){
5332         vtxs->add(xe,y0,a_zz);
5333       }
5334 
5335       empty = false;
5336       yp = y;
5337     }
5338 
5339     if(empty) {
5340       delete _sep;
5341     } else {
5342       m_bins_sep.add(_sep);
5343     }
5344   }
5345 
5346   void rep_bins1D_xy_points(std::ostream& a_out,
5347                             const style& a_style,
5348                             const base_colormap& a_cmap,
5349                             const std::vector<rep_bin1D>& a_bins,
5350                             const rep_box& a_box_x,
5351                             const rep_box& a_box_y,
5352                             float a_zz/*,
5353                             const std::string& aID*/){
5354     float xmin = a_box_x.m_pos;
5355     float dx = a_box_x.m_width;
5356     bool xlog = a_box_x.m_log;
5357 
5358     float ymin = a_box_y.m_pos;
5359     float dy = a_box_y.m_width;
5360     bool ylog = a_box_y.m_log;
5361 
5362     painting_policy painting = a_style.painting;
5363 
5364     separator* _sep = new separator();
5365 
5366     if(a_style.modeling==modeling_points()) {
5367       draw_style* ds = new draw_style;
5368       ds->style = draw_points;
5369       ds->point_size = a_style.point_size;
5370       _sep->add(ds);
5371     }
5372 
5373     bool empty = true;
5374     colorf clr;
5375     size_t xnbin = a_bins.size();
5376     for(size_t index=0;index<xnbin;index++) {
5377       float x = (a_bins[index].m_x_min + a_bins[index].m_x_max)/2;
5378       float y = a_bins[index].m_val;
5379       float val = a_bins[index].m_val;
5380 
5381       x = verify_log(x,xmin,dx,xlog);
5382       y = verify_log(y,ymin,dy,ylog);
5383 
5384       if((x<0)||(x>1)||(y<0)||(y>1)) continue;
5385 
5386       separator* sep = new separator();
5387       _sep->add(sep);
5388 
5389       if(painting==painting_by_value) {
5390         a_cmap.get_color(val,clr);
5391       } else if( (painting==painting_grey_scale) ||
5392                  (painting==painting_grey_scale_inverse) ||
5393                  (painting==painting_violet_to_red) ){
5394         a_cmap.get_color(a_bins[index].m_ratio,clr);
5395       } else {
5396         clr = a_style.color;
5397       }
5398 
5399       rgba* mat = new rgba();
5400       mat->color = clr;
5401       sep->add(mat);
5402 
5403       if(a_style.modeling==modeling_points()) {
5404         vertices* vtxs = new vertices;
5405         vtxs->mode = gl::points();
5406         vtxs->add(x,y,a_zz);
5407         sep->add(vtxs);
5408       } else if(a_style.modeling==modeling_markers()) {
5409         markers* _marks = new markers;
5410         _marks->size = a_style.marker_size;
5411         _marks->style = a_style.marker_style;
5412         _marks->add(x,y,a_zz);
5413         sep->add(_marks);
5414       } else {
5415         a_out << "tools::sg::plotter::rep_bins1D_xy_points :"
5416               << " bad modeling style " << tools::sout(a_style.modeling) << std::endl;
5417         delete _sep;
5418         return;
5419       }
5420 
5421       empty = false;
5422     }
5423 
5424     if(empty) {
5425       delete _sep;
5426     } else {
5427       m_bins_sep.add(_sep);
5428     }
5429   }
5430 
5431   void rep_bins1D_xy_boxes(const style& a_style,
5432                            const base_colormap& a_cmap,
5433                            const std::vector<rep_bin1D>& a_bins,
5434                            const rep_box& a_box_x,
5435                            const rep_box& a_box_y,
5436                            float a_zz //,const std::string& aID
5437                                ){
5438     painting_policy painting = a_style.painting;
5439 
5440     float xmin = a_box_x.m_pos;
5441     float dx = a_box_x.m_width;
5442     bool xlog = a_box_x.m_log;
5443 
5444     float ymin = a_box_y.m_pos;
5445     float dy = a_box_y.m_width;
5446     bool ylog = a_box_y.m_log;
5447 
5448     separator* _sep = new separator();
5449 
5450     _sep->add(new normal);
5451 
5452     bool empty = true;
5453     colorf clr;
5454 
5455     tools_vforcit(rep_bin1D,a_bins,it) {
5456       const rep_bin1D& rbin = *it;
5457 
5458       float xx = rbin.m_x_min;
5459       float xe = rbin.m_x_max;
5460       float yy = rbin.m_v_min;
5461       float ye = rbin.m_val;
5462       if(ye<yy) {
5463         yy = rbin.m_val;
5464         ye = rbin.m_v_min;
5465       }
5466 
5467       float val = rbin.m_val;
5468 
5469       xx = verify_log(xx,xmin,dx,xlog);
5470       xe = verify_log(xe,xmin,dx,xlog);
5471       yy = verify_log(yy,ymin,dy,ylog);
5472       ye = verify_log(ye,ymin,dy,ylog);
5473 
5474       // Clipping :
5475       if(xx>1) continue;
5476       if(xe<0) continue;
5477       if(xx<0) xx = 0;
5478       if(xe>1) xe = 1;
5479       if(yy>1) continue;
5480       if(ye<0) continue;
5481       if(yy<0) yy = 0;
5482       if(ye>1) ye = 1;
5483 
5484       //FIXME if(ye<=yy) continue; //Else we shall have a tessellation error.
5485 
5486       separator* sep = new separator();
5487       _sep->add(sep);
5488 
5489       if(painting==painting_by_value) {
5490         a_cmap.get_color(val,clr);
5491       } else if( (painting==painting_grey_scale) ||
5492                  (painting==painting_grey_scale_inverse) ||
5493                  (painting==painting_violet_to_red) ){
5494         a_cmap.get_color(rbin.m_ratio,clr);
5495       } else {
5496         clr = a_style.color;
5497       }
5498 
5499       rgba* mat = new rgba();
5500       mat->color = clr;
5501       sep->add(mat);
5502 
5503       vertices* vtxs = new vertices;
5504       vtxs->mode = gl::triangle_fan();
5505       sep->add(vtxs);
5506 
5507       vtxs->add(xx,yy,a_zz);
5508       vtxs->add(xe,yy,a_zz);
5509       vtxs->add(xe,ye,a_zz);
5510       vtxs->add(xx,ye,a_zz);
5511 
5512       empty = false;
5513     }
5514 
5515     if(empty) {
5516       delete _sep;
5517     } else {
5518       m_bins_sep.add(_sep);
5519     }
5520   }
5521 
5522   void rep_bins1D_xy_wire_boxes(const style& a_style,
5523                                 const base_colormap& a_cmap,
5524                                 const std::vector<rep_bin1D>& a_bins,
5525                                 const rep_box& a_box_x,const rep_box& a_box_y,
5526                                 float a_zz,
5527                                 bool a_bar_chart/*,
5528                                 const std::string& aID*/){
5529 
5530     painting_policy painting = a_style.painting;
5531 
5532     float xmin = a_box_x.m_pos;
5533     float dx = a_box_x.m_width;
5534     bool xlog = a_box_x.m_log;
5535 
5536     float ymin = a_box_y.m_pos;
5537     float dy = a_box_y.m_width;
5538     bool ylog = a_box_y.m_log;
5539 
5540     separator* _sep = new separator();
5541 
5542     bool empty = true;
5543     colorf clr;
5544 
5545     tools_vforcit(rep_bin1D,a_bins,it) {
5546       const rep_bin1D& rbin = *it;
5547 
5548       float xx = rbin.m_x_min;
5549       float xe = rbin.m_x_max;
5550       float yy = rbin.m_v_min;
5551       float ye = rbin.m_val;
5552       if(ye<yy) {
5553         yy = rbin.m_val;
5554         ye = rbin.m_v_min;
5555       }
5556 
5557       float val = rbin.m_val;
5558 
5559       if(a_bar_chart) {
5560         bar_chart(a_style.bar_offset.value(),
5561                   a_style.bar_width.value(),xx,xe);
5562       }
5563 
5564       xx = verify_log(xx,xmin,dx,xlog);
5565       xe = verify_log(xe,xmin,dx,xlog);
5566       yy = verify_log(yy,ymin,dy,ylog);
5567       ye = verify_log(ye,ymin,dy,ylog);
5568 
5569       // Clipping :
5570       if(xx>1) continue;
5571       if(xe<0) continue;
5572       if(xx<0) xx = 0;
5573       if(xe>1) xe = 1;
5574       if(yy>1) continue;
5575       if(ye<0) continue;
5576       if(yy<0) yy = 0;
5577       if(ye>1) ye = 1;
5578 
5579       separator* sep = new separator();
5580       _sep->add(sep);
5581 
5582       if(painting==painting_by_value) {
5583         a_cmap.get_color(val,clr);
5584       } else if( (painting==painting_grey_scale) ||
5585                  (painting==painting_grey_scale_inverse) ||
5586                  (painting==painting_violet_to_red) ){
5587         a_cmap.get_color(rbin.m_ratio,clr);
5588       } else {
5589         clr = a_style.color;
5590       }
5591 
5592       rgba* mat = new rgba();
5593       mat->color = clr;
5594       sep->add(mat);
5595 
5596       vertices* vtxs = new vertices;
5597       vtxs->mode = gl::line_strip();
5598       sep->add(vtxs);
5599 
5600       vtxs->add(xx,yy,a_zz);
5601       vtxs->add(xe,yy,a_zz);
5602       vtxs->add(xe,ye,a_zz);
5603       vtxs->add(xx,ye,a_zz);
5604       vtxs->add(xx,yy,a_zz);
5605 
5606       empty = false;
5607     }
5608 
5609     if(empty) {
5610       delete _sep;
5611     } else {
5612       m_bins_sep.add(_sep);
5613     }
5614   }
5615 
5616   void rep_bins1D_xy_lines_one(const style& a_style,const std::vector<rep_bin1D>& a_bins,
5617                                const rep_box& a_box_x,const rep_box& a_box_y,float a_zz/*,const SbString& aID*/) {
5618     // Draw lines connecting top middle of bins.
5619     size_t xnbin = a_bins.size();
5620     std::vector<vec3f> points(xnbin);
5621     for(size_t index=0;index<xnbin;index++) {
5622       float x = (a_bins[index].m_x_min + a_bins[index].m_x_max)/2;
5623       float y = a_bins[index].m_val;
5624       points[index] = vec3f(x,y,a_zz);
5625     }
5626 
5627     vertices* vtxs = new vertices;
5628     std::vector<float>& pts = vtxs->xyzs.values(); //npt*3
5629 
5630     clip_polyline_2D(points,a_box_x,a_box_y,pts);
5631     if(pts.size()) {
5632       sg::separator* separator = new sg::separator;
5633 
5634       rgba* mat = new rgba();
5635       mat->color = a_style.color;
5636       separator->add(mat);
5637 
5638       draw_style* ds = new draw_style;
5639       ds->style = draw_lines;
5640       ds->line_pattern = a_style.line_pattern;
5641       ds->line_width = a_style.line_width;
5642       separator->add(ds);
5643 
5644       vtxs->mode = gl::line_strip();
5645       separator->add(vtxs);
5646 
5647       m_bins_sep.add(separator);
5648     } else {
5649       delete vtxs;
5650     }
5651   }
5652 
5653   void rep_bins1D_xy_curve_one(std::ostream& a_out,const style& a_style,const std::vector<rep_bin1D>& a_bins,
5654                                const rep_box& a_box_x,const rep_box& a_box_y,float a_zz/*,const SbString& aID*/){
5655     size_t number = a_bins.size();
5656     if(!number) return;
5657 
5658     double* xs = new double[number];
5659     double* ys = new double[number];
5660     float x,y;
5661     for(size_t index=0;index<number;index++) {
5662       x = (a_bins[index].m_x_min + a_bins[index].m_x_max)/2;
5663       y = a_bins[index].m_val;
5664       xs[index] = x;ys[index] = y;
5665     }
5666     spline::cubic _spline(a_out,number,xs,ys);
5667     delete [] xs;delete [] ys;
5668 
5669     float xmn = m_x_axis_data.min_value();
5670     float xmx = m_x_axis_data.max_value();
5671     unsigned int nstp = curve_number_of_points;
5672     float step = (xmx - xmn)/nstp;
5673     std::vector<vec3f> points(nstp+1);
5674     for(unsigned int ibin=0;ibin<=nstp;ibin++) {
5675       float xx = xmn + ibin * step;
5676       double val = _spline.eval(xx);
5677       points[ibin].set_value(xx,float(val),a_zz);
5678     }
5679 
5680     vertices* vtxs = new vertices;
5681     std::vector<float>& pts = vtxs->xyzs.values(); //npt*3
5682 
5683     clip_polyline_2D(points,a_box_x,a_box_y,pts);
5684     if(pts.size()) {
5685       sg::separator* separator = new sg::separator;
5686 
5687       rgba* mat = new rgba();
5688       mat->color = a_style.color;
5689       separator->add(mat);
5690 
5691       draw_style* ds = new draw_style;
5692       ds->style = draw_lines;
5693       ds->line_pattern = a_style.line_pattern;
5694       ds->line_width = a_style.line_width;
5695       separator->add(ds);
5696 
5697       vtxs->mode = gl::line_strip();
5698       separator->add(vtxs);
5699 
5700       m_bins_sep.add(separator);
5701     } else {
5702       delete vtxs;
5703     }
5704 
5705   }
5706 
5707 
5708   void rep_bins2D_xy_box(const style& a_style,const std::vector<rep_bin2D>& a_bins,
5709                          const rep_box& a_box_x,const rep_box& a_box_y,float a_bmin,float a_bmax,float a_zz) {
5710     // Draw box of size proportionnal to bin value.
5711     separator* _sep = new separator();
5712 
5713     _sep->add(new normal);
5714 
5715     rgba* mat = new rgba();
5716     mat->color = a_style.color;
5717     _sep->add(mat);
5718 
5719     float xmin = a_box_x.m_pos;
5720     float dx = a_box_x.m_width;
5721     bool xlog = a_box_x.m_log;
5722 
5723     float ymin = a_box_y.m_pos;
5724     float dy = a_box_y.m_width;
5725     bool ylog = a_box_y.m_log;
5726 
5727     bool empty = true;
5728     float range = a_bmax - a_bmin;
5729 
5730     tools_vforcit(rep_bin2D,a_bins,it) {
5731       const rep_bin2D& rbin = *it;
5732 
5733       float xx = rbin.m_x_min;
5734       float xe = rbin.m_x_max;
5735       float yy = rbin.m_y_min;
5736       float ye = rbin.m_y_max;
5737       float val = rbin.m_val;
5738 
5739       float xsize,ysize;
5740       if(range>0) {
5741         // If val = bmax, the box maps the cell.
5742         xsize = (val - a_bmin) * (xe - xx) / range;
5743         ysize = (val - a_bmin) * (ye - yy) / range;
5744       } else {
5745         //If range is 0. ; then all bins that have
5746         // entries have same values. Draw box xdbin * ydbin.
5747         xsize = xe - xx;
5748         ysize = ye - yy;
5749       }
5750 
5751       xx = xx + ((xe-xx) - xsize)/2;
5752       xe = xx + xsize;
5753       yy = yy + ((ye-yy) - ysize)/2;
5754       ye = yy + ysize;
5755 
5756       xx = verify_log(xx ,xmin,dx  ,xlog);
5757       xe = verify_log(xe ,xmin,dx  ,xlog);
5758       yy = verify_log(yy ,ymin,dy  ,ylog);
5759       ye = verify_log(ye ,ymin,dy  ,ylog);
5760 
5761       // Clipping :
5762       if(xx>1) continue;
5763       if(xe<0) continue;
5764       if(xx<0) xx = 0;
5765       if(xe>1) xe = 1;
5766       if(yy>1) continue;
5767       if(ye<0) continue;
5768       if(yy<0) yy = 0;
5769       if(ye>1) ye = 1;
5770 
5771       vertices* vtxs = new vertices;
5772       vtxs->mode = gl::triangle_fan();
5773       _sep->add(vtxs);
5774 
5775       vtxs->add(xx,yy,a_zz);
5776       vtxs->add(xe,yy,a_zz);
5777       vtxs->add(xe,ye,a_zz);
5778       vtxs->add(xx,ye,a_zz);
5779 
5780       empty = false;
5781     }
5782 
5783     if(empty) {
5784       delete _sep;
5785     } else {
5786       m_bins_sep.add(_sep);
5787     }
5788   }
5789 
5790   void rep_bins2D_xy_wire_box(const style& a_style,
5791                               const std::vector<rep_bin2D>& a_bins,
5792                               const rep_box& a_box_x,const rep_box& a_box_y,
5793                               float a_bmin,float a_bmax,float a_zz
5794                               /*,const SbString& aID*/){
5795     // Draw box of size proportionnal to bin value.
5796 
5797     sg::separator* separator = new sg::separator;
5798 
5799     rgba* mat = new rgba();
5800     mat->color = a_style.color;
5801     separator->add(mat);
5802 
5803     draw_style* ds = new draw_style;
5804     ds->style = draw_lines;
5805     ds->line_pattern = a_style.line_pattern;
5806     ds->line_width = a_style.line_width;
5807     separator->add(ds);
5808 
5809     vertices* vtxs = new vertices;
5810     vtxs->mode = gl::lines();
5811     separator->add(vtxs);
5812 
5813     bool empty = true;
5814 
5815     float xmin = a_box_x.m_pos;
5816     float dx = a_box_x.m_width;
5817     bool xlog = a_box_x.m_log;
5818 
5819     float ymin = a_box_y.m_pos;
5820     float dy = a_box_y.m_width;
5821     bool ylog = a_box_y.m_log;
5822 
5823     float range = a_bmax - a_bmin;
5824     size_t number = a_bins.size();
5825     for(size_t index=0;index<number;index++) {
5826 
5827       float xx = a_bins[index].m_x_min;
5828       float xe = a_bins[index].m_x_max;
5829       float yy = a_bins[index].m_y_min;
5830       float ye = a_bins[index].m_y_max;
5831       float val = a_bins[index].m_val;
5832 
5833       float xsize,ysize;
5834       if(range>0) {
5835         // If val = bmax, the box maps the cell.
5836         xsize = (val - a_bmin) * (xe - xx) / range;
5837         ysize = (val - a_bmin) * (ye - yy) / range;
5838       } else {
5839         //If range is 0. ; then all bins that have
5840         // entries have same values. Draw box xdbin * ydbin.
5841         xsize = xe - xx;
5842         ysize = ye - yy;
5843       }
5844 
5845       xx = xx + ((xe-xx) - xsize)/2;
5846       xe = xx + xsize;
5847       yy = yy + ((ye-yy) - ysize)/2;
5848       ye = yy + ysize;
5849 
5850       xx = verify_log(xx ,xmin,dx  ,xlog);
5851       xe = verify_log(xe ,xmin,dx  ,xlog);
5852       yy = verify_log(yy ,ymin,dy  ,ylog);
5853       ye = verify_log(ye ,ymin,dy  ,ylog);
5854 
5855       // Clipping :
5856       if(xx>1) continue;
5857       if(xe<0) continue;
5858       if(xx<0) xx = 0;
5859       if(xe>1) xe = 1;
5860       if(yy>1) continue;
5861       if(ye<0) continue;
5862       if(yy<0) yy = 0;
5863       if(ye>1) ye = 1;
5864 
5865       vtxs->add(xx,yy,a_zz);
5866       vtxs->add(xe,yy,a_zz);
5867 
5868       vtxs->add(xe,yy,a_zz);
5869       vtxs->add(xe,ye,a_zz);
5870 
5871       vtxs->add(xe,ye,a_zz);
5872       vtxs->add(xx,ye,a_zz);
5873 
5874       vtxs->add(xx,ye,a_zz);
5875       vtxs->add(xx,yy,a_zz);
5876 
5877       empty = false;
5878     }
5879 
5880     if(empty) {
5881       delete separator;
5882     } else {
5883       m_bins_sep.add(separator);
5884     }
5885   }
5886 
5887   void rep_bins2D_xy_solid(const style& a_style,const base_colormap& a_cmap,const std::vector<rep_bin2D>& a_bins,
5888                            const rep_box& a_box_x,const rep_box& a_box_y,float a_zz) {
5889     painting_policy painting = a_style.painting;
5890 
5891     separator* _sep = new separator();
5892 
5893     _sep->add(new normal);
5894 
5895     float xmin = a_box_x.m_pos;
5896     float dx = a_box_x.m_width;
5897     bool xlog = a_box_x.m_log;
5898 
5899     float ymin = a_box_y.m_pos;
5900     float dy = a_box_y.m_width;
5901     bool ylog = a_box_y.m_log;
5902 
5903     bool empty = true;
5904     colorf clr;
5905 
5906     tools_vforcit(rep_bin2D,a_bins,it) {
5907       const rep_bin2D& rbin = *it;
5908 
5909       float xx = rbin.m_x_min;
5910       float xe = rbin.m_x_max;
5911       float yy = rbin.m_y_min;
5912       float ye = rbin.m_y_max;
5913       float val = rbin.m_val;
5914 
5915       xx = verify_log(xx ,xmin,dx  ,xlog);
5916       xe = verify_log(xe ,xmin,dx  ,xlog);
5917       yy = verify_log(yy ,ymin,dy  ,ylog);
5918       ye = verify_log(ye ,ymin,dy  ,ylog);
5919 
5920       // Clipping :
5921       if(xx>1) continue;
5922       if(xe<0) continue;
5923       if(xx<0) xx = 0;
5924       if(xe>1) xe = 1;
5925       if(yy>1) continue;
5926       if(ye<0) continue;
5927       if(yy<0) yy = 0;
5928       if(ye>1) ye = 1;
5929 
5930       if(painting==painting_by_value) {
5931         a_cmap.get_color(val,clr);
5932       } else if( (painting==painting_grey_scale) ||
5933                  (painting==painting_grey_scale_inverse) ||
5934                  (painting==painting_violet_to_red) ){
5935         a_cmap.get_color(rbin.m_ratio,clr);
5936       } else {
5937         clr = a_style.color;
5938       }
5939 
5940       rgba* mat = new rgba();
5941       mat->color = clr;
5942       _sep->add(mat);
5943 
5944       vertices* vtxs = new vertices;
5945       vtxs->mode = gl::triangle_fan();
5946       //sep->add(vtxs);
5947       _sep->add(vtxs);
5948 
5949       vtxs->add(xx,yy,a_zz);
5950       vtxs->add(xe,yy,a_zz);
5951       vtxs->add(xe,ye,a_zz);
5952       vtxs->add(xx,ye,a_zz);
5953 
5954       empty = false;
5955     }
5956 
5957     if(empty) {
5958       delete _sep;
5959     } else {
5960       m_bins_sep.add(_sep);
5961     }
5962   }
5963 
5964   void rep_bins2D_xy_random_one(const style& a_style,const std::vector<rep_bin2D>& a_bins,
5965                                 const rep_box& a_box_x,const rep_box& a_box_y,float a_bmin,float a_bmax,float a_zz
5966                                 /*,const SbString& aID*/){
5967     sg::separator* separator = new sg::separator;
5968 
5969     rgba* mat = new rgba();
5970     mat->color = a_style.color;
5971     separator->add(mat);
5972 
5973     draw_style* ds = new draw_style;
5974     ds->style = draw_points;
5975     ds->point_size = a_style.point_size;
5976     separator->add(ds);
5977 
5978     float xmin = a_box_x.m_pos;
5979     float dx = a_box_x.m_width;
5980     bool xlog = a_box_x.m_log;
5981 
5982     float ymin = a_box_y.m_pos;
5983     float dy = a_box_y.m_width;
5984     bool ylog = a_box_y.m_log;
5985 
5986     //  Draw for each bins a number of random
5987     // points proportiannal to bins range.
5988 
5989     float range = a_bmax - a_bmin;
5990 
5991     bool empty = true;
5992 
5993     size_t number = a_bins.size();
5994     for(size_t index=0;index<number;index++) {
5995 
5996       float xx = a_bins[index].m_x_min;
5997       float xe = a_bins[index].m_x_max;
5998       float yy = a_bins[index].m_y_min;
5999       float ye = a_bins[index].m_y_max;
6000       float val = a_bins[index].m_val;
6001 
6002       // If range is 0. ; then all bins that have entries
6003       // have same values. Draw one point.
6004 
6005       int nmin = 1;
6006       int nmax = 50;
6007       int npt = range>0. ? (int)((val - a_bmin)*(nmax-nmin)/range + nmin):1;
6008       if(npt>0) {
6009         vertices* vtxs = new vertices;
6010         vtxs->mode = gl::points();
6011         separator->add(vtxs);
6012 
6013         float xdbin = xe - xx;
6014         float ydbin = ye - yy;
6015         for(int count=0;count<npt;count++) {
6016           float xxx = xx + xdbin * m_rtausmef.shoot();
6017           float yyy = yy + ydbin * m_rtausmef.shoot();
6018           xxx = verify_log(xxx ,xmin,dx  ,xlog);
6019           yyy = verify_log(yyy ,ymin,dy  ,ylog);
6020           if((xxx>=0)&&(xxx<=1)  &&
6021              (yyy>=0)&&(yyy<=1)  ) {
6022             vtxs->add(xxx,yyy,a_zz);
6023             empty = false;
6024           }
6025         }
6026       }
6027 
6028     }//end for
6029 
6030     if(empty) {
6031       delete separator;
6032     } else {
6033       m_bins_sep.add(separator);
6034     }
6035   }
6036 
6037   void rep_bins2D_xy_text(
6038    const style& //a_style
6039   ,const std::vector<rep_bin2D>& //a_bins
6040   ,const rep_box& //a_box_x
6041   ,const rep_box& //a_box_y
6042   //,const SbString& aID
6043   ){
6044     //Draw box and text for number of entries.
6045 
6046   }
6047 
6048   void rep_contour_xy(std::ostream& a_out,const style& a_style,painting_policy a_painting,
6049                       const base_colormap& a_cmap,clist_contour& a_contour,
6050                       const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_zz
6051                       /*,const std::string& aID*/){
6052 
6053     float xmin = a_box_x.m_pos;
6054     float dx = a_box_x.m_width;
6055     bool xlog = a_box_x.m_log;
6056 
6057     float ymin = a_box_y.m_pos;
6058     float dy = a_box_y.m_width;
6059     bool ylog = a_box_y.m_log;
6060 
6061     float zmin = a_box_z.m_pos;
6062     float dz = a_box_z.m_width;
6063 
6064     sg::separator* separator = new sg::separator;
6065 
6066     draw_style* ds = new draw_style;
6067     ds->style.value(draw_lines);
6068     ds->line_pattern.value(a_style.line_pattern);
6069     ds->line_width.value(a_style.line_width);
6070     separator->add(ds);
6071 
6072     atb_vertices* vtxs = new atb_vertices;
6073     vtxs->mode = gl::lines(); //segments
6074     separator->add(vtxs);
6075 
6076     bool empty = true;
6077 
6078     for (unsigned int i=0;i<a_contour.get_number_of_planes();i++)  {
6079       cline_strip_list* pStripList = a_contour.get_lines(i);
6080       if(!pStripList) {
6081         a_out << "tools::sg;:plotter::rep_contour_xy : problem with contour." << std::endl;
6082         delete separator;
6083         return;
6084       }
6085 
6086       //If zlog true, zz is already in log.
6087       float val = (float)a_contour.get_plane(i);
6088       float zz = val;
6089 
6090       zz = verify_log(zz,zmin,dz,false);
6091       if(zz>1) continue;
6092       if(zz<0) continue;
6093 
6094       colorf _color;
6095       if(a_painting==painting_by_value) {
6096         a_cmap.get_color(val,_color);
6097       } else if(a_painting==painting_by_level) {
6098         size_t icol = a_cmap.colorn() ? (i % a_cmap.colorn()) :0;
6099         _color = a_cmap.color(icol);
6100       } else {
6101         _color = a_style.color;
6102       }
6103 
6104       tools_lforcit(cline_strip*,*pStripList,pos) {
6105         cline_strip* pStrip = (*pos);
6106         if(!pStrip) {
6107           a_out << "tools::sg;:plotter::rep_contour_xy : problem with contour." << std::endl;
6108           delete separator;
6109           return;
6110         }
6111         if (pStrip->empty()) continue;
6112 
6113         //// putting point at start and end of strip
6114         //// retreiving index
6115         //unsigned int index=pStrip->front();
6116         //double xb=a_contour.get_xi(index);
6117         //double yb=a_contour.get_yi(index);
6118         //// retreiving index
6119         ////glColor4f(0,0,1,.8f);
6120         //index=pStrip->back();
6121         //double xe=a_contour.get_xi(index);
6122         //double ye=a_contour.get_yi(index);
6123 
6124         bool first = true;
6125         float xprev = 0;
6126         float yprev = 0;
6127         float xx,yy;
6128 
6129         tools_lforcit(unsigned int,*pStrip,pos2) {
6130           xx = (float)a_contour.get_xi(*pos2);
6131           yy = (float)a_contour.get_yi(*pos2);
6132           xx = verify_log(xx,xmin,dx,xlog);
6133           yy = verify_log(yy,ymin,dy,ylog);
6134           if(
6135               (xx<0) || (xx>1) ||
6136               (yy<0) || (yy>1)
6137             ) {
6138             // Throw away this strip :
6139           }
6140           if(first) {
6141             first = false;
6142           } else {
6143             vtxs->add(xprev,yprev,a_zz+zz);
6144             vtxs->add(xx,yy,a_zz+zz);
6145             vtxs->add_color(_color);
6146             vtxs->add_color(_color);
6147           }
6148           xprev = xx;
6149           yprev = yy;
6150 
6151           empty = false;
6152       }
6153     }
6154 
6155     }
6156 
6157     if(empty) {
6158       delete separator;
6159     } else {
6160       m_bins_sep.add(separator);
6161     }
6162   }
6163 
6164   void rep_contour_xy_filled(std::ostream& a_out,const style& a_style,painting_policy a_painting,
6165                              const base_colormap& a_cmap,clist_contour& a_contour,
6166                              const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_zz
6167                              /*,const std::string& aID*/){
6168 
6169     float xmin = a_box_x.m_pos;
6170     float dx = a_box_x.m_width;
6171     bool xlog = a_box_x.m_log;
6172 
6173     float ymin = a_box_y.m_pos;
6174     float dy = a_box_y.m_width;
6175     bool ylog = a_box_y.m_log;
6176 
6177     float zmin = a_box_z.m_pos;
6178     float dz = a_box_z.m_width;
6179 
6180     sg::separator* separator = new sg::separator;
6181 
6182     vec3f AB,BC,vcross;
6183 
6184     {// Draw background :
6185       sg::separator* sep = new sg::separator;
6186       separator->add(sep);
6187 
6188       float zz = a_zz - 0.01F;
6189 
6190       colorf _color;
6191       if(a_cmap.colorn()) {
6192         _color = a_cmap.color(0);
6193       } else {
6194         _color = a_style.color;
6195       }
6196 
6197       rgba* mat = new rgba();
6198       mat->color = _color;
6199       sep->add(mat);
6200 
6201       float xx = xmin;
6202       float xe = xmin+dx;
6203       float yy = ymin;
6204       float ye = ymin+dy;
6205 
6206       xx = verify_log(xx,xmin,dx,xlog);
6207       xe = verify_log(xe,xmin,dx,xlog);
6208       yy = verify_log(yy,ymin,dy,ylog);
6209       ye = verify_log(ye,ymin,dy,ylog);
6210 
6211       vertices* vtxs = new vertices;
6212       vtxs->mode = gl::triangle_fan();
6213       vtxs->add(xx,yy,zz);
6214       vtxs->add(xe,yy,zz);
6215       vtxs->add(xe,ye,zz);
6216       vtxs->add(xx,ye,zz);
6217       sep->add(vtxs);
6218 
6219     } // End background.
6220 
6221     bool empty = true;
6222 
6223     for (unsigned int i=0;i<a_contour.get_number_of_planes();i++)  {
6224 
6225       cline_strip_list* pStripList = a_contour.get_lines(i);
6226       if(!pStripList) {
6227         a_out << "tools::sg;:plotter::rep_contour_xy_filled : problem with contour." << std::endl;
6228         delete separator;
6229         return;
6230       }
6231 
6232       sg::separator* sep = new sg::separator;
6233       separator->add(sep);
6234 
6235       //If zlog true, zz is already in log.
6236       float val = (float)a_contour.get_plane(i);
6237       float zz = val;
6238 
6239       zz = verify_log(zz,zmin,dz,false);
6240       if(zz>1) continue;
6241       if(zz<0) continue;
6242 
6243       std::vector< std::vector<vec3f> > contourVector;
6244 
6245       tools_lforcit(cline_strip*,*pStripList,pos) {
6246         cline_strip* pStrip = (*pos);
6247         if(pStrip->size() >2) {
6248           std::vector<vec3f> v;
6249           for (cline_strip::iterator pos2=pStrip->begin();pos2 != pStrip->end();pos2++) {
6250             unsigned int index=(*pos2);
6251             float xx = (float)a_contour.get_xi(index);
6252             float yy = (float)a_contour.get_yi(index);
6253             xx = verify_log(xx,xmin,dx,xlog);
6254             yy = verify_log(yy,ymin,dy,ylog);
6255             v.push_back(vec3f(xx,yy,a_zz+zz));
6256           }
6257           contourVector.push_back(std::move(v));
6258         }
6259       }
6260 
6261       std::vector<tess_triangle> tris;
6262       tess_contour tessContour(a_out,tris); //we pass a ref to tris.
6263       tessContour.getFilledArea(contourVector);
6264       if(!tris.size()) continue;
6265 
6266       colorf _color;
6267       if(a_painting==painting_by_value) {
6268         a_cmap.get_color(val,_color);
6269       } else if(a_painting==painting_by_level) {
6270         int icol = a_cmap.colorn() ? (i % a_cmap.colorn()) :0;
6271         _color = a_cmap.color(icol);
6272       } else {
6273         _color = a_style.color;
6274       }
6275 
6276       atb_vertices* vtxs = new atb_vertices; //PAW_C/color.kumac. It needs back face.
6277       vtxs->mode = gl::triangles();
6278       sep->add(vtxs);
6279 
6280       for(size_t itri=0;itri<tris.size();itri++) {
6281         tess_triangle& tri = tris[itri];
6282         AB.set_value((float)(tri.pointB[0]-tri.pointA[0]),
6283                      (float)(tri.pointB[1]-tri.pointA[1]),
6284                      (float)(tri.pointB[2]-tri.pointA[2]));
6285         BC.set_value((float)(tri.pointC[0]-tri.pointB[0]),
6286                      (float)(tri.pointC[1]-tri.pointB[1]),
6287                      (float)(tri.pointC[2]-tri.pointB[2]));
6288         AB.cross(BC,vcross);
6289         if(vcross.z()>=0) {
6290           vtxs->add((float)tri.pointA[0],(float)tri.pointA[1],(float)tri.pointA[2]);
6291           vtxs->add((float)tri.pointB[0],(float)tri.pointB[1],(float)tri.pointB[2]);
6292           vtxs->add((float)tri.pointC[0],(float)tri.pointC[1],(float)tri.pointC[2]);
6293         } else {
6294           vtxs->add((float)tri.pointA[0],(float)tri.pointA[1],(float)tri.pointA[2]);
6295           vtxs->add((float)tri.pointC[0],(float)tri.pointC[1],(float)tri.pointC[2]);
6296           vtxs->add((float)tri.pointB[0],(float)tri.pointB[1],(float)tri.pointB[2]);
6297         }
6298         vtxs->add_color(_color);
6299         vtxs->add_color(_color);
6300         vtxs->add_color(_color);
6301       }
6302 
6303       empty = false;
6304 
6305     }
6306 
6307     if(empty) {
6308       delete separator;
6309     } else {
6310       m_bins_sep.add(separator);
6311     }
6312   }
6313 
6314   void rep_errors_plus_xy(std::ostream& /*a_out*/,const style& a_style,const std::vector<rep_bin1D>& a_bins,
6315                           const rep_box& a_box_x,const rep_box& a_box_y,const std::vector<float>& a_bars,float aZ) {
6316     separator* _sep = new separator();
6317 
6318     rgba* mat = new rgba();
6319     mat->color = a_style.color;
6320     _sep->add(mat);
6321 
6322     draw_style* ds = new draw_style;
6323     ds->style.value(draw_lines);
6324     ds->line_pattern.value(a_style.line_pattern);
6325     ds->line_width.value(a_style.line_width);
6326     _sep->add(ds);
6327 
6328     vertices* vtxs = new vertices;
6329     vtxs->mode = gl::lines();
6330     _sep->add(vtxs);
6331 
6332     float xmin = a_box_x.m_pos;
6333     float dx = a_box_x.m_width;
6334     bool xlog = a_box_x.m_log;
6335 
6336     float ymin = a_box_y.m_pos;
6337     float dy = a_box_y.m_width;
6338     bool ylog = a_box_y.m_log;
6339 
6340     size_t xnbin = a_bins.size();
6341 
6342     for(size_t index=0;index<xnbin;index++) {
6343 
6344       //Need all bins modeled for fitting.
6345 
6346       float val = a_bins[index].m_val;
6347       float bar_height = a_bars[index];
6348 
6349       float bar_min = val - bar_height/2;
6350       float bar_max = val + bar_height/2;
6351 
6352       float xx = a_bins[index].m_x_min;
6353       float xe = a_bins[index].m_x_max;
6354 
6355       xx = verify_log(xx,xmin,dx,xlog);
6356       xe = verify_log(xe,xmin,dx,xlog);
6357       val = verify_log(val,ymin,dy,ylog);
6358 
6359       bar_min = verify_log(bar_min,ymin,dy,ylog);
6360       bar_max = verify_log(bar_max,ymin,dy,ylog);
6361 
6362       if(xe<0) continue;
6363       if(xx>1) continue;
6364       if(xx<0) xx = 0;
6365       if(xe>1) xe = 1;
6366 
6367       float ex = (xe+xx)/2;
6368 
6369       float edx = 0.3F * (xe-xx);
6370 
6371       if((val>=0)&&(val<=1)) {
6372         vtxs->add(ex-edx,val,aZ);
6373         vtxs->add(ex+edx,val,aZ);
6374       }
6375 
6376       if(bar_min >1)  {
6377         // do nothing
6378       } else  if(bar_max <0)  {
6379         // do nothing
6380       } else  if(bar_min <0) {
6381         if(bar_max >1) {
6382           vtxs->add(ex,0,aZ);
6383           vtxs->add(ex,1,aZ);
6384         } else {
6385           vtxs->add(ex,0,aZ);
6386           vtxs->add(ex,bar_max,aZ);
6387         }
6388       } else  if(bar_max >1) {
6389         vtxs->add(ex,bar_min,aZ);
6390         vtxs->add(ex,1,aZ);
6391       } else {
6392         vtxs->add(ex    ,bar_min,aZ);
6393         vtxs->add(ex    ,bar_max,aZ);
6394       }
6395 
6396     }
6397 
6398     if(vtxs->number()) {
6399       m_errors_sep.add(_sep);
6400     } else {
6401       delete _sep;
6402     }
6403   }
6404 
6405   void rep_errors_I_xy(std::ostream& /*a_out*/,const style& a_style,const std::vector<rep_bin1D>& a_bins,
6406                        const rep_box& a_box_x,const rep_box& a_box_y,const std::vector<float>& a_bars,float aZ){
6407     separator* _sep = new separator();
6408 
6409     rgba* mat = new rgba();
6410     mat->color = a_style.color;
6411     _sep->add(mat);
6412 
6413     draw_style* ds = new draw_style;
6414     ds->style.value(draw_lines);
6415     ds->line_pattern.value(a_style.line_pattern);
6416     ds->line_width.value(a_style.line_width);
6417     _sep->add(ds);
6418 
6419     vertices* vtxs = new vertices;
6420     vtxs->mode = gl::lines();
6421     _sep->add(vtxs);
6422 
6423     float xmin = a_box_x.m_pos;
6424     float dx = a_box_x.m_width;
6425     bool xlog = a_box_x.m_log;
6426 
6427     float ymin = a_box_y.m_pos;
6428     float dy = a_box_y.m_width;
6429     bool ylog = a_box_y.m_log;
6430 
6431     size_t xnbin = a_bins.size();
6432 
6433     for(size_t index=0;index<xnbin;index++) {
6434 
6435       //Need all bins modeled for fitting.
6436 
6437       float val = a_bins[index].m_val;
6438       float bar_height = a_bars[index];
6439 
6440       float bar_min = val - bar_height/2;
6441       float bar_max = val + bar_height/2;
6442 
6443       float xx = a_bins[index].m_x_min;
6444       float xe = a_bins[index].m_x_max;
6445 
6446       xx = verify_log(xx,xmin,dx,xlog);
6447       xe = verify_log(xe,xmin,dx,xlog);
6448       val = verify_log(val,ymin,dy,ylog);
6449 
6450       bar_min = verify_log(bar_min,ymin,dy,ylog);
6451       bar_max = verify_log(bar_max,ymin,dy,ylog);
6452 
6453       if(xe<0) continue;
6454       if(xx>1) continue;
6455       if(xx<0) xx = 0;
6456       if(xe>1) xe = 1;
6457       if(val<0) val = 0;
6458       if(val>1) val = 1;
6459 
6460       float ex = (xe+xx)/2;
6461 
6462       float edx = 0.3F * (xe-xx);
6463 
6464       if(bar_min >1)  {
6465         // do nothing
6466       } else  if(bar_max <0)  {
6467         // do nothing
6468       } else  if(bar_min <0) {
6469         if(bar_max >1) {
6470           vtxs->add(ex,0,aZ);
6471           vtxs->add(ex,1,aZ);
6472         } else {
6473           vtxs->add(ex,0,aZ);
6474           vtxs->add(ex,bar_max,aZ);
6475           vtxs->add(ex-edx,bar_max,aZ);
6476           vtxs->add(ex+edx,bar_max,aZ);
6477         }
6478       } else  if(bar_max >1) {
6479         vtxs->add(ex-edx,bar_min,aZ);
6480         vtxs->add(ex+edx,bar_min,aZ);
6481         vtxs->add(ex,bar_min,aZ);
6482         vtxs->add(ex,1,aZ);
6483       } else {
6484         vtxs->add(ex-edx,bar_min,aZ);
6485         vtxs->add(ex+edx,bar_min,aZ);
6486         vtxs->add(ex    ,bar_min,aZ);
6487         vtxs->add(ex    ,bar_max,aZ);
6488         vtxs->add(ex-edx,bar_max,aZ);
6489         vtxs->add(ex+edx,bar_max,aZ);
6490       }
6491 
6492     }
6493 
6494     if(vtxs->number()) {
6495       m_errors_sep.add(_sep);
6496     } else {
6497       delete _sep;
6498     }
6499   }
6500 
6501   void rep_hatch1D_xy(const style& a_style,
6502                       const std::vector<rep_bin1D>& a_bins,
6503                       const rep_box& a_box_x,const rep_box& a_box_y,float a_zz,
6504                       bool a_bar_chart){
6505 
6506     separator* _sep = new separator;
6507 
6508     rgba* mat = new rgba();
6509     mat->color = a_style.color;
6510     _sep->add(mat);
6511 
6512     draw_style* ds = new draw_style;
6513     if(a_style.strip_width.value()==0) {
6514       ds->style = draw_lines;
6515       ds->line_pattern = line_solid;
6516       ds->line_width = a_style.line_width;
6517     } else {
6518       ds->style = draw_filled;
6519     }
6520     _sep->add(ds);
6521 
6522     float xmin = a_box_x.m_pos;
6523     float dx = a_box_x.m_width;
6524     bool xlog = a_box_x.m_log;
6525 
6526     float ymin = a_box_y.m_pos;
6527     float dy = a_box_y.m_width;
6528     bool ylog = a_box_y.m_log;
6529 
6530     bool empty = true;
6531 
6532     vec3f points[5];
6533     size_t xnbin = a_bins.size();
6534     for(size_t index=0;index<xnbin;index++) {
6535       float xx = a_bins[index].m_x_min;
6536       float xe = a_bins[index].m_x_max;
6537       float yy = a_bins[index].m_v_min;
6538       float ye = a_bins[index].m_val;
6539       if(ye<yy) {
6540         yy = a_bins[index].m_val;
6541         ye = a_bins[index].m_v_min;
6542       }
6543 
6544       if(a_bar_chart) bar_chart(a_style.bar_offset.value(),a_style.bar_width.value(),xx,xe);
6545 
6546       xx = verify_log(xx,xmin,dx,xlog);
6547       xe = verify_log(xe,xmin,dx,xlog);
6548       yy = verify_log(yy,ymin,dy,ylog);
6549       ye = verify_log(ye,ymin,dy,ylog);
6550 
6551       // Clipping :
6552       if(xx>1) continue;
6553       if(xe<0) continue;
6554       if(xx<0) xx = 0;
6555       if(xe>1) xe = 1;
6556       if(yy>1) continue;
6557       if(ye<0) continue;
6558       if(yy<0) yy = 0;
6559       if(ye>1) ye = 1;
6560 
6561       points[0].set_value(xx,yy,a_zz);
6562       points[1].set_value(xe,yy,a_zz);
6563       points[2].set_value(xe,ye,a_zz);
6564       points[3].set_value(xx,ye,a_zz);
6565       points[4].set_value(xx,yy,a_zz);
6566 
6567       //FIXME : have picking a hatch picks also the bin.
6568 
6569       hatcher _hatcher;
6570       _hatcher.set_offset_point(vec3f(0,0,a_zz));
6571       _hatcher.set_angle(a_style.angle.value());
6572       _hatcher.set_spacing(a_style.spacing.value());
6573       if(!_hatcher.set_strip_width(a_style.strip_width.value())) {}
6574 
6575       bool res = _hatcher.check_polyline(points,4);
6576       if(res) res = _hatcher.compute_polyline(points,4);
6577 
6578       size_t numPoints = _hatcher.points().size();
6579       size_t numVertices = _hatcher.vertices().size();
6580       if((res) && numPoints && numVertices) {
6581 
6582           const std::vector<vec3f>& _points = _hatcher.points();
6583 
6584           if(a_style.strip_width.value()==0) {
6585 
6586             size_t ipt = 0;
6587             tools_vforcit(unsigned int,_hatcher.vertices(),itv) {
6588               vertices* vtxs = new vertices;
6589               vtxs->mode = gl::line_strip();
6590               for(size_t _index=0;_index<(*itv);_index++) {
6591                 vtxs->add(_points[ipt]);
6592                 ipt++;
6593               }
6594               _sep->add(vtxs);
6595               empty = false;
6596             }
6597 
6598           } else {
6599             size_t ipt = 0;
6600             tools_vforcit(unsigned int,_hatcher.vertices(),itv) {
6601               vertices* vtxs = new vertices;
6602               vtxs->mode = gl::triangle_fan();
6603               for(size_t _index=0;_index<(*itv);_index++) {
6604                 vtxs->add(_points[ipt]);
6605                 ipt++;
6606               }
6607               _sep->add(vtxs);
6608               empty = false;
6609             }
6610           }
6611 
6612       }
6613     }
6614     if(empty) {
6615       delete _sep;
6616     } else {
6617       m_bins_sep.add(_sep);
6618     }
6619   }
6620 
6621   void rep_points2D_xy_lines(const style& a_style,const points2D& a_points,
6622                              const rep_box& a_box_x,const rep_box& a_box_y,float a_zz){
6623     float xmin = a_box_x.m_pos;
6624     float dx = a_box_x.m_width;
6625     bool xlog = a_box_x.m_log;
6626 
6627     float ymin = a_box_y.m_pos;
6628     float dy = a_box_y.m_width;
6629     bool ylog = a_box_y.m_log;
6630 
6631     separator* _sep = new separator();
6632 
6633     rgba* mat = new rgba();
6634     mat->color = a_style.color;
6635     _sep->add(mat);
6636 
6637     draw_style* ds = new draw_style;
6638     ds->style.value(draw_lines);
6639     ds->line_pattern.value(a_style.line_pattern);
6640     ds->line_width.value(a_style.line_width);
6641     _sep->add(ds);
6642 
6643     vertices* vtxs = new vertices;
6644     vtxs->mode = gl::line_strip();
6645     _sep->add(vtxs);
6646 
6647     bool empty = true;
6648 
6649     float x,y;
6650     unsigned int number = a_points.points();
6651     for(unsigned int index=0;index<number;index++) {
6652       a_points.ith_point(index,x,y);
6653       x = verify_log(x,xmin,dx,xlog);
6654       y = verify_log(y,ymin,dy,ylog);
6655       if((x<0)||(x>1)||(y<0)||(y>1)) continue;
6656       vtxs->add(x,y,a_zz);
6657       empty = false;
6658     }
6659 
6660     if(empty) {
6661       delete _sep;
6662     } else {
6663       m_points_sep.add(_sep);
6664     }
6665   }
6666 
6667   void rep_points2D_xy_curve(std::ostream& a_out,const style& a_style,const points2D& a_points,
6668                              const rep_box& a_box_x,const rep_box& a_box_y,float a_zz){
6669     unsigned int number = a_points.points();
6670     if(!number) return;
6671 
6672     double* xs = new double[number];
6673     double* ys = new double[number];
6674     float x,y;
6675    {for(unsigned int index=0;index<number;index++) {
6676       a_points.ith_point(index,x,y);
6677       xs[index] = x;ys[index] = y;
6678     }}
6679     spline::cubic _spline(a_out,number,xs,ys);
6680     delete [] xs;delete [] ys;
6681 
6682     float xmn = m_x_axis_data.min_value();
6683     float xmx = m_x_axis_data.max_value();
6684     unsigned int nstp = curve_number_of_points;
6685     float step = (xmx - xmn)/nstp;
6686     std::vector<vec3f> points(nstp+1);
6687     for(unsigned int ibin=0;ibin<=nstp;ibin++) {
6688       float xx = xmn + ibin * step;
6689       double val = _spline.eval(xx);
6690       points[ibin].set_value(xx,float(val),a_zz);
6691     }
6692 
6693     vertices* vtxs = new vertices;
6694     std::vector<float>& pts = vtxs->xyzs.values(); //npt*3
6695 
6696     clip_polyline_2D(points,a_box_x,a_box_y,pts);
6697     if(pts.size()) {
6698       sg::separator* separator = new sg::separator;
6699 
6700       rgba* mat = new rgba();
6701       mat->color = a_style.color;
6702       separator->add(mat);
6703 
6704       draw_style* ds = new draw_style;
6705       ds->style = draw_lines;
6706       ds->line_pattern = a_style.line_pattern;
6707       ds->line_width = a_style.line_width;
6708       separator->add(ds);
6709 
6710       vtxs->mode = gl::line_strip();
6711       separator->add(vtxs);
6712 
6713       m_points_sep.add(separator);
6714     } else {
6715       delete vtxs;
6716     }
6717 
6718   }
6719 
6720   void rep_points2D_xy_points(std::ostream& a_out,
6721                               const style& a_style,const points2D& a_points,
6722                               const rep_box& a_box_x,const rep_box& a_box_y,float a_zz) {
6723     float xmin = a_box_x.m_pos;
6724     float dx = a_box_x.m_width;
6725     bool xlog = a_box_x.m_log;
6726 
6727     float ymin = a_box_y.m_pos;
6728     float dy = a_box_y.m_width;
6729     bool ylog = a_box_y.m_log;
6730 
6731     separator* _sep = new separator();
6732 
6733     rgba* mat = new rgba();
6734     mat->color = a_style.color;
6735     _sep->add(mat);
6736 
6737     mf<float>* _xyzs = 0;
6738 
6739     if(a_style.modeling==modeling_markers()) {
6740       markers* _marks = new markers;
6741       _marks->size = a_style.marker_size;
6742       _marks->style = a_style.marker_style;
6743       _xyzs = &(_marks->xyzs);
6744       _sep->add(_marks);
6745 
6746     } else if(a_style.modeling==modeling_points()) {
6747       draw_style* ds = new draw_style;
6748       ds->style = draw_points;
6749       ds->point_size = a_style.point_size;
6750       _sep->add(ds);
6751 
6752       vertices* vtxs = new vertices;
6753       vtxs->mode = gl::points();
6754       _xyzs = &(vtxs->xyzs);
6755       _sep->add(vtxs);
6756     } else {
6757       a_out << "tools::sg::plotter::rep_points2D_xy_points :"
6758             << " bad modeling style " << tools::sout(a_style.modeling) << std::endl;
6759       delete _sep;
6760       return;
6761     }
6762 
6763     float x,y;
6764 
6765     // first round trip to get number of floats :
6766     size_t npts = 0;
6767    {unsigned int number = a_points.points();
6768     for(unsigned int index=0;index<number;index++) {
6769       a_points.ith_point(index,x,y);
6770       x = verify_log(x,xmin,dx,xlog);
6771       y = verify_log(y,ymin,dy,ylog);
6772       if((x<0)||(x>1)||(y<0)||(y>1)) continue;
6773       npts += 3;
6774     }}
6775 
6776     _xyzs->values().resize(npts);
6777     size_t xyz_pos = 0;
6778 
6779     bool empty = true;
6780 
6781    {unsigned int number = a_points.points();
6782     for(unsigned int index=0;index<number;index++) {
6783       a_points.ith_point(index,x,y);
6784       x = verify_log(x,xmin,dx,xlog);
6785       y = verify_log(y,ymin,dy,ylog);
6786       if((x<0)||(x>1)||(y<0)||(y>1)) continue;
6787       _xyzs->add_allocated(xyz_pos,x,y,a_zz);
6788       empty = false;
6789     }}
6790 
6791     if(empty) {
6792       delete _sep;
6793     } else {
6794       m_points_sep.add(_sep);
6795     }
6796   }
6797 
6798   void rep_points3D_xyz_points(std::ostream& a_out,
6799                                const style& a_style,const points3D& a_points,
6800                                const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z) {
6801     float xmin = a_box_x.m_pos;
6802     float dx = a_box_x.m_width;
6803     bool xlog = a_box_x.m_log;
6804 
6805     float ymin = a_box_y.m_pos;
6806     float dy = a_box_y.m_width;
6807     bool ylog = a_box_y.m_log;
6808 
6809     float zmin = a_box_z.m_pos;
6810     float dz = a_box_z.m_width;
6811     bool zlog = a_box_z.m_log;
6812 
6813     separator* _sep = new separator();
6814 
6815     rgba* mat = new rgba();
6816     mat->color = a_style.color;
6817     _sep->add(mat);
6818 
6819     mf<float>* _xyzs = 0;
6820 
6821     if(a_style.modeling==modeling_markers()) {
6822       markers* _marks = new markers;
6823       _marks->size = a_style.marker_size;
6824       _marks->style = a_style.marker_style;
6825       _xyzs = &(_marks->xyzs);
6826       _sep->add(_marks);
6827 
6828     } else if(a_style.modeling==modeling_points()) {
6829       draw_style* ds = new draw_style;
6830       ds->style = draw_points;
6831       ds->point_size = a_style.point_size;
6832       _sep->add(ds);
6833 
6834       vertices* vtxs = new vertices;
6835       vtxs->mode = gl::points();
6836       _xyzs = &(vtxs->xyzs);
6837       _sep->add(vtxs);
6838     } else {
6839       a_out << "tools::sg::plotter::rep_points3D_xy_points :"
6840             << " bad modeling style " << tools::sout(a_style.modeling) << std::endl;
6841       delete _sep;
6842       return;
6843     }
6844 
6845     float x,y,z;
6846 
6847     // first round trip to get number of floats :
6848     size_t npts = 0;
6849    {unsigned int number = a_points.points();
6850     for(unsigned int index=0;index<number;index++) {
6851       a_points.ith_point(index,x,y,z);
6852       //float val = a_bins[index].m_val;
6853       x = verify_log(x,xmin,dx,xlog);
6854       y = verify_log(y,ymin,dy,ylog);
6855       z = verify_log(z,zmin,dz,zlog);
6856       if((x<0)||(x>1)||(y<0)||(y>1)||(z<0)||(z>1)) continue;
6857       npts += 3;
6858     }}
6859 
6860     _xyzs->values().resize(npts);
6861     size_t xyz_pos = 0;
6862 
6863     bool empty = true;
6864 
6865    {unsigned int number = a_points.points();
6866     for(unsigned int index=0;index<number;index++) {
6867       a_points.ith_point(index,x,y,z);
6868       //float val = a_bins[index].m_val;
6869       x = verify_log(x,xmin,dx,xlog);
6870       y = verify_log(y,ymin,dy,ylog);
6871       z = verify_log(z,zmin,dz,zlog);
6872       if((x<0)||(x>1)||(y<0)||(y>1)||(z<0)||(z>1)) continue;
6873       _xyzs->add_allocated(xyz_pos,x,y,z);
6874       empty = false;
6875     }}
6876 
6877     if(empty) {
6878       delete _sep;
6879     } else {
6880       m_points_sep.add(_sep);
6881     }
6882   }
6883 
6884   void rep_bins2D_xyz_box(const style& a_style,const base_colormap& a_cmap,const std::vector<rep_bin2D>& a_bins,
6885                           const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_bmin,float /*a_bmax*/){
6886     float xmin = a_box_x.m_pos;
6887     float dx = a_box_x.m_width;
6888     bool xlog = a_box_x.m_log;
6889 
6890     float ymin = a_box_y.m_pos;
6891     float dy = a_box_y.m_width;
6892     bool ylog = a_box_y.m_log;
6893 
6894     float zmin = a_box_z.m_pos;
6895     float dz = a_box_z.m_width;
6896     bool zlog = a_box_z.m_log;
6897 
6898     painting_policy painting = a_style.painting;
6899 
6900     separator* _sep = new separator();
6901 
6902     bool empty = true;
6903     colorf clr;
6904 
6905     tools_vforcit(rep_bin2D,a_bins,it) {
6906       const rep_bin2D& rbin = *it;
6907 
6908       float xx = rbin.m_x_min;
6909       float xe = rbin.m_x_max;
6910       float yy = rbin.m_y_min;
6911       float ye = rbin.m_y_max;
6912       float val = rbin.m_val;
6913       float zz = a_bmin;
6914       float ze = val;
6915 
6916       xx = verify_log(xx ,xmin,dx  ,xlog);
6917       xe = verify_log(xe ,xmin,dx  ,xlog);
6918       yy = verify_log(yy ,ymin,dy  ,ylog);
6919       ye = verify_log(ye ,ymin,dy  ,ylog);
6920       zz = verify_log(zz ,zmin,dz  ,zlog);
6921       ze = verify_log(ze ,zmin,dz  ,zlog);
6922 
6923       // Clipping :
6924       if(xx>1) continue;
6925       if(xe<0) continue;
6926       if(xx<0) xx = 0;
6927       if(xe>1) xe = 1;
6928 
6929       if(yy>1) continue;
6930       if(ye<0) continue;
6931       if(yy<0) yy = 0;
6932       if(ye>1) ye = 1;
6933 
6934       if(zz>1) continue;
6935       if(ze<0) continue;
6936       if(zz<0) zz = 0;
6937       if(ze>1) ze = 1;
6938 
6939       if(yy>=ye) continue;
6940       if(xx>=xe) continue;
6941       if(zz>=ze) continue;
6942 
6943       separator* sep = new separator();
6944       _sep->add(sep);
6945 
6946       if(painting==painting_by_value) {
6947         a_cmap.get_color(val,clr);
6948       } else if( (painting==painting_grey_scale) ||
6949                  (painting==painting_grey_scale_inverse) ||
6950                  (painting==painting_violet_to_red) ){
6951         a_cmap.get_color(rbin.m_ratio,clr);
6952       } else {
6953         clr = a_style.color;
6954       }
6955 
6956       rgba* mat = new rgba();
6957       mat->color = clr;
6958       sep->add(mat);
6959 
6960       float sx = xe-xx;
6961       float sy = ye-yy;
6962       float sz = ze-zz;
6963 
6964       matrix* _tsf = new matrix;
6965       _tsf->set_translate(xx+sx/2,yy+sy/2,sz/2);
6966       sep->add(_tsf);
6967 
6968       cube* _cube = new cube;
6969       _cube->width = sx;
6970       _cube->height = sy;
6971       _cube->depth = sz;
6972       sep->add(_cube);
6973 
6974       empty = false;
6975     }
6976 
6977     if(empty) {
6978       delete _sep;
6979     } else {
6980       m_bins_sep.add(_sep);
6981     }
6982   }
6983 
6984   void rep_top_face2D_xyz(separator& a_sep,const style& a_style,const base_colormap& a_cmap,
6985                           const std::vector<rep_top_face2D>& a_faces,
6986                           const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z) {
6987     float xmin = a_box_x.m_pos;
6988     float dx = a_box_x.m_width;
6989     bool xlog = a_box_x.m_log;
6990 
6991     float ymin = a_box_y.m_pos;
6992     float dy = a_box_y.m_width;
6993     bool ylog = a_box_y.m_log;
6994 
6995     float zmin = a_box_z.m_pos;
6996     float dz = a_box_z.m_width;
6997     bool zlog = a_box_z.m_log;
6998 
6999     bool empty = true;
7000 
7001     painting_policy painting = a_style.painting;
7002 
7003     separator* _sep = new separator();
7004 
7005     atb_vertices* vtxs = new atb_vertices;
7006     vtxs->mode = gl::triangles();
7007     vtxs->do_back = true;
7008     vtxs->epsilon = 1e-6f;
7009     _sep->add(vtxs);
7010 
7011     colorf clr;
7012     vec3f nm;
7013 
7014     size_t number = a_faces.size();
7015     for(size_t index=0;index<number;index++) {
7016       float xx = a_faces[index].m_x_min;
7017       float xe = a_faces[index].m_x_max;
7018       float yy = a_faces[index].m_y_min;
7019       float ye = a_faces[index].m_y_max;
7020       float val1 = a_faces[index].m_v1;
7021       float val2 = a_faces[index].m_v2;
7022       float val3 = a_faces[index].m_v3;
7023       float val4 = a_faces[index].m_v4;
7024 
7025       float val = val1;
7026 
7027       val1 = verify_log(val1,zmin,dz,zlog);
7028       val2 = verify_log(val2,zmin,dz,zlog);
7029       val3 = verify_log(val3,zmin,dz,zlog);
7030       val4 = verify_log(val4,zmin,dz,zlog);
7031       xx = verify_log(xx,xmin,dx,xlog);
7032       xe = verify_log(xe,xmin,dx,xlog);
7033       yy = verify_log(yy,ymin,dy,ylog);
7034       ye = verify_log(ye,ymin,dy,ylog);
7035 
7036       if(val1<0) val1 = 0;
7037       if(val1>1) val1 = 1;
7038 
7039       if(val2<0) val2 = 0;
7040       if(val2>1) val2 = 1;
7041 
7042       if(val3<0) val3 = 0;
7043       if(val3>1) val3 = 1;
7044 
7045       if(val4<0) val4 = 0;
7046       if(val4>1) val4 = 1;
7047 
7048       if((xx>=0)&&(xx<=1)   &&
7049          (xe>=0)&&(xe<=1)   &&
7050          (yy>=0)&&(yy<=1)   &&
7051          (ye>=0)&&(ye<=1)  ) {
7052 
7053         if(painting==painting_by_value) {
7054           float v = (zlog?take_log(val):val);
7055           a_cmap.get_color(v,clr);
7056         } else if( (painting==painting_grey_scale) ||
7057                    (painting==painting_grey_scale_inverse) ||
7058                    (painting==painting_violet_to_red) ){
7059           a_cmap.get_color(a_faces[index].m_ratio,clr);
7060         } else {
7061           clr = a_style.color;
7062         }
7063 
7064         //////////////////////////////////////
7065         //////////////////////////////////////
7066         vtxs->add(xx,ye,val4);
7067         vtxs->add(xx,yy,val1);
7068         vtxs->add(xe,yy,val2);
7069 
7070         vtxs->add_color(clr);
7071         vtxs->add_color(clr);
7072         vtxs->add_color(clr);
7073 
7074         direction(xx,ye,val4,
7075                   xx,yy,val1,
7076                   xe,yy,val2,nm);
7077         nm.normalize();
7078         vtxs->add_normal(nm[0],nm[1],nm[2]);
7079         vtxs->add_normal(nm[0],nm[1],nm[2]);
7080         vtxs->add_normal(nm[0],nm[1],nm[2]);
7081 
7082         //////////////////////////////////////
7083         //////////////////////////////////////
7084         vtxs->add(xe,yy,val2);
7085         vtxs->add(xe,ye,val3);
7086         vtxs->add(xx,ye,val4);
7087 
7088         vtxs->add_rgba(clr[0],clr[1],clr[2],clr[3]);
7089         vtxs->add_rgba(clr[0],clr[1],clr[2],clr[3]);
7090         vtxs->add_rgba(clr[0],clr[1],clr[2],clr[3]);
7091 
7092         direction(xe,yy,val2,
7093                   xe,ye,val3,
7094                   xx,ye,val4,nm);
7095         nm.normalize();
7096         vtxs->add_normal(nm[0],nm[1],nm[2]);
7097         vtxs->add_normal(nm[0],nm[1],nm[2]);
7098         vtxs->add_normal(nm[0],nm[1],nm[2]);
7099 
7100         empty = false;
7101       }
7102     }
7103     if(empty) {
7104       delete _sep;
7105     } else {
7106       a_sep.add(_sep);
7107     }
7108   }
7109 
7110   void rep_top_face2D_xyz_line(const style& /*a_style*/,const std::vector<rep_top_face2D>& a_top_faces,
7111                                const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z/*,const SbString& aID*/){
7112     float xmin = a_box_x.m_pos;
7113     float dx = a_box_x.m_width;
7114     bool xlog = a_box_x.m_log;
7115 
7116     float ymin = a_box_y.m_pos;
7117     float dy = a_box_y.m_width;
7118     bool ylog = a_box_y.m_log;
7119 
7120     float zmin = a_box_z.m_pos;
7121     float dz = a_box_z.m_width;
7122     bool zlog = a_box_z.m_log;
7123 
7124     sg::separator* separator = new sg::separator;
7125     bool empty = true;
7126 
7127     rgba* mat = new rgba();
7128     mat->color = colorf_black();
7129     separator->add(mat);
7130 
7131     draw_style* ds = new draw_style;
7132     ds->style = draw_lines;
7133     ds->line_pattern = line_solid;
7134     ds->line_width = 1;
7135     separator->add(ds);
7136 
7137     vertices* vtxs = new vertices;
7138     vtxs->mode = gl::lines();
7139     separator->add(vtxs);
7140 
7141     float zepsilon = 0.02f; //for pawex9.kumac top-left and bottom-right.
7142 
7143     size_t number = a_top_faces.size();
7144     for(size_t index=0;index<number;index++) {
7145       float xx = a_top_faces[index].m_x_min;
7146       float xe = a_top_faces[index].m_x_max;
7147       float yy = a_top_faces[index].m_y_min;
7148       float ye = a_top_faces[index].m_y_max;
7149       float val1 = a_top_faces[index].m_v1;
7150       float val2 = a_top_faces[index].m_v2;
7151       float val3 = a_top_faces[index].m_v3;
7152       float val4 = a_top_faces[index].m_v4;
7153 
7154       val1 = verify_log(val1,zmin,dz,zlog);
7155       val2 = verify_log(val2,zmin,dz,zlog);
7156       val3 = verify_log(val3,zmin,dz,zlog);
7157       val4 = verify_log(val4,zmin,dz,zlog);
7158       xx = verify_log(xx,xmin,dx,xlog);
7159       xe = verify_log(xe,xmin,dx,xlog);
7160       yy = verify_log(yy,ymin,dy,ylog);
7161       ye = verify_log(ye,ymin,dy,ylog);
7162 
7163       if(val1<0) val1 = 0;
7164       if(val1>1) val1 = 1;
7165 
7166       if(val2<0) val2 = 0;
7167       if(val2>1) val2 = 1;
7168 
7169       if(val3<0) val3 = 0;
7170       if(val3>1) val3 = 1;
7171 
7172       if(val4<0) val4 = 0;
7173       if(val4>1) val4 = 1;
7174 
7175       if((xx>=0)&&(xx<=1)   &&
7176          (xe>=0)&&(xe<=1)   &&
7177          (yy>=0)&&(yy<=1)   &&
7178          (ye>=0)&&(ye<=1)  ) {
7179 
7180         vtxs->add(xx,ye,val4+zepsilon);
7181         vtxs->add(xx,yy,val1+zepsilon);
7182 
7183         vtxs->add(xx,yy,val1+zepsilon);
7184         vtxs->add(xe,yy,val2+zepsilon);
7185 
7186         vtxs->add(xe,yy,val2+zepsilon);
7187         vtxs->add(xe,ye,val3+zepsilon);
7188 
7189         vtxs->add(xe,ye,val3+zepsilon);
7190         vtxs->add(xx,ye,val4+zepsilon);
7191 
7192         empty = false;
7193 
7194       }
7195     }
7196     if(empty) {
7197       delete separator;
7198     } else {
7199       m_bins_sep.add(separator);
7200     }
7201   }
7202 
7203   void rep_top_face2D_xyz_by_level(const style& /*a_style*/,painting_policy /*a_painting*/,const base_colormap& a_cmap,
7204                                    const std::vector<rep_top_face2D>& a_top_faces,
7205                                    const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,
7206                                    float a_bmin,float a_bmax/*,const SbString& aID*/){
7207     size_t ncol = a_cmap.colorn();
7208     if(!ncol) return;
7209 
7210     float xmin = a_box_x.m_pos;
7211     float dx = a_box_x.m_width;
7212     bool xlog = a_box_x.m_log;
7213 
7214     float ymin = a_box_y.m_pos;
7215     float dy = a_box_y.m_width;
7216     bool ylog = a_box_y.m_log;
7217 
7218     float zmin = a_box_z.m_pos;
7219     float dz = a_box_z.m_width;
7220     bool zlog = a_box_z.m_log;
7221 
7222     float zz = a_bmin;
7223     zz = verify_log(zz,zmin,dz,zlog);
7224     float zmx = a_bmax;
7225     zmx = verify_log(zmx,zmin,dz,zlog);
7226 
7227     bool empty = true;
7228 
7229     sg::separator* separator = new sg::separator;
7230 
7231     atb_vertices* tris = new atb_vertices;
7232     tris->mode = gl::triangles();
7233     tris->do_back = true;
7234     tris->epsilon = 1e-6f;
7235     separator->add(tris);
7236 
7237     colorf _color;
7238     vec3f _point;
7239 
7240     float d_z = (zmx-zz)/ncol;
7241 
7242     size_t number = a_top_faces.size();
7243 
7244     for(size_t icol=0;icol<ncol;icol++) {
7245       _color = a_cmap.color(icol);
7246 
7247       for(size_t index=0;index<number;index++) {
7248         float xx = a_top_faces[index].m_x_min;
7249         float xe = a_top_faces[index].m_x_max;
7250         float yy = a_top_faces[index].m_y_min;
7251         float ye = a_top_faces[index].m_y_max;
7252         float val1 = a_top_faces[index].m_v1;
7253         float val2 = a_top_faces[index].m_v2;
7254         float val3 = a_top_faces[index].m_v3;
7255         float val4 = a_top_faces[index].m_v4;
7256 
7257         val1 = verify_log(val1,zmin,dz,zlog);
7258         val2 = verify_log(val2,zmin,dz,zlog);
7259         val3 = verify_log(val3,zmin,dz,zlog);
7260         val4 = verify_log(val4,zmin,dz,zlog);
7261         xx = verify_log(xx,xmin,dx,xlog);
7262         xe = verify_log(xe,xmin,dx,xlog);
7263         yy = verify_log(yy,ymin,dy,ylog);
7264         ye = verify_log(ye,ymin,dy,ylog);
7265 
7266         if(val1<0) val1 = 0;
7267         if(val1>1) val1 = 1;
7268 
7269         if(val2<0) val2 = 0;
7270         if(val2>1) val2 = 1;
7271 
7272         if(val3<0) val3 = 0;
7273         if(val3>1) val3 = 1;
7274 
7275         if(val4<0) val4 = 0;
7276         if(val4>1) val4 = 1;
7277 
7278         if((xx>=0)&&(xx<=1)   &&
7279            (xe>=0)&&(xe<=1)   &&
7280            (yy>=0)&&(yy<=1)   &&
7281            (ye>=0)&&(ye<=1)  ) {
7282 
7283           //////////////////////////////////////
7284           //////////////////////////////////////
7285          {clip<vec3f> clipper;
7286           clipper.add(vec3f(xx,ye,val4));
7287           clipper.add(vec3f(xx,yy,val1));
7288           clipper.add(vec3f(xe,yy,val2));
7289           //val[n] had been z normalized.
7290           float z1 = zz+d_z*icol;
7291           float z2 = z1+d_z;
7292           plane<vec3f> plane_z_bot(vec3f(0,0,1),vec3f(0,0,z1));
7293           plane<vec3f> plane_z_top(vec3f(0,0,-1),vec3f(0,0,z2));
7294           clipper.execute(plane_z_bot);
7295           clipper.execute(plane_z_top);
7296 
7297           const std::vector<vec3f>& result = clipper.result();
7298           if(result.size()) {
7299             plane<vec3f> plane1(vec3f(xx,ye,val4),vec3f(xx,yy,val1),vec3f(xe,yy,val2));
7300             if(result.size()==3) {
7301               tools_vforcit(vec3f,result,it) {
7302                 tris->add(*it);
7303                 tris->add_color(_color);
7304                 tris->add_normal(plane1.normal());
7305               }
7306             } else {
7307               atb_vertices* vtxs = new atb_vertices; //FIXME : ouch! optimize.
7308               vtxs->mode = gl::triangle_fan();
7309               vtxs->do_back = true;
7310               vtxs->epsilon = 1e-6f;
7311               separator->add(vtxs);
7312               tools_vforcit(vec3f,result,it) {
7313                 vtxs->add(*it);
7314                 vtxs->add_color(_color);
7315                 vtxs->add_normal(plane1.normal());
7316               }
7317           }
7318             empty = false;
7319           }}
7320 
7321           //////////////////////////////////////
7322           //////////////////////////////////////
7323          {clip<vec3f> clipper;
7324           clipper.add(vec3f(xe,yy,val2));
7325           clipper.add(vec3f(xe,ye,val3));
7326           clipper.add(vec3f(xx,ye,val4));
7327           //val[n] had been z normalized.
7328           float z1 = zz+d_z*icol;
7329           float z2 = z1+d_z;
7330           plane<vec3f> plane_z_bot(vec3f(0,0,1),vec3f(0,0,z1));
7331           plane<vec3f> plane_z_top(vec3f(0,0,-1),vec3f(0,0,z2));
7332           clipper.execute(plane_z_bot);
7333           clipper.execute(plane_z_top);
7334 
7335           const std::vector<vec3f>& result = clipper.result();
7336           if(result.size()) {
7337             plane<vec3f> plane2(vec3f(xe,yy,val2),vec3f(xe,ye,val3),vec3f(xx,ye,val4));
7338             if(result.size()==3) {
7339               tools_vforcit(vec3f,result,it) {
7340                 tris->add(*it);
7341                 tris->add_color(_color);
7342                 tris->add_normal(plane2.normal());
7343               }
7344             } else {
7345               atb_vertices* vtxs = new atb_vertices; //FIXME : ouch! optimize.
7346               vtxs->mode = gl::triangle_fan();
7347               vtxs->do_back = true;
7348               vtxs->epsilon = 1e-6f;
7349               separator->add(vtxs);
7350               tools_vforcit(vec3f,result,it) {
7351                 vtxs->add(*it);
7352                 vtxs->add_color(_color);
7353                 vtxs->add_normal(plane2.normal());
7354               }
7355             }
7356             empty = false;
7357           }}
7358         }
7359 
7360       } //index faces
7361     } //icol
7362 
7363     if(empty) {
7364       delete separator;
7365     } else {
7366       m_bins_sep.add(separator);
7367     }
7368   }
7369 
7370   // for OpenPAW /GRAPHICS/PRIMITIVES/TEXT
7371   // for OpenPAW /GRAPHICS/PRIMITIVES/ITX
7372   void update_primitive_text(const plottable_text& a_obj){
7373     if(a_obj.m_TEXT.empty()) return;
7374 
7375     float z = xy_depth.value()*1.1F;
7376 
7377     vec3f pos;
7378     axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y,z),pos); //FIXME return FALSE
7379     xx_2_yy(pos,pos);
7380 
7381     separator* sep = new separator;
7382 
7383     rgba* mat = new rgba();
7384     mat->color = a_obj.m_TXCI;
7385     sep->add(mat);
7386 
7387     matrix* _tsf = new matrix;
7388     _tsf->set_translate(pos);
7389     _tsf->mul_rotate(0,0,1,a_obj.m_ANGLE*fpi()/180.0f);
7390     _tsf->mul_scale(a_obj.m_SCALE,a_obj.m_SCALE,1);
7391     sep->add(_tsf);
7392 
7393     //SIZE is in page coordinate YSIZ.
7394     //float YSIZ = height.value();
7395     //if(YSIZ<=0) YSIZ = 1;
7396 
7397     if(a_obj.m_text_mode==plottable_text::text_enforce_width) {  // not tested yet.
7398 
7399       vec3f pos2;
7400       axis_2_data_frame(vec3f(a_obj.m_X+a_obj.m_SIZE,a_obj.m_Y,z),pos2);  //m_SIZE is taken as text width in this text_mode.
7401       xx_2_yy(pos2,pos2);
7402 
7403       float _width = pos2.x()-pos.x();
7404 
7405       text* _text = new text(m_ttf);
7406       _text->enforce_front_width = true;  //it will set _text->width, height.
7407       _text->front_width = _width;
7408       _text->back_visible = false;
7409 
7410       _text->encoding = encoding_PAW();
7411       _text->strings.add(a_obj.m_TEXT);
7412       _text->line_width = a_obj.m_line_width;
7413       _text->font = a_obj.m_FONT;
7414       _text->font_modeling = a_obj.m_font_modeling;
7415 
7416       if(a_obj.m_HJUST=='R') {
7417         _text->hjust = right;
7418       } else if(a_obj.m_HJUST=='C') {
7419         _text->hjust = center;
7420       } else {
7421         _text->hjust = left;
7422       }
7423       if(a_obj.m_VJUST=='T') {
7424         _text->vjust = top;
7425       } else if(a_obj.m_VJUST=='M') {
7426         _text->vjust = middle;
7427       } else {
7428         _text->vjust = bottom;
7429       }
7430 
7431       sep->add(_text);
7432 
7433     } else if(a_obj.m_text_mode==plottable_text::text_enforce_height) { // for EsbRootView neard, fard 2D plot.
7434 
7435       vec3f pos2;
7436       axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y+a_obj.m_SIZE,z),pos2);  //m_SIZE is taken as text height in this text_mode.
7437       xx_2_yy(pos2,pos2);
7438 
7439       float _height = pos2.y()-pos.y();
7440 
7441       text* _text = new text(m_ttf);
7442       _text->enforce_front_height = true;  //it will set _text->width, height.
7443       _text->front_height = _height;
7444       _text->back_visible = false;  //if true, we should adapt back_area::width, height to inside text size.
7445 
7446       _text->encoding = encoding_PAW();
7447       _text->strings.add(a_obj.m_TEXT);
7448       _text->line_width = a_obj.m_line_width;
7449       _text->font = a_obj.m_FONT;
7450       _text->font_modeling = a_obj.m_font_modeling;
7451 
7452       if(a_obj.m_HJUST=='R') {
7453         _text->hjust = right;
7454       } else if(a_obj.m_HJUST=='C') {
7455         _text->hjust = center;
7456       } else {
7457         _text->hjust = left;
7458       }
7459       if(a_obj.m_VJUST=='T') {
7460         _text->vjust = top;
7461       } else if(a_obj.m_VJUST=='M') {
7462         _text->vjust = middle;
7463       } else {
7464         _text->vjust = bottom;
7465       }
7466 
7467       sep->add(_text);
7468 
7469     } else { //text_as_it (for gopaw/pagpri.cpp).
7470       _tsf->mul_scale(a_obj.m_SIZE,a_obj.m_SIZE,1);
7471 
7472       if(a_obj.m_FONT==font_hershey()) {
7473         draw_style* ds = new draw_style;
7474         ds->style = draw_lines;
7475         ds->line_pattern = line_solid;
7476         ds->line_width = a_obj.m_line_width;
7477         sep->add(ds);
7478 
7479         text_hershey* text = new text_hershey;
7480         text->encoding = encoding_PAW();
7481         text->strings.add(a_obj.m_TEXT);
7482         if(a_obj.m_HJUST=='R') {
7483           text->hjust = right;
7484         } else if(a_obj.m_HJUST=='C') {
7485           text->hjust = center;
7486         } else {
7487           text->hjust = left;
7488         }
7489         if(a_obj.m_VJUST=='T') {
7490           text->vjust = top;
7491         } else if(a_obj.m_VJUST=='M') {
7492           text->vjust = middle;
7493         } else {
7494           text->vjust = bottom;
7495         }
7496         sep->add(text);
7497 
7498       } else {
7499         base_freetype* text = base_freetype::create(m_ttf);
7500 
7501         text->font = a_obj.m_FONT;
7502         if(a_obj.m_HJUST=='R') {
7503           text->hjust = right;
7504         } else if(a_obj.m_HJUST=='C') {
7505           text->hjust = center;
7506         } else {
7507           text->hjust = left;
7508         }
7509         if(a_obj.m_VJUST=='T') {
7510           text->vjust = top;
7511         } else if(a_obj.m_VJUST=='M') {
7512           text->vjust = middle;
7513         } else {
7514           text->vjust = bottom;
7515         }
7516 
7517         text->modeling = a_obj.m_font_modeling;
7518 
7519         text->strings.add(a_obj.m_TEXT);
7520 
7521         sep->add(text);
7522       }
7523 
7524     } //text_mode.
7525 
7526     m_primitives_sep.add(sep);
7527   }
7528 
7529   // for OpenPAW /GRAPHICS/PRIMITIVES/BOX
7530   void PAW_hatch(int aHTYP,hatching_policy& a_policy,float& a_spacing,float& a_angle_right,float& a_angle_left) {
7531     // PAW hatching encoding (paw.pdf 1.14(1992) p 174) :
7532 
7533     a_policy = hatching_none;
7534     a_spacing = 0;
7535     a_angle_right = 0;
7536     a_angle_left = 0;
7537 
7538     int code = aHTYP;
7539     if(code==0) return;
7540 
7541     // From PAW FAQ web page.
7542     // special code from code [1,25]
7543     if(code==1) {
7544       a_policy = hatching_left_and_right;
7545       a_spacing = 0.04F;
7546       a_angle_right = 3.0F*fpi()/4.0F;
7547       a_angle_left = fpi()/4.0F;
7548       return;
7549     } else if(code==2) {
7550       a_policy = hatching_left_and_right;
7551       a_spacing = 0.08F;
7552       a_angle_right = 3.0F*fpi()/4.0F;
7553       a_angle_left = fpi()/4.0F;
7554       return;
7555     } else if(code==3) {
7556       a_policy = hatching_left_and_right;
7557       a_spacing = 1.6f*0.07F; //cooking
7558       a_angle_right = 3.0F*fpi()/4.0F;
7559       a_angle_left = fpi()/4.0F;
7560       return;
7561     } else if(code==4) {
7562       code = 354;
7563     } else if(code==5) {
7564       code = 345;
7565     } else if(code==6) {
7566       code = 359;
7567     } else if(code==7) {
7568       code = 350;
7569     } else if(code<=25) {
7570       //FIXME : seems to be done with patterns.
7571       a_policy = hatching_none;
7572       return;
7573     } else if(code<=99) {
7574       //FIXME
7575       a_policy = hatching_none;
7576       return;
7577     }
7578 
7579     int i = code / 100;
7580     int j = (code - i * 100)/10;
7581     int k = code - i * 100 - j * 10;
7582 
7583     // j-hatching on rightHatchStyle :
7584     // k-hatching on leftHatchStyle :
7585 
7586     if((j==5)&&(k==5))
7587       a_policy = hatching_none;
7588     else if((j!=5)&&(k==5))
7589       a_policy = hatching_right;
7590     else if((j==5)&&(k!=5))
7591       a_policy = hatching_left;
7592     else if((j!=5)&&(k!=5))
7593       a_policy = hatching_left_and_right;
7594 
7595     unsigned int NY = 1;
7596 
7597     a_spacing = float(NY) * float(i) * 0.07F; //cooking
7598 
7599     if(j!=5) {
7600       float angle = float(j==4?45:j*10);
7601       angle = 180.0F - angle;
7602       angle *= fpi() / 180.0F;
7603 
7604       a_angle_right = angle;
7605     }
7606 
7607     if(k!=5) {
7608       float angle = float(k==4?45:k*10);
7609       angle *= fpi() / 180.0F;
7610       a_angle_left = angle;
7611     }
7612 
7613   }
7614 
7615   void rep_box_hatch(separator& a_parent,float a_spacing,float a_angle,float a_strip_width,
7616                      float xx,float yy,float xe,float ye,float a_zz){
7617 
7618     sg::separator* separator = new sg::separator;
7619 
7620     bool empty = true;
7621 
7622     vec3f points[5];
7623 
7624     points[0].set_value(xx,yy,a_zz);
7625     points[1].set_value(xe,yy,a_zz);
7626     points[2].set_value(xe,ye,a_zz);
7627     points[3].set_value(xx,ye,a_zz);
7628     points[4].set_value(xx,yy,a_zz);
7629 
7630     //We can have multiple hatching for a bins ; have a separator :
7631     hatcher _hatcher;
7632     _hatcher.set_offset_point(vec3f(0,0,a_zz));
7633     _hatcher.set_angle(a_angle);
7634     _hatcher.set_spacing(a_spacing);
7635     if(!_hatcher.set_strip_width(a_strip_width)) {}
7636 
7637     bool res = _hatcher.check_polyline(points,4);
7638     if(res) res = _hatcher.compute_polyline(points,4);
7639 
7640     size_t numPoints = _hatcher.points().size();
7641     size_t numVertices = _hatcher.vertices().size();
7642     if((res) && numPoints && numVertices) {
7643 
7644       const std::vector<vec3f>& _points = _hatcher.points();
7645 
7646       if(a_strip_width==0) {
7647         size_t ipt = 0;
7648         tools_vforcit(unsigned int,_hatcher.vertices(),itv) {
7649           vertices* vtxs = new vertices;
7650           vtxs->mode = gl::line_strip();
7651           for(size_t index=0;index<(*itv);index++) {
7652             vtxs->add(_points[ipt]);
7653             ipt++;
7654                 }
7655           separator->add(vtxs);
7656           empty = false;
7657         }
7658 
7659       } else {
7660         size_t ipt = 0;
7661         tools_vforcit(unsigned int,_hatcher.vertices(),itv) {
7662           vertices* vtxs = new vertices;
7663           vtxs->mode = gl::triangle_fan();
7664           for(size_t index=0;index<(*itv);index++) {
7665             vtxs->add(_points[ipt]);
7666             ipt++;
7667           }
7668           separator->add(vtxs);
7669           empty = false;
7670         }
7671       }
7672 
7673       empty = false;
7674     }
7675 
7676     if(empty) {
7677       delete separator;
7678     } else {
7679       a_parent.add(separator);
7680     }
7681   }
7682 
7683   void update_primitive_box(std::ostream& a_out,const plottable_box& a_obj){
7684 
7685     float z = xy_depth.value()*1.1F;
7686 
7687     vec3f pos1;
7688     axis_2_data_frame(vec3f(a_obj.m_X1,a_obj.m_Y1,z),pos1);
7689     xx_2_yy(pos1,pos1);
7690 
7691     vec3f pos2;
7692     axis_2_data_frame(vec3f(a_obj.m_X2,a_obj.m_Y2,z),pos2);
7693     xx_2_yy(pos2,pos2);
7694 
7695     z = pos1[2];
7696 
7697     if(a_obj.m_FAIS==plottable_box::HOLLOW) {
7698 
7699       separator* sep = new separator;
7700 
7701       rgba* mat = new rgba();
7702       mat->color = a_obj.m_PLCI;
7703       sep->add(mat);
7704 
7705       draw_style* ds = new draw_style;
7706       ds->style = draw_lines;
7707       ds->line_pattern = line_solid;
7708       ds->line_width = a_obj.m_LWID;
7709       sep->add(ds);
7710 
7711       vertices* vtxs = new vertices;
7712       vtxs->mode = gl::line_strip();
7713       sep->add(vtxs);
7714 
7715       vtxs->add(pos1[0],pos1[1],z);
7716       vtxs->add(pos2[0],pos1[1],z);
7717       vtxs->add(pos2[0],pos2[1],z);
7718       vtxs->add(pos1[0],pos2[1],z);
7719       vtxs->add(pos1[0],pos1[1],z);
7720 
7721       m_primitives_sep.add(sep);
7722 
7723     } else if(a_obj.m_FAIS==plottable_box::SOLID) {
7724       separator* sep = new separator;
7725 
7726       rgba* mat = new rgba();
7727       mat->color = a_obj.m_FACI;
7728       sep->add(mat);
7729 
7730       draw_style* ds = new draw_style;
7731       ds->style = draw_filled;
7732       sep->add(ds);
7733 
7734       vertices* vtxs = new vertices;
7735       vtxs->mode = gl::triangle_fan();
7736       sep->add(vtxs);
7737 
7738       vtxs->add(pos1[0],pos1[1],z);
7739       vtxs->add(pos2[0],pos1[1],z);
7740       vtxs->add(pos2[0],pos2[1],z);
7741       vtxs->add(pos1[0],pos2[1],z);
7742 
7743       m_primitives_sep.add(sep);
7744 
7745     } else if(a_obj.m_FAIS==plottable_box::HATCHED) {
7746 
7747      {separator* sep = new separator;
7748 
7749       rgba* mat = new rgba();
7750       mat->color = a_obj.m_FACI;
7751       sep->add(mat);
7752 
7753       hatching_policy hatching;
7754       float spacing;
7755       float angle_right;
7756       float angle_left;
7757       PAW_hatch(a_obj.m_FASI,hatching,spacing,angle_right,angle_left);
7758       float stripWidth = 0;
7759 
7760       if((hatching==hatching_right)||((hatching==hatching_left_and_right))) {
7761         rep_box_hatch(*sep,spacing,angle_right,stripWidth,pos1[0],pos1[1],pos2[0],pos2[1],z);
7762       }
7763       if((hatching==hatching_left)||((hatching==hatching_left_and_right))) {
7764         rep_box_hatch(*sep,spacing,angle_left,stripWidth,pos1[0],pos1[1],pos2[0],pos2[1],z);
7765       }
7766 
7767       if(hatching==hatching_none) {
7768         draw_style* ds = new draw_style;
7769         ds->style = draw_filled;
7770         sep->add(ds);
7771         vertices* vtxs = new vertices;
7772         vtxs->mode = gl::triangle_fan();
7773         sep->add(vtxs);
7774         vtxs->add(pos1[0],pos1[1],z);
7775         vtxs->add(pos2[0],pos1[1],z);
7776         vtxs->add(pos2[0],pos2[1],z);
7777         vtxs->add(pos1[0],pos2[1],z);
7778       }
7779 
7780       m_primitives_sep.add(sep);}
7781 
7782       if(a_obj.m_BORD) {
7783         separator* sep = new separator;
7784         rgba* mat = new rgba();
7785         mat->color = a_obj.m_PLCI;
7786         sep->add(mat);
7787 
7788         draw_style* ds = new draw_style;
7789         ds->style = draw_lines;
7790         ds->line_pattern = line_solid;
7791         ds->line_width = 1;
7792         sep->add(ds);
7793 
7794         vertices* vtxs = new vertices;
7795         vtxs->mode = gl::line_strip();
7796         sep->add(vtxs);
7797 
7798         z *= 1.01F;
7799         vtxs->add(pos1[0],pos1[1],z);
7800         vtxs->add(pos2[0],pos1[1],z);
7801         vtxs->add(pos2[0],pos2[1],z);
7802         vtxs->add(pos1[0],pos2[1],z);
7803         vtxs->add(pos1[0],pos1[1],z);
7804 
7805         m_primitives_sep.add(sep);
7806       }
7807 
7808     } else if(a_obj.m_FAIS==plottable_box::PATTERN) {
7809       a_out << "tools::sg::plotter::update_plottable_box FAIS PATTERN not yet handled." << std::endl;
7810     }
7811 
7812   }
7813 
7814   void update_primitive_ellipse(std::ostream& a_out,const plottable_ellipse& a_obj){
7815 
7816     float z = xy_depth.value()*1.1F;
7817 
7818     vec3f pos;
7819     axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y,z),pos);
7820     xx_2_yy(pos,pos);
7821 
7822     vec3f pos2;
7823     axis_2_data_frame(vec3f(a_obj.m_X+a_obj.m_R1,a_obj.m_Y+a_obj.m_R2,z),pos2);
7824     xx_2_yy(pos2,pos2);
7825 
7826     float rx = pos2[0]-pos[0];
7827     float ry = pos2[1]-pos[1];
7828 
7829     z = pos[2];
7830 
7831     if(a_obj.m_FAIS==plottable_ellipse::HOLLOW) {
7832 
7833       separator* sep = new separator;
7834 
7835       matrix* _tsf = new matrix;
7836       _tsf->set_translate(pos);
7837       sep->add(_tsf);
7838 
7839       rgba* mat = new rgba();
7840       mat->color = a_obj.m_PLCI;
7841       sep->add(mat);
7842 
7843       draw_style* ds = new draw_style;
7844       ds->style = draw_lines;
7845       ds->line_pattern = line_solid;
7846       ds->line_width = a_obj.m_LWID;
7847       sep->add(ds);
7848 
7849       ellipse* _ellipse = new ellipse;
7850       _ellipse->rx = rx;
7851       _ellipse->ry = ry;
7852       sep->add(_ellipse);
7853 
7854       m_primitives_sep.add(sep);
7855     } else {
7856       a_out << "tools::sg::plotter::update_plottable_box FAIS " << a_obj.m_FAIS << " not yet handled." << std::endl;
7857     }
7858 
7859   }
7860 
7861   void update_primitive_img(std::ostream& /*a_out*/,const plottable_img& a_obj){
7862 
7863     float z = xy_depth.value()*1.1F;
7864 
7865     vec3f pos;
7866     axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y,z),pos);
7867     xx_2_yy(pos,pos);   //pos = center of image in axes coordinates.
7868     z = pos[2];
7869 
7870     vec3f top;
7871     axis_2_data_frame(vec3f(0,a_obj.m_Y+a_obj.m_HEIGHT*0.5f,0),top);
7872     xx_2_yy(top,top);  //top = (o,y-top)  of image in axes coordinates.
7873     float scale = 2.0f*(top[1]-pos[1]);
7874 
7875     const img<byte>& img = a_obj.m_img;
7876 
7877     separator* sep = new separator;
7878 
7879     rgba* mat = new rgba();
7880     mat->color = colorf_white();
7881     sep->add(mat);
7882 
7883     normal* nm = new normal;
7884     sep->add(nm);
7885 
7886     matrix* _tsf = new matrix;
7887     _tsf->set_translate(pos);
7888     _tsf->mul_rotate(0,1,0,a_obj.m_THETA*fpi()/180.0f);
7889     _tsf->mul_rotate(0,0,1,a_obj.m_PHI*fpi()/180.0f);
7890     _tsf->mul_scale(scale,scale,1);
7891     sep->add(_tsf);
7892 
7893     tex_rect* _img = new tex_rect();
7894     _img->img = img;
7895     sep->add(_img);
7896 
7897     m_primitives_sep.add(sep);
7898 
7899   }
7900 
7901 protected: //etc
7902   // background is at z = 0.
7903   // last z items are text in infos, legend boxes that should be at xy_depth().
7904 
7905   float _zoffset() const {
7906     // first data plane is at _zoffset.
7907     // last one at m_plottables.size()*_zoffset = xy_depth.value()-_zoffset().
7908     return xy_depth.value()/(float(m_plottables.size())+1.0f);
7909   }
7910   float _zaxis() const {return _zoffset();}
7911   float _zgrid() const {return xy_depth.value()-_zoffset()*0.5f;}
7912   float _ztext() const {return 0.01f;} //if text back is visible else 0. (sf<float> zfront ?)
7913   float _zscale_text() const {return _zoffset()*0.4f/_ztext();} //title and infos boxes thickness.
7914   float _zinfos() const {return xy_depth.value()-_zoffset()*0.4f;} //in front _zgrid
7915   float _zhatch() const {return _zoffset()*0.25f;}
7916   float _zerrors() const {return _zoffset()*0.5f;}
7917 
7918   static float take_log(float a_x){
7919     if(a_x<=0) {
7920       return -FLT_MAX;
7921     } else {
7922       return flog10(a_x);
7923     }
7924   }
7925 
7926   static float verify_log(float a_val,float a_min,float a_dx,bool a_log){
7927     if(a_log) {
7928       if(a_val>0.0F) {
7929         return (flog10(a_val) - a_min)/a_dx;
7930       } else { // Return a negative large number :
7931         return -100;
7932       }
7933     } else {
7934       // Simple protection against value that could exceed a float :
7935       if(a_val>(a_min+100.0F * a_dx)) return 100;
7936       if(a_val<(a_min-100.0F * a_dx)) return -100;
7937       // Rescale :
7938       return (a_val - a_min)/a_dx;
7939     }
7940   }
7941 
7942   static float verify_log_inv(float a_val,float a_min,float a_dx,bool a_log){
7943    if(a_log) {
7944       return fpow(10,a_val*a_dx+a_min);
7945     } else {
7946       return a_val*a_dx+a_min;
7947     }
7948   }
7949 
7950   style* merge_bins_style(unsigned int a_index,plottable&) {
7951     style& _style = bins_style(a_index);
7952     //uuu merge with a_p.infos().
7953     return new style(_style);
7954   }
7955 
7956   style* merge_left_hatch_style(unsigned int a_index,plottable&) {
7957     style& _style = left_hatch_style(a_index);
7958     //uuu merge with a_p.infos().
7959     return new style(_style);
7960   }
7961 
7962   style* merge_right_hatch_style(unsigned int a_index,plottable&) {
7963     style& _style = right_hatch_style(a_index);
7964     //uuu merge with a_p.infos().
7965     return new style(_style);
7966   }
7967 
7968   style* merge_errors_style(unsigned int a_index,plottable&) {
7969     style& _style = errors_style(a_index);
7970     //uuu merge with a_p.infos().
7971     return new style(_style);
7972   }
7973 
7974   style* merge_func_style(unsigned int a_index,plottable&) {
7975     style& _style = func_style(a_index);
7976     //uuu merge with a_p.infos().
7977     return new style(_style);
7978   }
7979 
7980   style* merge_points_style(unsigned int a_index,plottable&) {
7981     style& _style = points_style(a_index);
7982     //uuu merge with a_p.infos().
7983     return new style(_style);
7984   }
7985 
7986   shape_type get_shape() const {
7987     if(!shape_automated) return shape.value();
7988  {
7989       return xy; //Default.
7990     }
7991   }
7992 
7993   void clear_plottables() {
7994     //unsigned int objn = m_plottables.size();
7995    {std::vector<plottable*>::iterator it;
7996     for(it=m_plottables.begin();it!=m_plottables.end();++it) delete *it;
7997     m_plottables.clear();}
7998 
7999     touch();
8000   }
8001   void clear_primitives() {
8002    {std::vector<plotprim*>::iterator it;
8003     for(it=m_primitives.begin();it!=m_primitives.end();++it) delete *it;
8004     m_primitives.clear();}
8005     touch();
8006   }
8007 
8008   void clear_todels() {m_todel_group.clear();}
8009 
8010   bool first_bins(bins1D*& a_1,bins2D*& a_2) const {
8011     tools_vforcit(plottable*,m_plottables,it) {
8012       plottable* object = *it;
8013       if(!object) continue;
8014       if(bins1D* b1 = safe_cast<plottable,bins1D>(*object)) {
8015         a_1 = b1;
8016         a_2 = 0;
8017         return true;
8018       } else if(bins2D* b2 = safe_cast<plottable,bins2D>(*object)) {
8019         a_1 = 0;
8020         a_2 = b2;
8021         return true;
8022       }
8023     }
8024     a_1 = 0;
8025     a_2 = 0;
8026     return false;
8027   }
8028 
8029   bool first_func(func1D*& a_1,func2D*& a_2) const {
8030     tools_vforcit(plottable*,m_plottables,it) {
8031       plottable* object = *it;
8032       if(!object) continue;
8033       if(func1D* f1 = safe_cast<plottable,func1D>(*object)) {
8034         a_1 = f1;
8035         a_2 = 0;
8036         return true;
8037       } else if(func2D* f2 = safe_cast<plottable,func2D>(*object)) {
8038         a_1 = 0;
8039         a_2 = f2;
8040         return true;
8041       }
8042     }
8043     a_1 = 0;
8044     a_2 = 0;
8045     return false;
8046   }
8047 
8048   bool first_points(points2D*& a_2,points3D*& a_3) const {
8049     tools_vforcit(plottable*,m_plottables,it) {
8050       plottable* object = *it;
8051       if(!object) continue;
8052       if(points2D* p2 = safe_cast<plottable,points2D>(*object)) {
8053         a_2 = p2;
8054         a_3 = 0;
8055         return true;
8056       } else if(points3D* p3 = safe_cast<plottable,points3D>(*object)) {
8057         a_2 = 0;
8058         a_3 = p3;
8059         return true;
8060       }
8061     }
8062     a_2 = 0;
8063     a_3 = 0;
8064     return false;
8065   }
8066 
8067   void clear_sg() {
8068     m_bins_sep.clear();
8069     m_errors_sep.clear();
8070     m_func_sep.clear();
8071     m_points_sep.clear();
8072   }
8073 
8074   void DUMP_UPDATE_WHAT(std::ostream&,const std::string&) {}
8075 
8076   static void add_pt(std::vector<float>& a_pts,float a_x,float a_y,float a_z){
8077     a_pts.push_back(a_x);
8078     a_pts.push_back(a_y);
8079     a_pts.push_back(a_z);
8080   }
8081 
8082   static void clip_points_2D(const std::vector<vec3f>& a_points,
8083                              const rep_box& a_box_x,const rep_box& a_box_y,std::vector<float>& a_pts) {
8084     float xmin = a_box_x.m_pos;
8085     float dx = a_box_x.m_width;
8086     bool xlog = a_box_x.m_log;
8087 
8088     float ymin = a_box_y.m_pos;
8089     float dy = a_box_y.m_width;
8090     bool ylog = a_box_y.m_log;
8091 
8092     a_pts.clear();
8093 
8094     float xx,yy,zz;
8095     tools_vforcit(vec3f,a_points,it) {
8096       const vec3f& _point = *it;
8097       xx = _point[0];
8098       yy = _point[1];
8099       zz = _point[2];
8100       xx = verify_log(xx,xmin,dx,xlog);
8101       yy = verify_log(yy,ymin,dy,ylog);
8102       if((xx>=0)&&(xx<=1)&&(yy>=0)&&(yy<=1)) add_pt(a_pts,xx,yy,zz);
8103     }
8104   }
8105 
8106   static void clip_polyline_2D(const std::vector<vec3f>& a_points,
8107                                const rep_box& a_box_x,const rep_box& a_box_y,std::vector<float>& a_pts) {
8108     //  Clip line in a_box_x, a_box_y.
8109 
8110     //NOTE : it is not a general algorithm.
8111     //       It is assumed that a_points are ordered with increasing x.
8112     //       And the algorithm clips against up and bottom BoxY lines.
8113     //       (Use clip<float> for a more general algorithm ?)
8114 
8115     float xmin = a_box_x.m_pos;
8116     float dx = a_box_x.m_width;
8117     bool xlog = a_box_x.m_log;
8118 
8119     float ymin = a_box_y.m_pos;
8120     float dy = a_box_y.m_width;
8121     bool ylog = a_box_y.m_log;
8122 
8123     a_pts.clear();
8124 
8125     float xprev = 0;
8126     float yprev = 0;
8127 
8128    {unsigned int index = 0;
8129     std::vector<vec3f>::const_iterator it;
8130     for(it=a_points.begin();it!=a_points.end();++it,index++) {
8131       const vec3f& _point = *it;
8132       float xx = _point[0];
8133       float yy = _point[1];
8134       float zz = _point[2];
8135       //add_pt(a_pts,xx,yy,zz);continue; //debug
8136       xx = verify_log(xx,xmin,dx,xlog);
8137       yy = verify_log(yy,ymin,dy,ylog);
8138       if((xx>=0)&&(xx<=1) ) {
8139         if(yy>1) {
8140           if(index==0) {
8141             add_pt(a_pts,xx,1,zz);
8142           } else {
8143             if(yprev>1) {
8144               add_pt(a_pts,xx,1,zz);
8145             } else if(yprev<0) {
8146               float a = (yy - yprev)/(xx - xprev);
8147               float b = yy - a * xx;
8148               add_pt(a_pts,-b/a,0,zz);
8149               add_pt(a_pts,(1 - b)/a,1,zz);
8150               add_pt(a_pts,xx,1,zz);
8151             } else {
8152               float a = (yy - yprev)/(xx - xprev);
8153               float b = yy - a * xx;
8154               add_pt(a_pts,(1 - b)/a,1,zz);
8155               add_pt(a_pts,xx,1,zz);
8156             }
8157           }
8158         } else if (yy < 0) {
8159           if(index==0) {
8160             add_pt(a_pts,xx,0,zz);
8161           } else {
8162             if(yprev<0) {
8163               add_pt(a_pts,xx,0,zz);
8164             } else if(yprev>1) {
8165               float a = (yy - yprev)/(xx - xprev);
8166               float b = yy - a * xx;
8167               add_pt(a_pts,(1 - b)/a,1,zz);
8168               add_pt(a_pts,-b/a,0,zz);
8169               add_pt(a_pts,xx,0,zz);
8170             } else {
8171               float a = (yy - yprev)/(xx - xprev);
8172               float b = yy - a * xx;
8173               add_pt(a_pts,-b/a,0,zz);
8174               add_pt(a_pts,xx,0,zz);
8175              }
8176           }
8177         } else {
8178           if(index==0) {
8179             add_pt(a_pts,xx,yy,zz);
8180           } else if( (yprev>1) || (yprev<0) ) {
8181             // interpolate :
8182             float a = (yy - yprev)/(xx - xprev);
8183             float b = yy - a * xx;
8184             if(yprev>1) {
8185               add_pt(a_pts,(1 - b)/a,1,zz);
8186             } else {
8187               add_pt(a_pts,-b/a,0,zz);
8188             }
8189             add_pt(a_pts,xx,yy,zz);
8190           } else {
8191             add_pt(a_pts,xx,yy,zz);
8192           }
8193         }
8194       }
8195       xprev = xx;
8196       yprev = yy;
8197     }}
8198   }
8199 
8200   bool sto(const std::string& a_s,vec2f& a_v) {
8201     std::vector<std::string> ws;
8202     words(a_s," ",false,ws);
8203     if(ws.size()!=2) return false;
8204     float x = 0;
8205     if(!to<float>(ws[0],x)) return false;
8206     float y = 0;
8207     if(!to<float>(ws[1],x)) return false;
8208     a_v.set_value(x,y);
8209     return true;
8210   }
8211 
8212   bool sto(const std::string& a_s,unit_type& a_v) {
8213     if(a_s=="percent") {a_v = unit_percent;return true;}
8214     else if(a_s=="axis") {a_v = unit_axis;return true;}
8215     return false;
8216   }
8217 
8218   void clear_cmaps() {
8219    {std::vector<base_colormap*>::iterator it;
8220     for(it=m_bins_cmaps.begin();it!=m_bins_cmaps.end();++it) delete *it;
8221     m_bins_cmaps.clear();}
8222 
8223    {std::vector<base_colormap*>::iterator it;
8224     for(it=m_points_cmaps.begin();it!=m_points_cmaps.end();++it) delete *it;
8225     m_points_cmaps.clear();}
8226 
8227    {std::vector<base_colormap*>::iterator it;
8228     for(it=m_func_cmaps.begin();it!=m_func_cmaps.end();++it) delete *it;
8229     m_func_cmaps.clear();}
8230   }
8231 
8232   void bar_chart(float a_bar_offset,float a_bar_width,
8233                  float& a_beg,float& a_end){
8234     float xe = (a_end - a_beg)*a_bar_offset;
8235     float xw = (a_end - a_beg)*a_bar_width;
8236     a_end = a_beg + xe + xw;
8237     a_beg = a_beg + xe;
8238   }
8239 
8240 protected:
8241   const base_freetype& m_ttf;
8242 protected: //fields for skeleton.
8243   group m_group;
8244 
8245   separator m_background_sep;
8246 
8247   separator m_cmap_sep;
8248   matrix m_cmap_matrix;
8249   separator m_cmap_cells_sep;
8250   matrix m_cmap_axis_matrix;
8251   sg::axis m_cmap_axis;
8252 
8253   separator m_infos_title_sep;
8254   separator m_infos_sep;
8255   separator m_legend_sep;
8256   separator m_title_box_sep;
8257 
8258   matrix m_tsf;
8259   matrix m_layout;
8260 
8261   separator m_title_sep;
8262 
8263   separator m_x_axis_sep;
8264   matrix m_x_axis_matrix;
8265   sg::axis m_x_axis;
8266 
8267   separator m_y_axis_sep;
8268   matrix m_y_axis_matrix;
8269   sg::axis m_y_axis;
8270 
8271   separator m_z_axis_sep;
8272   matrix m_z_axis_matrix;
8273   sg::axis m_z_axis;
8274 
8275   separator m_grid_sep;
8276 
8277   separator m_data_sep;
8278   torche m_data_light;
8279   matrix m_data_matrix;
8280   separator m_bins_sep;
8281   separator m_errors_sep;
8282   separator m_func_sep;
8283   separator m_points_sep;
8284   separator m_inner_frame_sep;
8285   separator m_primitives_sep;
8286   separator m_etc_sep;
8287 
8288 protected: //fields
8289   shape_type m_shape;
8290 
8291   data_axis m_x_axis_data;
8292   data_axis m_y_axis_data;
8293   data_axis m_z_axis_data;
8294 
8295   std::vector<plottable*> m_plottables; //it has ownership.
8296 
8297   std::vector<style> m_bins_style;
8298   std::vector<style> m_errors_style;
8299   std::vector<style> m_func_style;
8300   std::vector<style> m_points_style;
8301   std::vector<style> m_left_hatch_style;
8302   std::vector<style> m_right_hatch_style;
8303   std::vector<style> m_legend_style;
8304 
8305   text_style m_title_style;
8306   text_style m_infos_style;
8307   text_style m_title_box_style;
8308   style m_background_style;
8309   style m_wall_style; //for gopaw.
8310   style m_inner_frame_style;
8311   style m_grid_style;
8312 
8313 protected:
8314   std::vector<std::string> m_legend_strings;
8315 
8316   std::vector<base_colormap*> m_bins_cmaps;
8317   std::vector<base_colormap*> m_points_cmaps;
8318   std::vector<base_colormap*> m_func_cmaps;
8319 
8320   group m_todel_group;
8321   std::vector<plotprim*> m_primitives;
8322   cmaps_t m_cmaps;
8323   rtausmef m_rtausmef;
8324 };
8325 
8326 }}
8327 
8328 #endif