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