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