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