Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_plotter 5 #define tools_sg_plotter 6 7 #include "../lina/vec2f" 8 9 #include "render_action" 10 #include "plottables" 11 #include "style" 12 #include "rep" 13 #include "colormap" 14 #include "noderef" 15 #include "atb_vertices" 16 #include "cube" //for lego 17 #include "matrix" 18 #include "normal" 19 #include "holder" 20 #include "tex_rect" //for plottable_img. 21 22 #include "axis" 23 #include "infos_box" 24 #include "legend" 25 #include "text" 26 #include "torche" 27 #include "ellipse" 28 29 #include "../data_axis" 30 #include "../hatcher" 31 #include "../clist_contour" 32 #include "../tess_contour" 33 #include "../lina/geom3" 34 #include "../spline" 35 #include "../rtausmef" 36 37 //#define INLIBS_SG_PLOTTER_TIMING 38 #ifdef INLIBS_SG_PLOTTER_TIMING 39 #include "../sys/atime" 40 #endif 41 42 #include <utility> 43 44 namespace tools { 45 namespace sg { 46 47 class plotter : public node { 48 TOOLS_NODE(plotter,tools::sg::plotter,node) 49 private: 50 static const std::string& s_infos_what_def() { 51 static const std::string s_v("name entries mean rms fit_quality fit_ndf fit_parameters fit_errors"); 52 return s_v; 53 } 54 static float default_infos_margin() {return 0.005f;} 55 static float default_title_box_width() {return 0.3f;} 56 static float default_title_box_height() {return 0.05f;} 57 static float default_title_box_x_margin() {return 0.01f;} 58 static float default_title_box_y_margin() {return 0.005f;} 59 public: 60 sf<float> width; //PAW XSIZ 61 sf<float> height; //PAW YSIZ 62 sf<float> left_margin; //PAW XMGL 63 sf<float> right_margin; //PAW XMGR 64 sf<float> bottom_margin; //PAW YMGL 65 sf<float> top_margin; //PAW YMGU 66 67 sf<float> depth; 68 sf<float> down_margin; 69 sf<float> up_margin; 70 71 sf<bool> title_up; 72 sf<float> title_to_axis; 73 sf<float> title_height; 74 sf<bool> title_automated; 75 sf_enum<hjust> title_hjust; 76 sf_string title; //output if title_automated. 77 78 sf<bool> colormap_visible; 79 enum colormap_axis_labeling_type { 80 cells = 0, 81 min_max 82 }; 83 sf_enum<colormap_axis_labeling_type> colormap_axis_labeling; 84 sf<bool> colormap_attached; 85 sf<bool> colormap_axis_visible; 86 87 // Wanted axes parameters. 88 // They are not necessary realized on the sg::axis nodes. 89 sf<bool> x_axis_enforced; 90 sf<bool> x_axis_automated; 91 sf<float> x_axis_min; 92 sf<float> x_axis_max; 93 sf<bool> x_axis_is_log; 94 95 sf<bool> y_axis_enforced; 96 sf<bool> y_axis_automated; 97 sf<float> y_axis_min; 98 sf<float> y_axis_max; 99 sf<bool> y_axis_is_log; 100 101 sf<bool> z_axis_enforced; 102 sf<bool> z_axis_automated; 103 sf<float> z_axis_min; 104 sf<float> z_axis_max; 105 sf<bool> z_axis_is_log; 106 107 sf<float> value_top_margin; 108 sf<float> value_bottom_margin; 109 sf<bool> value_bins_with_entries; 110 111 sf<float> infos_width; //in percent of width. 112 sf<float> infos_x_margin; //in percent of width. From right. 113 sf<float> infos_y_margin; //in percent of height. From top. 114 sf_string infos_what; 115 116 sf<float> title_box_width; //in percent of width. 117 sf<float> title_box_height; //in percent of height. 118 sf<float> title_box_x_margin; //in percent of width. From left. 119 sf<float> title_box_y_margin; //in percent of height. From top. 120 121 sf<bool> func2D_borders_visible; 122 123 // used with shape xyz 124 sf<float> theta; //in degrees. 125 sf<float> phi; //in degrees. 126 sf<float> tau; //in degrees. 127 128 //////////////////////////////////////////////////////////////// 129 /// legend related ://////////////////////////////////////////// 130 //////////////////////////////////////////////////////////////// 131 sf<bool> legends_automated; 132 //sf<bool> legends_attached_to_infos; 133 //if legends_attached_to_infos is false : 134 // legends_origin is used to place the legends. It is then 135 // the lower left corner of the box containing all legends. 136 mf_vec<vec2f,float> legends_origin; //common origin of legend boxes. 137 enum unit_type { 138 unit_percent, 139 unit_axis 140 }; 141 mf_enum<unit_type> legends_origin_unit; 142 mf_vec<vec2f,float> legends_size; //overall legend boxes size. 143 mf_string legends_string; 144 145 //////////////////////////////////////////////////////////////// 146 //////////////////////////////////////////////////////////////// 147 //////////////////////////////////////////////////////////////// 148 149 sf<bool> shape_automated; 150 151 enum shape_type { 152 xy = 0, 153 xyz 154 }; 155 sf_enum<shape_type> shape; 156 157 // used with xy shape : 158 sf<float> xy_depth; //all is in z [0,xy_depth] 159 160 sf<unsigned int> curve_number_of_points; 161 162 sf<bool> data_light_on_automated; 163 164 // for gopaw : 165 sf<bool> primitives_enforced; 166 sf<bool> inner_frame_enforced; 167 // to be implemented : 168 sf<bool> top_axis_visible; 169 sf<bool> right_axis_visible; 170 sf<bool> superpose_bins; 171 //sf<bool> grid_visible; 172 // For contours : 173 sf<unsigned int> number_of_levels; 174 mf<float> levels; 175 //sf<bool> frozen; 176 //sf<float> ttfScale; 177 //sf<bool> wallEnforced; 178 //sf<bool> gridEnforced; 179 //SoMFString infos; //Output 180 //SoMFString legend; //Output 181 182 public: 183 virtual const desc_fields& node_desc_fields() const { 184 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::plotter) 185 static const desc_fields s_v(parent::node_desc_fields(),63, //WARNING : take care of count. 186 187 TOOLS_ARG_FIELD_DESC(width), 188 TOOLS_ARG_FIELD_DESC(height), 189 TOOLS_ARG_FIELD_DESC(left_margin), 190 TOOLS_ARG_FIELD_DESC(right_margin), 191 TOOLS_ARG_FIELD_DESC(bottom_margin), 192 TOOLS_ARG_FIELD_DESC(top_margin), 193 TOOLS_ARG_FIELD_DESC(depth), 194 TOOLS_ARG_FIELD_DESC(down_margin), 195 TOOLS_ARG_FIELD_DESC(up_margin), 196 TOOLS_ARG_FIELD_DESC(colormap_visible), //10 197 198 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(colormap_axis_labeling,2) 199 TOOLS_ARG_ENUM(cells), 200 TOOLS_ARG_ENUM(min_max) 201 TOOLS_ARG_FIELD_DESC_ENUMS_END, 202 203 TOOLS_ARG_FIELD_DESC(colormap_attached), 204 TOOLS_ARG_FIELD_DESC(colormap_axis_visible), 205 206 TOOLS_ARG_FIELD_DESC(title_up), 207 TOOLS_ARG_FIELD_DESC(title_to_axis), 208 TOOLS_ARG_FIELD_DESC(title_height), 209 TOOLS_ARG_FIELD_DESC(title_automated), 210 211 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(title_hjust,3) 212 "left",left, 213 "center",center, 214 "right",right 215 TOOLS_ARG_FIELD_DESC_ENUMS_END, 216 217 TOOLS_ARG_FIELD_DESC(title), 218 219 TOOLS_ARG_FIELD_DESC(x_axis_enforced), //20 220 TOOLS_ARG_FIELD_DESC(x_axis_automated), 221 TOOLS_ARG_FIELD_DESC(x_axis_min), 222 TOOLS_ARG_FIELD_DESC(x_axis_max), 223 TOOLS_ARG_FIELD_DESC(x_axis_is_log), 224 225 TOOLS_ARG_FIELD_DESC(y_axis_enforced), 226 TOOLS_ARG_FIELD_DESC(y_axis_automated), 227 TOOLS_ARG_FIELD_DESC(y_axis_min), 228 TOOLS_ARG_FIELD_DESC(y_axis_max), 229 TOOLS_ARG_FIELD_DESC(y_axis_is_log), 230 231 TOOLS_ARG_FIELD_DESC(z_axis_enforced), //30 232 TOOLS_ARG_FIELD_DESC(z_axis_automated), 233 TOOLS_ARG_FIELD_DESC(z_axis_min), 234 TOOLS_ARG_FIELD_DESC(z_axis_max), 235 TOOLS_ARG_FIELD_DESC(z_axis_is_log), 236 237 TOOLS_ARG_FIELD_DESC(value_top_margin), 238 TOOLS_ARG_FIELD_DESC(value_bottom_margin), 239 TOOLS_ARG_FIELD_DESC(value_bins_with_entries), 240 241 TOOLS_ARG_FIELD_DESC(infos_width), 242 TOOLS_ARG_FIELD_DESC(infos_x_margin), 243 TOOLS_ARG_FIELD_DESC(infos_y_margin), //40 244 TOOLS_ARG_FIELD_DESC(infos_what), 245 246 TOOLS_ARG_FIELD_DESC(func2D_borders_visible), 247 TOOLS_ARG_FIELD_DESC(theta), 248 TOOLS_ARG_FIELD_DESC(phi), 249 TOOLS_ARG_FIELD_DESC(tau), 250 251 TOOLS_ARG_FIELD_DESC(legends_automated), 252 253 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(legends_origin,2) 254 "unit_percent",unit_percent, 255 "unit_axis",unit_axis 256 TOOLS_ARG_FIELD_DESC_ENUMS_END, 257 258 TOOLS_ARG_FIELD_DESC(legends_origin_unit), 259 TOOLS_ARG_FIELD_DESC(legends_size), 260 TOOLS_ARG_FIELD_DESC(legends_string), //50 261 262 TOOLS_ARG_FIELD_DESC(shape_automated), 263 264 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(shape,2) 265 "xy",xy, 266 "xyz",xyz 267 TOOLS_ARG_FIELD_DESC_ENUMS_END, 268 269 TOOLS_ARG_FIELD_DESC(xy_depth), 270 TOOLS_ARG_FIELD_DESC(curve_number_of_points), 271 272 TOOLS_ARG_FIELD_DESC(number_of_levels), 273 TOOLS_ARG_FIELD_DESC(levels), 274 275 TOOLS_ARG_FIELD_DESC(data_light_on_automated), 276 277 TOOLS_ARG_FIELD_DESC(primitives_enforced), 278 TOOLS_ARG_FIELD_DESC(inner_frame_enforced), 279 280 TOOLS_ARG_FIELD_DESC(title_box_width), //60 281 TOOLS_ARG_FIELD_DESC(title_box_height), 282 TOOLS_ARG_FIELD_DESC(title_box_x_margin), 283 TOOLS_ARG_FIELD_DESC(title_box_y_margin) //63 284 285 ); 286 return s_v; 287 } 288 virtual bool touched() { 289 if(parent::touched()) return true; 290 291 if(background_style().touched()) return true; 292 if(title_style().touched()) return true; 293 if(infos_style().touched()) return true; 294 if(title_box_style().touched()) return true; 295 if(inner_frame_style().touched()) return true; 296 if(grid_style().touched()) return true; 297 if(wall_style().touched()) return true; 298 299 {tools_vforit(style,m_bins_style,it) {if((*it).touched()) return true;}} 300 {tools_vforit(style,m_errors_style,it) {if((*it).touched()) return true;}} 301 {tools_vforit(style,m_func_style,it) {if((*it).touched()) return true;}} 302 {tools_vforit(style,m_points_style,it) {if((*it).touched()) return true;}} 303 {tools_vforit(style,m_left_hatch_style,it) {if((*it).touched()) return true;}} 304 {tools_vforit(style,m_right_hatch_style,it) {if((*it).touched()) return true;}} 305 {tools_vforit(style,m_legend_style,it) {if((*it).touched()) return true;}} 306 307 return false; 308 } 309 virtual void reset_touched() { 310 parent::reset_touched(); 311 312 background_style().reset_touched(); 313 title_style().reset_touched(); 314 infos_style().reset_touched(); 315 title_box_style().reset_touched(); 316 inner_frame_style().reset_touched(); 317 grid_style().reset_touched(); 318 wall_style().reset_touched(); 319 320 {tools_vforit(style,m_bins_style,it) (*it).reset_touched();} 321 {tools_vforit(style,m_errors_style,it) (*it).reset_touched();} 322 {tools_vforit(style,m_func_style,it) (*it).reset_touched();} 323 {tools_vforit(style,m_points_style,it) (*it).reset_touched();} 324 {tools_vforit(style,m_left_hatch_style,it) (*it).reset_touched();} 325 {tools_vforit(style,m_right_hatch_style,it) (*it).reset_touched();} 326 {tools_vforit(style,m_legend_style,it) (*it).reset_touched();} 327 } 328 329 private: 330 void add_fields(){ 331 // if adding a field, look for reset_style(), set_from_style() and set_from_string() 332 add_field(&width); 333 add_field(&height); 334 add_field(&left_margin); 335 add_field(&right_margin); 336 add_field(&bottom_margin); 337 add_field(&top_margin); 338 add_field(&depth); 339 add_field(&down_margin); 340 add_field(&up_margin); 341 342 add_field(&title_up); 343 add_field(&title_to_axis); 344 add_field(&title_height); 345 add_field(&title_automated); 346 add_field(&title_hjust); 347 add_field(&title); 348 349 add_field(&x_axis_enforced); 350 add_field(&x_axis_automated); 351 add_field(&x_axis_min); 352 add_field(&x_axis_max); 353 add_field(&x_axis_is_log); 354 355 add_field(&y_axis_enforced); 356 add_field(&y_axis_automated); 357 add_field(&y_axis_min); 358 add_field(&y_axis_max); 359 add_field(&y_axis_is_log); 360 361 add_field(&z_axis_enforced); 362 add_field(&z_axis_automated); 363 add_field(&z_axis_min); 364 add_field(&z_axis_max); 365 add_field(&z_axis_is_log); 366 367 add_field(&value_top_margin); 368 add_field(&value_bottom_margin); 369 add_field(&value_bins_with_entries); 370 371 add_field(&infos_width); 372 add_field(&infos_x_margin); 373 add_field(&infos_y_margin); 374 add_field(&infos_what); 375 376 add_field(&title_box_width); 377 add_field(&title_box_height); 378 add_field(&title_box_x_margin); 379 add_field(&title_box_y_margin); 380 381 add_field(&func2D_borders_visible); 382 add_field(&theta); 383 add_field(&phi); 384 add_field(&tau); 385 386 add_field(&legends_automated); 387 //add_field(&legends_attached_to_infos); 388 add_field(&legends_origin); 389 add_field(&legends_origin_unit); 390 add_field(&legends_size); 391 add_field(&legends_string); 392 393 add_field(&shape_automated); 394 add_field(&shape); 395 396 add_field(&xy_depth); 397 add_field(&curve_number_of_points); 398 add_field(&number_of_levels); 399 add_field(&levels); 400 add_field(&data_light_on_automated); 401 add_field(&primitives_enforced); 402 add_field(&inner_frame_enforced); 403 } 404 public: //style 405 void copy_style(const plotter& a_from) { //used in sg::plots. 406 //////////////////////////////////////////// 407 //////////////////////////////////////////// 408 //////////////////////////////////////////// 409 shape_automated = a_from.shape_automated; 410 shape = a_from.shape; 411 xy_depth = a_from.xy_depth; 412 curve_number_of_points = a_from.curve_number_of_points; 413 value_top_margin = a_from.value_top_margin; 414 value_bottom_margin = a_from.value_bottom_margin; 415 value_bins_with_entries = a_from.value_bins_with_entries; 416 infos_what = a_from.infos_what; 417 infos_width = a_from.infos_width; 418 //infos height is automatic. 419 infos_x_margin = a_from.infos_x_margin; 420 infos_y_margin = a_from.infos_y_margin; 421 422 title_box_width = a_from.title_box_width; 423 title_box_height = a_from.title_box_height; 424 title_box_x_margin = a_from.title_box_x_margin; 425 title_box_y_margin = a_from.title_box_y_margin; 426 427 legends_automated = a_from.legends_automated; 428 title_automated = a_from.title_automated; 429 title = a_from.title; 430 title_up = a_from.title_up; 431 title_hjust = a_from.title_hjust; 432 433 colormap_visible = a_from.colormap_visible; 434 colormap_axis_labeling = a_from.colormap_axis_labeling; 435 colormap_attached = a_from.colormap_attached; 436 colormap_axis_visible = a_from.colormap_axis_visible; 437 438 number_of_levels = a_from.number_of_levels; 439 levels = a_from.levels; 440 data_light_on_automated = a_from.data_light_on_automated; 441 primitives_enforced = a_from.primitives_enforced; 442 inner_frame_enforced = a_from.inner_frame_enforced; 443 444 //////////////////////////////////////////// 445 //////////////////////////////////////////// 446 //////////////////////////////////////////// 447 x_axis_enforced = a_from.x_axis_enforced; 448 x_axis_automated = a_from.x_axis_automated; 449 x_axis_min = a_from.x_axis_min; 450 x_axis_max = a_from.x_axis_max; 451 x_axis_is_log = a_from.x_axis_is_log; 452 453 y_axis_enforced = a_from.y_axis_enforced; 454 y_axis_automated = a_from.y_axis_automated; 455 y_axis_min = a_from.y_axis_min; 456 y_axis_max = a_from.y_axis_max; 457 y_axis_is_log = a_from.y_axis_is_log; 458 459 z_axis_enforced = a_from.z_axis_enforced; 460 z_axis_automated = a_from.z_axis_automated; 461 z_axis_min = a_from.z_axis_min; 462 z_axis_max = a_from.z_axis_max; 463 z_axis_is_log = a_from.z_axis_is_log; 464 465 /* 466 m_x_axis = a_from.m_x_axis; 467 m_y_axis = a_from.m_y_axis; 468 m_z_axis = a_from.m_z_axis; 469 m_cmap_axis = a_from.m_cmap_axis; 470 471 */ 472 //////////////////////////////////////////// 473 //////////////////////////////////////////// 474 //////////////////////////////////////////// 475 476 m_background_style = a_from.m_background_style; 477 m_title_style = a_from.m_title_style; 478 m_infos_style = a_from.m_infos_style; 479 m_title_box_style = a_from.m_title_box_style; 480 m_inner_frame_style = a_from.m_inner_frame_style; 481 m_grid_style = a_from.m_grid_style; 482 m_wall_style = a_from.m_wall_style; 483 484 m_bins_style = a_from.m_bins_style; 485 m_errors_style = a_from.m_errors_style; 486 m_func_style = a_from.m_func_style; 487 m_points_style = a_from.m_points_style; 488 m_left_hatch_style = a_from.m_left_hatch_style; 489 m_right_hatch_style = a_from.m_right_hatch_style; 490 m_legend_style = a_from.m_legend_style; 491 } 492 493 void reset_style(bool a_geom = false) { 494 //reset fields that are considered as part of the style. 495 496 //::printf("debug : tools::sg::plotter::reset_style :\n"); 497 498 shape_automated = true; 499 shape = xy; 500 501 xy_depth = 0.01f; 502 curve_number_of_points = 100; 503 //////////////////////////////////////////// 504 value_top_margin = 0.1f; //percent. // CERN-PAW seems to have 0.1F and CERN-ROOT 0.05F. 505 value_bottom_margin = 0.0f; //percent. 506 value_bins_with_entries = true; //gopaw uses false. 507 508 infos_what = s_infos_what_def(); 509 infos_width = 0.3f; 510 //infos height is automatic. 511 infos_x_margin = default_infos_margin(); //percent of width 512 infos_y_margin = default_infos_margin(); //percent of height 513 514 title_box_width = default_title_box_width(); 515 title_box_height = default_title_box_height(); 516 title_box_x_margin = default_title_box_x_margin(); //percent of width 517 title_box_y_margin = default_title_box_y_margin(); //percent of height 518 519 legends_automated = true; 520 521 //////////////////////////////////////////// 522 523 if(a_geom) { 524 float xfac = 1.0F/20.0F; //0.05 525 float yfac = 1.0F/20.0F; //0.05 526 527 // Take PAW defaults : 528 float XSIZ = 20 * xfac; //1 //page width 529 float YSIZ = 20 * yfac; //1 //page height 530 float XMGL = 2 * xfac; //0.1 //left x margin (to data frame). 531 float XMGR = 2 * xfac; //0.1 //right y margin (to data frame). 532 float YMGL = 2 * yfac; //0.1 //low y margin (to data frame). 533 float YMGU = 2 * yfac; //0.1 //up y margin (to data frame). 534 // Axes : 535 float VSIZ = 0.28F * yfac; //0.014 //tick label character size. 536 float XVAL = 0.4F * xfac; //0.02 //x distance of y tick label to data frame. 537 float YVAL = 0.4F * yfac; //0.02 //y distance of x tick label to data frame. 538 float XTIC = 0.3F * yfac; //0.015 //y length of X axis ticks. 539 float YTIC = 0.3F * xfac; //0.015 //x length of Y axis ticks. 540 float XLAB = 1.4F * xfac; //0.07 //x distance of y title to data frame. 541 float YLAB = 0.8F * yfac; //0.04 //y distance of x title to data frame. 542 float ASIZ = 0.28F * yfac; //0.014 // axis title (label) character size. 543 544 float YHTI = 1.2F * yfac; //0.06 //y distance of title to x axis. 545 float TSIZ = 0.28F * yfac; //0.014 //title character size 546 547 float zfac = 1.0F/20.0F; //0.05 548 float ZSIZ = 20 * zfac; //1 //page depth 549 float ZMGD = 2 * zfac; //0.1 //low y margin (to data frame). 550 float ZMGU = 2 * zfac; //0.1 //up y margin (to data frame). 551 552 // Data area : 553 //float wData = XSIZ-XMGL-XMGR; 554 //float hData = YSIZ-YMGL-YMGU; 555 //float dData = ZSIZ-ZMGD-ZMGU; 556 557 width = XSIZ; 558 height = YSIZ; 559 depth = ZSIZ; 560 561 left_margin = XMGL; 562 right_margin = XMGR; 563 bottom_margin = YMGL; 564 top_margin = YMGU; 565 down_margin = ZMGD; 566 up_margin = ZMGU; 567 568 title_to_axis = YHTI; 569 title_height = TSIZ; 570 571 if(shape.value()==xy) { 572 m_x_axis.tick_length.value(XTIC); 573 m_x_axis.label_to_axis.value(YVAL); 574 m_x_axis.label_height.value(VSIZ); 575 m_x_axis.title_to_axis.value(YLAB); 576 m_x_axis.title_height.value(ASIZ); 577 578 m_y_axis.tick_length.value(YTIC); 579 m_y_axis.label_to_axis.value(XVAL); 580 m_y_axis.label_height.value(VSIZ); 581 m_y_axis.title_to_axis.value(XLAB); 582 m_y_axis.title_height.value(ASIZ); 583 584 //set anyway z axis : 585 //m_z_axis.tick_length.value(YTIC); 586 //m_z_axis.label_to_axis.value(XVAL); 587 //m_z_axis.label_height.value(VSIZ); 588 //m_z_axis.title_to_axis.value(XLAB); 589 //m_z_axis.title_height.value(ASIZ); 590 591 m_cmap_axis.tick_length.value(YTIC); 592 m_cmap_axis.label_to_axis.value(XVAL); 593 m_cmap_axis.label_height.value(VSIZ); 594 m_cmap_axis.title_to_axis.value(XLAB); 595 m_cmap_axis.title_height.value(ASIZ); 596 597 } else { //xyz 598 m_x_axis.tick_length.value(XTIC); 599 m_x_axis.label_to_axis.value(YVAL); 600 m_x_axis.label_height.value(VSIZ); 601 m_x_axis.title_to_axis.value(YLAB); 602 m_x_axis.title_height.value(ASIZ); 603 604 m_y_axis.tick_length.value(XTIC); 605 m_y_axis.label_to_axis.value(YVAL); 606 m_y_axis.label_height.value(VSIZ); 607 m_y_axis.title_to_axis.value(YLAB); 608 m_y_axis.title_height.value(ASIZ); 609 610 m_z_axis.tick_length.value(YTIC); 611 m_z_axis.label_to_axis.value(XVAL); 612 m_z_axis.label_height.value(VSIZ); 613 m_z_axis.title_to_axis.value(XLAB); 614 m_z_axis.title_height.value(ASIZ); 615 616 m_cmap_axis.tick_length.value(XTIC); 617 m_cmap_axis.label_to_axis.value(YVAL); 618 m_cmap_axis.label_height.value(VSIZ); 619 m_cmap_axis.title_to_axis.value(YLAB); 620 m_cmap_axis.title_height.value(ASIZ); 621 622 } 623 624 } 625 626 title_automated = true; 627 title.value().clear(); 628 title_up = true; 629 title_hjust = center; 630 631 //////////////////////////////////////////// 632 colormap_visible = true; 633 colormap_axis_labeling = cells; 634 colormap_attached = true; 635 colormap_axis_visible = true; 636 637 //////////////////////////////////////////// 638 x_axis_enforced = false; 639 x_axis_automated = true; 640 x_axis_min = 0; 641 x_axis_max = 1; 642 x_axis_is_log = false; 643 644 y_axis_enforced = false; 645 y_axis_automated = true; 646 y_axis_min = 0; 647 y_axis_max = 1; 648 y_axis_is_log = false; 649 650 z_axis_enforced = false; 651 z_axis_automated = true; 652 z_axis_min = 0; 653 z_axis_max = 1; 654 z_axis_is_log = false; 655 656 m_x_axis.reset_style(); 657 m_y_axis.reset_style(); 658 m_z_axis.reset_style(); 659 660 //////////////////////////////////////////// 661 //////////////////////////////////////////// 662 //////////////////////////////////////////// 663 number_of_levels = 10; 664 levels.clear(); 665 data_light_on_automated = true; 666 primitives_enforced = false; 667 inner_frame_enforced = false; 668 669 //////////////////////////////////////////// 670 // setup styles : 671 //////////////////////////////////////////// 672 673 m_title_style = text_style(); 674 m_infos_style = text_style(); 675 m_title_box_style = text_style(); 676 m_background_style = style(); 677 m_wall_style = style(); 678 m_inner_frame_style = style(); 679 m_grid_style = style(); 680 681 m_title_style.color = colorf_black(); 682 m_title_style.font = font_hershey(); 683 m_title_style.font_modeling = font_filled; 684 m_title_style.encoding = encoding_PAW(); 685 686 m_background_style.back_color = colorf_white(); 687 m_background_style.line_width = 0; //no border 688 m_background_style.color = colorf_black(); //border 689 690 m_inner_frame_style.color = colorf_black(); 691 m_inner_frame_style.line_pattern = line_solid; 692 693 m_grid_style.color = colorf_black(); 694 m_grid_style.line_pattern = line_dashed; 695 696 m_infos_style.font = font_hershey(); 697 m_infos_style.font_modeling = font_filled; 698 m_infos_style.encoding = encoding_PAW(); 699 700 m_title_box_style.visible = false; 701 m_title_box_style.font = font_hershey(); 702 m_title_box_style.font_modeling = font_filled; 703 m_title_box_style.encoding = encoding_PAW(); 704 705 {tools_vforit(style,m_bins_style,it) { 706 (*it) = style(); 707 (*it).modeling = modeling_top_lines(); 708 (*it).marker_size = 5; //for bins1D of profile. 709 }} 710 {tools_vforit(style,m_errors_style,it) {(*it) = style();(*it).visible = false;}} 711 {tools_vforit(style,m_func_style,it) (*it) = style();} 712 {tools_vforit(style,m_points_style,it) { 713 (*it) = style(); 714 (*it).modeling = modeling_markers(); //for gopaw. 715 }} 716 {tools_vforit(style,m_left_hatch_style,it) {(*it) = style();(*it).visible = false;}} 717 {tools_vforit(style,m_right_hatch_style,it) {(*it) = style();(*it).visible = false;}} 718 {tools_vforit(style,m_legend_style,it) {(*it) = style();(*it).visible = false;}} 719 720 } 721 722 void gopaw_reset_style() { 723 {tools_vforit(style,m_bins_style,it) { 724 (*it) = style(); 725 (*it).modeling = modeling_top_lines(); 726 (*it).marker_size = 5; //for bins1D of profile. 727 }} 728 729 {tools_vforit(style,m_errors_style,it) {(*it) = style();(*it).visible = false;}} 730 {tools_vforit(style,m_func_style,it) (*it) = style();} 731 {tools_vforit(style,m_points_style,it) { 732 (*it) = style(); 733 (*it).modeling = modeling_markers(); //for gopaw. 734 }} 735 {tools_vforit(style,m_left_hatch_style,it) {(*it) = style();(*it).visible = false;}} 736 {tools_vforit(style,m_right_hatch_style,it) {(*it) = style();(*it).visible = false;}} 737 {tools_vforit(style,m_legend_style,it) {(*it) = style();(*it).visible = false;}} 738 } 739 740 typedef std::pair<std::string,std::string> style_item_t; 741 typedef std::vector<style_item_t> style_t; 742 bool set_from_style(std::ostream& a_out,const style_t& a_style) { 743 tools_vforcit(style_item_t,a_style,it) { 744 const std::string& key = (*it).first; 745 const std::string& sv = (*it).second; 746 //::printf("debug : plotter::set_from_style : key \"%s\" \"%s\"\n",key.c_str(),sv.c_str()); 747 //if(key=="reset") {} 748 if(key=="tag") { 749 // key to find back <plotter_style>s. 750 // see also : 751 // xml_style::load_plotter_style() 752 // xml_style::find_plotter_styles() 753 754 755 //width,height,depth : could set from style (for exa for lego). 756 } else if(key=="width") { 757 float v; 758 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 759 width = v; 760 } else if(key=="height") { 761 float v; 762 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 763 height = v; 764 } else if(key=="depth") { 765 float v; 766 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 767 depth = v; 768 769 } else if(key=="left_margin") { 770 float v; 771 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 772 left_margin = v; 773 } else if(key=="right_margin") { 774 float v; 775 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 776 right_margin = v; 777 } else if(key=="bottom_margin") { 778 float v; 779 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 780 bottom_margin = v; 781 } else if(key=="top_margin") { 782 float v; 783 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 784 top_margin = v; 785 } else if(key=="down_margin") { 786 float v; 787 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 788 down_margin = v; 789 } else if(key=="up_margin") { 790 float v; 791 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 792 up_margin = v; 793 794 } else if(key=="title") { 795 title = sv; 796 } else if(key=="title_up") { 797 bool v; 798 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 799 title_up = v; 800 } else if(key=="title_to_axis") { 801 float v; 802 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 803 title_to_axis = v; 804 } else if(key=="title_height") { 805 float v; 806 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 807 title_height = v; 808 } else if(key=="title_automated") { 809 bool v; 810 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 811 title_automated = v; 812 } else if(key=="title_hjust") { 813 hjust v; 814 if(!shjust(sv,v)) 815 {style_failed(a_out,key,sv);return false;} 816 title_hjust = v; 817 818 } else if(key=="x_axis_enforced") { 819 bool v; 820 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 821 x_axis_enforced = v; 822 } else if(key=="x_axis_automated") { 823 bool v; 824 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 825 x_axis_automated = v; 826 } else if(key=="x_axis_min") { 827 float v; 828 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 829 x_axis_min = v; 830 } else if(key=="x_axis_max") { 831 float v; 832 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 833 x_axis_max = v; 834 } else if(key=="x_axis_is_log") { 835 bool v; 836 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 837 x_axis_is_log = v; 838 839 } else if(key=="y_axis_enforced") { 840 bool v; 841 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 842 y_axis_enforced = v; 843 } else if(key=="y_axis_automated") { 844 bool v; 845 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 846 y_axis_automated = v; 847 } else if(key=="y_axis_min") { 848 float v; 849 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 850 y_axis_min = v; 851 } else if(key=="y_axis_max") { 852 float v; 853 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 854 y_axis_max = v; 855 } else if(key=="y_axis_is_log") { 856 bool v; 857 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 858 y_axis_is_log = v; 859 860 } else if(key=="z_axis_enforced") { 861 bool v; 862 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 863 z_axis_enforced = v; 864 } else if(key=="z_axis_automated") { 865 bool v; 866 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 867 z_axis_automated = v; 868 } else if(key=="z_axis_min") { 869 float v; 870 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 871 z_axis_min = v; 872 } else if(key=="z_axis_max") { 873 float v; 874 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 875 z_axis_max = v; 876 } else if(key=="z_axis_is_log") { 877 bool v; 878 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 879 z_axis_is_log = v; 880 881 } else if(key=="value_top_margin") { 882 float v; 883 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 884 value_top_margin = v; 885 } else if(key=="value_bottom_margin") { 886 float v; 887 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 888 value_bottom_margin = v; 889 } else if(key=="value_bins_with_entries") { 890 float v; 891 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 892 value_bins_with_entries = v; 893 } else if(key=="infos_width") { 894 float v; 895 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 896 infos_width = v; 897 } else if(key=="infos_x_margin") { 898 float v; 899 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 900 infos_x_margin = v; 901 } else if(key=="infos_y_margin") { 902 float v; 903 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 904 infos_y_margin = v; 905 906 } else if(key=="title_box_width") { 907 float v; 908 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 909 title_box_width = v; 910 } else if(key=="title_box_height") { 911 float v; 912 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 913 title_box_height = v; 914 } else if(key=="title_box_x_margin") { 915 float v; 916 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 917 title_box_x_margin = v; 918 } else if(key=="title_box_y_margin") { 919 float v; 920 if(!to<float>(sv,v)) {style_failed(a_out,key,sv);return false;} 921 title_box_y_margin = v; 922 923 } else if(key=="infos_what") { 924 infos_what = sv; 925 926 // } else if(key=="legends_visible") { 927 // bool v; 928 // if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 929 // legends_visible = v; 930 } else if(key=="legends_automated") { 931 bool v; 932 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 933 legends_automated = v; 934 // } else if(key=="legends_attached_to_infos") { 935 // bool v; 936 // if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 937 // legends_attached_to_infos = v; 938 } else if(key=="legends_origin") { 939 vec2f v; 940 if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;} 941 legends_origin.setValue(v); 942 } else if(key=="legends_size") { 943 vec2f v; 944 if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;} 945 legends_size.setValue(v); 946 } else if(key=="legends_origin_unit") { 947 unit_type v; 948 if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;} 949 legends_origin_unit.setValue(v); 950 951 } else if(key=="shape_automated") { 952 bool v; 953 if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} 954 shape_automated = v; 955 956 } else if(key=="shape") { 957 if(sv=="xy") { 958 shape = xy; 959 } else if(sv=="xyz") { 960 shape = xyz; 961 } else { 962 style_failed(a_out,key,sv);return false; 963 } 964 965 //legends_string 966 //legends_color 967 //legends_string mf_string 968 //legends_color mf_vec<colorf,float> 969 970 } else { 971 a_out << "tools::sg::plotter::set_from_style : unknown key " << key << "." << std::endl; 972 } 973 } 974 return true; 975 } 976 977 protected: 978 bool s2axis(const std::string& a_s,sg::axis*& a_axis) { 979 if(a_s=="x_axis") {a_axis = &(x_axis());return true;} 980 else if(a_s=="y_axis") {a_axis = &(y_axis());return true;} 981 else if(a_s=="z_axis") {a_axis = &(z_axis());return true;} 982 else if(a_s=="colormap_axis") {a_axis = &(colormap_axis());return true;} 983 else { 984 a_axis = 0; 985 return false; 986 } 987 } 988 public: 989 bool set_from_string(std::ostream& a_out,cmaps_t& a_cmaps,const std::string& a_field,const std::string& a_value) { 990 // see also plotter_style file. 991 std::string::size_type pos = a_field.find('.'); 992 bool status = true; 993 if(pos==std::string::npos) { 994 style_t _style; 995 _style.push_back(style_item_t(a_field,a_value)); 996 if(!set_from_style(a_out,_style)) status = false; 997 } else { 998 std::vector<std::string> _words; 999 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